On Ubuntu, FlatBuffers is packaged to include both the static and shared libraries:
flatbuffers::flatbuffers points to the static libraries
flatbuffers::flatbuffers_shared points to the shared libraries.
But as packaged by Fedora, FlatBuffers does not include the static libraries at all. So only:
flatbuffers::flatbuffers_shared is available, pointing at the shared libraries.
Therefore, a simple CMake project like this can fail to configure in certain environments through no apparent fault of the project author:
cmake_minimum_required(VERSION 3.28)
project(myproj)
find_package(FlatBuffers REQUIRED)
# ...
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE flatbuffers::flatbuffers) # broken on shared-only installs
We discovered this issue in Halide when a colleague reported the find_package(FlatBuffers) call failing on Fedora 44. Halide links directly to flatbuffers::flatbuffers, which breaks on shared-only builds. I claim this is an issue with the contract on the FlatBuffers CMake package.
I wrote a blog post about distributing dual static/shared libraries in CMake a few years back. In it, I argue that libraries should expose a single target to CMake downstreams (here, flatbuffers::flatbuffers) because (a) they almost never need to link to both static and shared at the same time, (b) they rarely want both and, if they do, it's likely because they're packaging it and are willing to eat the cost of building it twice, (c) when a packager of the downstream wants to switch how FlatBuffers is built or linked, they must patch the downstream to use (or omit) the _shared suffix.
I would like to adjust FlatBuffers' CMake package to expose only flatbuffers::flatbuffers. We have several mitigations to make this change less disruptive to downstreams:
- We can provide an ALIAS target
flatbuffers::flatbuffers_shared that points to flatbuffers::flatbuffers when it is shared.
- The CMake package can provide
static and shared components that enforce one or the other when a downstream has a genuine need for one flavor.
- The CMake package can honor
FlatBuffers_SHARED_LIBS as a cache/environment toggle.
- The CMake package can honor
BUILD_SHARED_LIBS when both are available.
- Load whichever is available, preferring static.
Items (2)-(5) form a precedence chain resolved at configure-time: an explicit component request wins, then the package-specific variable, then the standard hint, and finally whatever is available. Switching between the two at configure-time then becomes a matter of setting BUILD_SHARED_LIBS, which is perfectly standard.
Would this be a welcome change for this project? I have a branch ready to PR.
On Ubuntu, FlatBuffers is packaged to include both the static and shared libraries:
flatbuffers::flatbufferspoints to the static librariesflatbuffers::flatbuffers_sharedpoints to the shared libraries.But as packaged by Fedora, FlatBuffers does not include the static libraries at all. So only:
flatbuffers::flatbuffers_sharedis available, pointing at the shared libraries.Therefore, a simple CMake project like this can fail to configure in certain environments through no apparent fault of the project author:
We discovered this issue in Halide when a colleague reported the
find_package(FlatBuffers)call failing on Fedora 44. Halide links directly toflatbuffers::flatbuffers, which breaks on shared-only builds. I claim this is an issue with the contract on the FlatBuffers CMake package.I wrote a blog post about distributing dual static/shared libraries in CMake a few years back. In it, I argue that libraries should expose a single target to CMake downstreams (here,
flatbuffers::flatbuffers) because (a) they almost never need to link to both static and shared at the same time, (b) they rarely want both and, if they do, it's likely because they're packaging it and are willing to eat the cost of building it twice, (c) when a packager of the downstream wants to switch how FlatBuffers is built or linked, they must patch the downstream to use (or omit) the_sharedsuffix.I would like to adjust FlatBuffers' CMake package to expose only
flatbuffers::flatbuffers. We have several mitigations to make this change less disruptive to downstreams:flatbuffers::flatbuffers_sharedthat points toflatbuffers::flatbufferswhen it is shared.staticandsharedcomponents that enforce one or the other when a downstream has a genuine need for one flavor.FlatBuffers_SHARED_LIBSas a cache/environment toggle.BUILD_SHARED_LIBSwhen both are available.Items (2)-(5) form a precedence chain resolved at configure-time: an explicit component request wins, then the package-specific variable, then the standard hint, and finally whatever is available. Switching between the two at configure-time then becomes a matter of setting
BUILD_SHARED_LIBS, which is perfectly standard.Would this be a welcome change for this project? I have a branch ready to PR.