From 4cf178545beb99d6d718f114d6bff5c96ba05f36 Mon Sep 17 00:00:00 2001 From: Tahmid Khan <60913202+ta7mid@users.noreply.github.com> Date: Tue, 6 Oct 2026 00:40:33 +0600 Subject: [PATCH] fix: CMake package and imported library target names - Accept both the libbson 2.x (`bson` package, `bson::static`/`bson::shared`) and libbson 1.x (`bson-1.0`, `mongo::bson_*`) names, in CMakeLists.txt as well as in the installed reflectcpp-config.cmake. - Link Arrow and Parquet via `Arrow::arrow_{static,shared}` and `Parquet::parquet_{static,shared}` outside vcpkg too: `arrow::arrow` is not provided by Arrow's own CMake packages (e.g. Homebrew, distros). Only look for the Parquet package if the Arrow package didn't provide it (Conan). - Resolve dependency targets at configure time instead of with generator expressions, which end up verbatim in the exported reflectcpp-exports.cmake. reflectcpp_link_one_of() picks the variant of the same library type as reflectcpp (static/shared) and falls back to any that exists, e.g. `flatbuffers::flatbuffers_shared` for shared Conan builds and `msgpack-c-static` for static builds against msgpack-c installs that ship both. - Link libbson PUBLIC again: rfl/bson/*.hpp include , and libbson 2.x installs its headers under include/bson-/. - conanfile.py: make `with_csv` enable Arrow's CSV support. --- CMakeLists.txt | 53 +++++++++++++++++++++++++------------- conanfile.py | 2 ++ reflectcpp-config.cmake.in | 4 +-- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acb80aa7e..572e8cd4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,6 +283,29 @@ if (_REFLECTCPP_NEEDS_JSON_IMPL) endif () endif () +# Links reflectcpp against one of the given targets: the first one that is the same kind of +# library as reflectcpp (static or shared), else the first one that exists at all. Resolving +# the name here instead of in a generator expression keeps the exported link interface clean. +function(reflectcpp_link_one_of) + get_target_property(wanted_type reflectcpp TYPE) + set(chosen "") + foreach(target IN LISTS ARGN) + if (TARGET "${target}") + get_target_property(type "${target}" TYPE) + if (type STREQUAL wanted_type) + set(chosen "${target}") + break() + elseif (NOT chosen) + set(chosen "${target}") + endif () + endif () + endforeach () + if (NOT chosen) + message(FATAL_ERROR "None of these targets exist: ${ARGN}") + endif () + target_link_libraries(reflectcpp PUBLIC "${chosen}") +endfunction() + if (REFLECTCPP_AVRO OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_avro.cpp @@ -320,10 +343,11 @@ if (REFLECTCPP_BSON OR REFLECTCPP_CHECK_HEADERS) list(APPEND REFLECT_CPP_SOURCES src/reflectcpp_bson.cpp ) - if (NOT TARGET mongo::bson_static AND NOT TARGET mongo::bson_shared) - find_package(bson CONFIG REQUIRED) + if (NOT TARGET bson::static AND NOT TARGET bson::shared AND NOT TARGET mongo::bson_static AND NOT TARGET mongo::bson_shared) + # libbson < 2.0 names its package bson-1.0 and its targets mongo::bson_* + find_package(bson CONFIG REQUIRED NAMES bson bson-1.0) endif () - target_link_libraries(reflectcpp PRIVATE $,bson::static,bson::shared>) + reflectcpp_link_one_of(bson::static bson::shared mongo::bson_static mongo::bson_shared) endif () if (REFLECTCPP_CAPNPROTO OR REFLECTCPP_CHECK_HEADERS) @@ -365,11 +389,7 @@ if (REFLECTCPP_CSV OR REFLECTCPP_CHECK_HEADERS) if (NOT TARGET Arrow) find_package(Arrow CONFIG REQUIRED) endif() - if (REFLECTCPP_USE_VCPKG) - target_link_libraries(reflectcpp PUBLIC "$,Arrow::arrow_static,Arrow::arrow_shared>") - else() - target_link_libraries(reflectcpp PUBLIC "arrow::arrow") - endif() + reflectcpp_link_one_of(Arrow::arrow_static Arrow::arrow_shared) endif () if (REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_CHECK_HEADERS) @@ -379,7 +399,7 @@ if (REFLECTCPP_FLEXBUFFERS OR REFLECTCPP_CHECK_HEADERS) if (NOT TARGET flatbuffers::flatbuffers) find_package(flatbuffers CONFIG REQUIRED) endif () - target_link_libraries(reflectcpp PUBLIC flatbuffers::flatbuffers) + reflectcpp_link_one_of(flatbuffers::flatbuffers flatbuffers::flatbuffers_shared) endif () if (REFLECTCPP_MSGPACK OR REFLECTCPP_CHECK_HEADERS) @@ -389,22 +409,19 @@ if (REFLECTCPP_MSGPACK OR REFLECTCPP_CHECK_HEADERS) if (NOT TARGET msgpack-c) find_package(msgpack-c CONFIG REQUIRED NAMES msgpack msgpack-c msgpackc) endif() - target_link_libraries(reflectcpp PUBLIC $,msgpack-c,$,msgpackc,msgpack-c>>) + reflectcpp_link_one_of(msgpack-c msgpackc msgpack-c-static) endif () if (REFLECTCPP_PARQUET OR REFLECTCPP_CHECK_HEADERS) if (NOT TARGET Arrow) find_package(Arrow CONFIG REQUIRED) endif() - if (REFLECTCPP_USE_VCPKG) - if (NOT TARGET Parquet) - find_package(Parquet CONFIG REQUIRED) - endif() - target_link_libraries(reflectcpp PUBLIC "$,Arrow::arrow_static,Arrow::arrow_shared>") - target_link_libraries(reflectcpp PUBLIC "$,Parquet::parquet_static,Parquet::parquet_shared>") - else() - target_link_libraries(reflectcpp PUBLIC "arrow::arrow") + # Conan's Arrow package also provides the Parquet targets + if (NOT TARGET Parquet::parquet_static AND NOT TARGET Parquet::parquet_shared) + find_package(Parquet CONFIG REQUIRED) endif() + reflectcpp_link_one_of(Arrow::arrow_static Arrow::arrow_shared) + reflectcpp_link_one_of(Parquet::parquet_static Parquet::parquet_shared) endif () if (REFLECTCPP_TOML OR REFLECTCPP_CHECK_HEADERS) diff --git a/conanfile.py b/conanfile.py index f31458600..1b7bc7bff 100644 --- a/conanfile.py +++ b/conanfile.py @@ -77,6 +77,8 @@ def config_options(self): def configure(self): if self.options.shared: self.options.rm_safe("fPIC") + if self.options.with_csv: + self.options["arrow"].with_csv = True def requirements(self): self.requires("ctre/3.9.0", transitive_headers=True) diff --git a/reflectcpp-config.cmake.in b/reflectcpp-config.cmake.in index a1ba06899..6177bb69d 100644 --- a/reflectcpp-config.cmake.in +++ b/reflectcpp-config.cmake.in @@ -36,7 +36,7 @@ if (REFLECTCPP_BOOST_SERIALIZATION) endif () if (REFLECTCPP_BSON) - find_dependency(bson-1.0) + find_dependency(bson NAMES bson bson-1.0) endif () if (REFLECTCPP_CAPNPROTO) @@ -60,7 +60,7 @@ if (REFLECTCPP_FLEXBUFFERS) endif () if (REFLECTCPP_MSGPACK) - find_dependency(msgpack-c) + find_dependency(msgpack-c NAMES msgpack msgpack-c msgpackc) endif() if (REFLECTCPP_PARQUET)