Document the build against the rocksdb of the distribution
The README still asked for the rocksdb 5.11 fork, which is not needed anymore,
and its build recipe did not work: the tests run the collocatordb_query tool,
which is built with the rpath of its install location, so they only pass after
make install, and they find the tool and their data only when the build
directory is build/ inside the sources.
Also documents when a static rocksdb is needed at all - only for linking a
program completely statically, as dereko2vec does, which is worth about 10% on
collocator lookups, measured with rocksdb 7.8.3 which ships both variants.
Debian and Ubuntu ship librocksdb.a, Fedora, Rocky Linux and RHEL do not, so
the README says how to build one without shadowing the packaged headers.
That shadowing is the trap behind the undefined references one gets when a
hand installed rocksdb sits below /usr/local, so the build compares the version
of the headers with the version of the library and stops with an explanation
instead of leaving that to the linker.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ie79c5a33bfd068a8c3915f368db7d0c45e8d20fb
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 84a14c4..071760c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,31 @@
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_collocatordb_lib_suffixes})
endif()
message(STATUS "Using RocksDB library ${ROCKSDB}")
+
+# The compiler looks into /usr/local/include before /usr/include, so a leftover
+# rocksdb installation there is used for the headers while the library of the
+# distribution is linked. That ends in a wall of undefined references, so say
+# what is wrong while it is still obvious.
+find_path(ROCKSDB_INCLUDE_DIR rocksdb/version.h)
+if (ROCKSDB_INCLUDE_DIR AND ROCKSDB)
+ file(STRINGS "${ROCKSDB_INCLUDE_DIR}/rocksdb/version.h" _rocksdb_major_line
+ REGEX "^#define ROCKSDB_MAJOR ")
+ string(REGEX MATCH "[0-9]+" ROCKSDB_HEADER_MAJOR "${_rocksdb_major_line}")
+ get_filename_component(_rocksdb_real "${ROCKSDB}" REALPATH)
+ if (_rocksdb_real MATCHES "librocksdb\\.so\\.([0-9]+)")
+ set(ROCKSDB_LIB_MAJOR ${CMAKE_MATCH_1})
+ message(STATUS "Using RocksDB headers ${ROCKSDB_INCLUDE_DIR} (version ${ROCKSDB_HEADER_MAJOR})")
+ if (NOT ROCKSDB_HEADER_MAJOR STREQUAL ROCKSDB_LIB_MAJOR)
+ message(FATAL_ERROR
+ "The rocksdb headers in ${ROCKSDB_INCLUDE_DIR} are version "
+ "${ROCKSDB_HEADER_MAJOR}, but ${ROCKSDB} is version "
+ "${ROCKSDB_LIB_MAJOR}. Most likely a leftover rocksdb below "
+ "/usr/local shadows the one of the distribution - remove it, "
+ "or point -DROCKSDB= at the library belonging to the headers.")
+ endif()
+ endif()
+endif()
+
find_library(ROCKSDB_STATIC librocksdb.a)
get_cmake_property(_variableNames VARIABLES)