Support RocksDB shared library and new unique_ptr DB::Open API

Some distributions (e.g. Fedora) ship only a shared RocksDB that exports
RocksDB::rocksdb-shared rather than RocksDB::rocksdb. The CMake target
selection now falls back to the shared target when the static one is absent.

Newer RocksDB also changed DB::Open and DB::OpenForReadOnly to take
std::unique_ptr<DB>* instead of DB**. IfcFile.cpp uses SFINAE tag dispatch
to build against both old and new APIs without version detection.
This commit is contained in:
Bruno Postle
2026-06-04 22:31:02 +01:00
committed by Thomas Krijnen
parent 5f7d9b86b8
commit 818ca6b2bc
4 changed files with 37 additions and 4 deletions
+8
View File
@@ -259,6 +259,14 @@ if (WITH_ROCKSDB)
endif()
message(STATUS "RocksDB: found at '${RocksDB_DIR}'.")
# See https://github.com/facebook/rocksdb/issues/981.
if(TARGET RocksDB::rocksdb)
set(IFCOPENSHELL_ROCKSDB_TARGET RocksDB::rocksdb)
elseif(TARGET RocksDB::rocksdb-shared)
set(IFCOPENSHELL_ROCKSDB_TARGET 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
+1 -1
View File
@@ -57,7 +57,7 @@ else()
endif()
if(WITH_ROCKSDB)
target_link_libraries(IfcParse RocksDB::rocksdb)
target_link_libraries(IfcParse ${IFCOPENSHELL_ROCKSDB_TARGET})
if(WITH_ZSTD)
target_link_libraries(IfcParse zstd::libzstd_static)
endif()
+27 -2
View File
@@ -7,8 +7,10 @@
#endif
#include <fstream>
#include <memory>
#include <sys/types.h>
#include <sys/stat.h>
#include <utility>
/*
ifcopenshell::IfcBaseClass* ifcopenshell::impl::rocks_db_file_storage::rocksdb_instance_iterator::operator*() const {
@@ -77,6 +79,25 @@ express::Base ifcopenshell::impl::rocks_db_file_storage::assert_existance(size_t
}
namespace {
#ifdef IFOPSH_WITH_ROCKSDB
// Newer RocksDB releases changed DB::Open / DB::OpenForReadOnly to take
// std::unique_ptr<DB>*. Select whichever signature the installed headers expose.
template <typename Fn>
auto rocksdb_open(Fn&& open, rocksdb::DB*& db, int)
-> decltype(open(std::declval<std::unique_ptr<rocksdb::DB>*>())) {
std::unique_ptr<rocksdb::DB> owned;
auto status = open(&owned);
db = owned.release();
return status;
}
template <typename Fn>
auto rocksdb_open(Fn&& open, rocksdb::DB*& db, long)
-> decltype(open(std::declval<rocksdb::DB**>())) {
return open(&db);
}
#endif
rocksdb::DB* init_db(const std::string& filepath, bool readonly) {
rocksdb::DB* db = nullptr;
#ifdef IFOPSH_WITH_ROCKSDB
@@ -113,9 +134,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;
+1 -1
View File
@@ -56,7 +56,7 @@ function(add_geometry_serializer_plugin target output_name)
endfunction()
if(WITH_ROCKSDB)
add_document_serializer_plugin(document_serializer_rdb "document.rdb" SOURCES document_rdb_plugin.cpp RocksDbSerializer.cpp LIBRARIES RocksDB::rocksdb)
add_document_serializer_plugin(document_serializer_rdb "document.rdb" SOURCES document_rdb_plugin.cpp RocksDbSerializer.cpp LIBRARIES ${IFCOPENSHELL_ROCKSDB_TARGET})
endif()
add_subdirectory(schema_dependent)