The repository now ships a Conan recipe (conanfile.py, added in 1bb10689). The recipe itself is carefully done: the MDBX_* build options are modeled, compiler.libcxx participates in the binary hash, and packages rebuild on option changes. My concern is not the recipe's quality but what packaging libmdbx as a prebuilt Conan binary invites, and I'd like to suggest de-emphasizing it in favor of source-level consumption (amalgamated sources or CMake subproject/FetchContent), or at least fencing it with warnings and safer defaults.
The core problem: Conan is profile-sticky, and the profile is not the consumer's toolchain. Conan resolves, builds and caches binaries according to the active profile, typically the default one auto-detected once by conan profile detect and cached forever after. Nothing ties that profile to the compiler the consumer's project is actually built with. On any multi-compiler machine (system gcc plus clang, or several gcc majors, which describes every developer workstation and most CI images) it is entirely routine to end up with libmdbx compiled by the profile's compiler while the consuming program is compiled by another. Conan will not flag this: the profile is internally consistent, the binary hash matches the profile, find_package(mdbx) succeeds, and the mismatch surfaces only at runtime.
Why this bites libmdbx harder than a typical C library. For the pure-C core the risk is modest, since the platform C ABI is stable across gcc/clang. But the default packaging is shared=True with mdbx.build_cxx=Default (which resolves to ON), so the package ships the C++ binding: mdbx.h++ is compiled by the consumer's compiler while its out-of-line definitions and extern template instantiations (src/mdbx.c++, e.g. mdbx::default_buffer) live in the package's binary, compiled by the profile's compiler. That splits one C++ API across two toolchains and couples the two sides tightly:
None of these are Conan bugs. They are the cost of consuming a header-heavy C++ library as a prebuilt binary selected by a profile rather than by the consumer's actual toolchain. The failure modes are the worst kind: no link error, no diagnostic, just misbehavior or aborts at runtime.
Why source-level consumption avoids the whole class. libmdbx already provides a first-class answer: the amalgamated source for direct embedding, and clean CMake for add_subdirectory/FetchContent. In both cases the library and the application are compiled by the same toolchain with the same flags in the same build, so profile drift is structurally impossible and the MDBX_* option set is decided by the consumer, visibly, at configure time.
Suggestions, in decreasing order of strength; any subset would help:
- Document (README / packaging notes) that source-level consumption is the recommended route, and that the Conan package is provided as a convenience with an explicit warning: the active Conan profile must match the consumer's real compiler, stdlib and build type, especially when the C++ binding is used.
- Consider defaulting
mdbx.build_cxx to False in the recipe: a C-only package is robust against compiler mixing thanks to the stable C ABI, while C++ users, who are exactly the ones exposed to the trap, would opt in consciously or, better, embed the sources.
- Have
package_info()/validate() emit a Conan warning when the C++ portion is enabled in a shared package, pointing at the toolchain-match requirement.
To be clear: this is not "remove the recipe". ConanCenter carries an independent libmdbx recipe anyway, so users who want Conan will use it regardless. The ask is that this repository not silently endorse a consumption route whose sharpest edge (profile-vs-toolchain drift on multi-compiler systems) is invisible until it corrupts a debugging session, or a database.
The repository now ships a Conan recipe (
conanfile.py, added in1bb10689). The recipe itself is carefully done: the MDBX_* build options are modeled,compiler.libcxxparticipates in the binary hash, and packages rebuild on option changes. My concern is not the recipe's quality but what packaging libmdbx as a prebuilt Conan binary invites, and I'd like to suggest de-emphasizing it in favor of source-level consumption (amalgamated sources or CMake subproject/FetchContent), or at least fencing it with warnings and safer defaults.The core problem: Conan is profile-sticky, and the profile is not the consumer's toolchain. Conan resolves, builds and caches binaries according to the active profile, typically the default one auto-detected once by
conan profile detectand cached forever after. Nothing ties that profile to the compiler the consumer's project is actually built with. On any multi-compiler machine (system gcc plus clang, or several gcc majors, which describes every developer workstation and most CI images) it is entirely routine to end up with libmdbx compiled by the profile's compiler while the consuming program is compiled by another. Conan will not flag this: the profile is internally consistent, the binary hash matches the profile,find_package(mdbx)succeeds, and the mismatch surfaces only at runtime.Why this bites libmdbx harder than a typical C library. For the pure-C core the risk is modest, since the platform C ABI is stable across gcc/clang. But the default packaging is
shared=Truewithmdbx.build_cxx=Default(which resolves to ON), so the package ships the C++ binding:mdbx.h++is compiled by the consumer's compiler while its out-of-line definitions and extern template instantiations (src/mdbx.c++, e.g.mdbx::default_buffer) live in the package's binary, compiled by the profile's compiler. That splits one C++ API across two toolchains and couples the two sides tightly:_GLIBCXX_USE_CXX11_ABI, dual-ABIstd::string/std::filesystem::pathinmdbx::signatures);buffer::append()/reserve()on a reference-modality buffer route external content throughreshape<false>— spurious assertion abort in checked builds #25), and several binding code paths are gated by plainassert()whose behavior is decided at library compile time (see Move-assigning from a reference-modalitybuffercalls the non-constdata()overload and tripsMDBX_CONSTEXPR_ASSERT(is_freestanding())— aborts any debug application build #24);noexceptsemantics and inlining decisions straddle the boundary, so a header-side change of compiler flags can diverge from the packaged binary silently.None of these are Conan bugs. They are the cost of consuming a header-heavy C++ library as a prebuilt binary selected by a profile rather than by the consumer's actual toolchain. The failure modes are the worst kind: no link error, no diagnostic, just misbehavior or aborts at runtime.
Why source-level consumption avoids the whole class. libmdbx already provides a first-class answer: the amalgamated source for direct embedding, and clean CMake for
add_subdirectory/FetchContent. In both cases the library and the application are compiled by the same toolchain with the same flags in the same build, so profile drift is structurally impossible and the MDBX_* option set is decided by the consumer, visibly, at configure time.Suggestions, in decreasing order of strength; any subset would help:
mdbx.build_cxxtoFalsein the recipe: a C-only package is robust against compiler mixing thanks to the stable C ABI, while C++ users, who are exactly the ones exposed to the trap, would opt in consciously or, better, embed the sources.package_info()/validate() emit a Conan warning when the C++ portion is enabled in a shared package, pointing at the toolchain-match requirement.To be clear: this is not "remove the recipe". ConanCenter carries an independent libmdbx recipe anyway, so users who want Conan will use it regardless. The ask is that this repository not silently endorse a consumption route whose sharpest edge (profile-vs-toolchain drift on multi-compiler systems) is invisible until it corrupts a debugging session, or a database.