diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 4d3f05fd10..913158b2e7 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -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 diff --git a/src/ifcparse/CMakeLists.txt b/src/ifcparse/CMakeLists.txt index 7d3c4db3d1..4c07174089 100644 --- a/src/ifcparse/CMakeLists.txt +++ b/src/ifcparse/CMakeLists.txt @@ -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() diff --git a/src/ifcparse/file.cpp b/src/ifcparse/file.cpp index 229f93066e..567c726e0b 100644 --- a/src/ifcparse/file.cpp +++ b/src/ifcparse/file.cpp @@ -7,8 +7,10 @@ #endif #include +#include #include #include +#include /* 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*. Select whichever signature the installed headers expose. + 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 @@ -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; diff --git a/src/serializers/CMakeLists.txt b/src/serializers/CMakeLists.txt index ccdeb08bf8..c8374df36e 100644 --- a/src/serializers/CMakeLists.txt +++ b/src/serializers/CMakeLists.txt @@ -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)