diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 917e66d192..baafc5c459 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -258,10 +258,14 @@ if(WITH_ROCKSDB) set(ROCKSDB_LIBRARIES "IFCOPENSHELL_RocksDB") target_compile_definitions(IFCOPENSHELL_RocksDB INTERFACE IFOPSH_WITH_ROCKSDB) set(SWIG_DEFINES ${SWIG_DEFINES} -DIFOPSH_WITH_ROCKSDB) - # Shared binaries for `rocksdb` only support limited API (only `c.h`), but we use `db.h` API. - # So rocksdb supported only as a static library. # See https://github.com/facebook/rocksdb/issues/981. - target_link_libraries(IFCOPENSHELL_RocksDB INTERFACE RocksDB::rocksdb) + if(TARGET RocksDB::rocksdb) + target_link_libraries(IFCOPENSHELL_RocksDB INTERFACE RocksDB::rocksdb) + elseif(TARGET RocksDB::rocksdb-shared) + target_link_libraries(IFCOPENSHELL_RocksDB INTERFACE RocksDB::rocksdb-shared) + else() + message(FATAL_ERROR "RocksDB found but neither RocksDB::rocksdb nor RocksDB::rocksdb-shared target exists") + endif() if(WITH_ZSTD) # @todo do we actually need the zstd include dir or rather just pass diff --git a/src/ifcparse/IfcFile.cpp b/src/ifcparse/IfcFile.cpp index 9e26b24442..06521d5565 100644 --- a/src/ifcparse/IfcFile.cpp +++ b/src/ifcparse/IfcFile.cpp @@ -7,6 +7,8 @@ #endif #include +#include +#include #include #include @@ -410,6 +412,26 @@ IfcUtil::IfcBaseClass* IfcParse::impl::rocks_db_file_storage::assert_existance(s } namespace { +#ifdef IFOPSH_WITH_ROCKSDB + // Newer RocksDB releases (e.g. the one shipped by Fedora rawhide) changed + // DB::Open / DB::OpenForReadOnly to take a std::unique_ptr* and removed + // the raw DB** overloads. These helpers select whichever signature the + // installed RocksDB exposes, so the code builds against both old and new + // headers. The int/long tag prefers the unique_ptr form when both exist. + template + auto rocksdb_open(Fn&& open, rocksdb::DB*& db, int) + -> decltype(open(std::declval*>())) { + std::unique_ptr owned; + auto status = open(&owned); + db = owned.release(); + return status; + } + template + auto rocksdb_open(Fn&& open, rocksdb::DB*& db, long) + -> decltype(open(std::declval())) { + return open(&db); + } +#endif rocksdb::DB* init_db(const std::string& filepath, bool readonly) { rocksdb::DB* db = nullptr; #ifdef IFOPSH_WITH_ROCKSDB @@ -446,9 +468,13 @@ namespace { rocksdb::Status status; if (readonly) { - status = rocksdb::DB::OpenForReadOnly(options, filepath, &db); + status = rocksdb_open([&](auto* dbptr) -> decltype(rocksdb::DB::OpenForReadOnly(options, filepath, dbptr)) { + return rocksdb::DB::OpenForReadOnly(options, filepath, dbptr); + }, db, 0); } else { - status = rocksdb::DB::Open(options, filepath, &db); + status = rocksdb_open([&](auto* dbptr) -> decltype(rocksdb::DB::Open(options, filepath, dbptr)) { + return rocksdb::DB::Open(options, filepath, dbptr); + }, db, 0); } if (!status.ok()) { return nullptr;