-
Notifications
You must be signed in to change notification settings - Fork 546
CXX-3103 bump minimum required C Driver version to 2.0.0 #1379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/bsoncxx/CMakeLists.txt
Outdated
message(STATUS "Using bson targets imported via add_subdirectory() without version checks") | ||
|
||
if(NOT BSONCXX_LINK_WITH_STATIC_MONGOC) | ||
set(libbson_target bson_shared) | ||
if(BSONCXX_LINK_WITH_STATIC_MONGOC) | ||
set(bson_target bson_static) | ||
else() | ||
set(libbson_target bson_static) | ||
set(bson_target bson_shared) | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The newer C driver CMake projects define bson::static
, bson::shared
, mongoc::static
, and mongoc::shared
ALIAS targets for uniformity with the installed target names, so those names can be used without the branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it would be preferable to refer to targets which can only be imported via add_subdirectory()
in the case when they are made available, rather than using bson::*
targets, which then imply they were imported via find_package()
. That is, the idea was:
bson_shared
: bson library was imported viaadd_subdirectory()
.bson::shared
: bson library was imported viafind_package()
.
Would you prefer the use of bson::*
targets for ${bson_target}
regardless (limiting use of bson_shared
to add vs. find detection only)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer it for uniformity, but it's not really a sticking point at this time. Either way, the installed C++ targets will link to the bson::
and mongoc::
names because the subproject targets have an EXPORT_NAME
set to match the aliases. There's also the option of skipping the branch and target name indirection and replacing it with a genex: $<IF:$<BOOL:${BSONCXX_LINK_WITH_STATIC_MONGOC}>,bson::static,bson::shared>
, but I won't commit to saying that's definitely better, as there may be other reason to use the indirection through ${bson_target}
.
Aside: While working on amongoc
, I studied more on using FetchContent
and find_package
and it may be preferrable from packagers' perspective that we modify the automatic fetching of mongoc
/bson
/catch2
to rely on FetchContent
redirection for find_package
rather than our custom fetching modules, and make the rest of the project agnostic to whether it is downloaded on-the-fly or imported from an installation, but that's all a bigger change that would take more investigation. (Refer: DeclareFetchContentDeps.cmake)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer it for uniformity, but it's not really a sticking point at this time
I suppose it wouldn't hurt to use the alias targets so we get better target_link_libraries()
behavior.
There's also the option of skipping the branch and target name indirection and replacing it with a genex.
I think I would prefer to avoid using generator expressions unless they are strictly necessary (such that using a generator expression implies the property/variable/flag/etc. must be evaluated at build-time rather than config-time). BSONCXX_LINK_WITH_STATIC_MONGOC
does not depend on the build configuration.
there may be other reason to use the indirection through
${bson_target}
.
I opted to leave things mostly as-is for now (still a variable) for easier PR diff. The reason that came to mind was that the normal variable has the benefit of function/directory scope, unlike targets which have the "globally unique" requirement (i.e. the uninstall
custom target problem from a while back: mongodb/mongo-c-driver#1352). We might consider doing something similar to _mongoc-*
-prefixed internal library targets, but we can defer this work to a PR that is more focused on refactors the CMake configuration.
it may be preferrable from packagers' perspective that we [...] rely on FetchContent redirection for
find_package
I've also thought about this (e.g. using FETCHCONTENT_TRY_FIND_PACKAGE_MODE
), but decided against pursuing it atm due to requiring a comparatively recent version of CMake (3.24 and newer), the quirk that we need to find_package()
two packages (bson
+ mongoc
) for a single FetchContent_Declare(mongo-c-driver)
(haven't investigated how to implement this in depth), and (AFAIK) the lack of package-specific opt-in/opt-out mechanisms for the preferred dependency resolution method (e.g. one user may prefer/require find_package()
, another may prefer/require add_subdirectory()
; at least atm users have the option to override each behavior via CMAKE_DISABLE_FIND_PACKAGE_<PackageName>
or FETCHCONTENT_SOURCE_DIR_<uppercaseName>
).
Opted to avoid specifying the patch number in CMake version requirements, since they are not expected to contain any notable changes to features (primarily bug fixes or internal, non-user-facing updates). However, the patch number is still required to specify the exact CMake binary version to be downloaded by our scripts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CMake compatibility tests and message improvements are much appreciated.
etc/calc_release_version_selftest.sh
Outdated
@@ -67,7 +67,7 @@ echo "Test next minor version ... begin" | |||
# failed, then it is probably because a new major/minor release was made. | |||
# Update the expected output to represent the correct next version. | |||
# XXX NOTE XXX NOTE XXX | |||
assert_eq "$got" "3.10.0-$DATE+git$CURRENT_SHORTREF" | |||
assert_eq "$got" "4.1.0-$DATE+git$CURRENT_SHORTREF" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noticed when validating this commit in #1381.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with minor comments
commands = [ | ||
Setup.call(), InstallUV.call() | ||
] + ([InstallCDriver.call() if install_c_driver else FetchCDriverSource.call()]) + [ | ||
CMakeCompat.call( | ||
vars={ | ||
'CMAKE_MAJOR_VERSION': version[0], | ||
'CMAKE_MINOR_VERSION': version[1], | ||
'CMAKE_PATCH_VERSION': version[2], | ||
'INSTALL_C_DRIVER': 1 if install_c_driver else 0, | ||
}, | ||
), | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be simplified to?
commands = [ | |
Setup.call(), InstallUV.call() | |
] + ([InstallCDriver.call() if install_c_driver else FetchCDriverSource.call()]) + [ | |
CMakeCompat.call( | |
vars={ | |
'CMAKE_MAJOR_VERSION': version[0], | |
'CMAKE_MINOR_VERSION': version[1], | |
'CMAKE_PATCH_VERSION': version[2], | |
'INSTALL_C_DRIVER': 1 if install_c_driver else 0, | |
}, | |
), | |
] | |
commands = [ | |
Setup.call(), | |
InstallUV.call(), | |
(InstallCDriver.call() if install_c_driver else FetchCDriverSource.call()), | |
CMakeCompat.call( | |
vars={ | |
'CMAKE_MAJOR_VERSION': version[0], | |
'CMAKE_MINOR_VERSION': version[1], | |
'CMAKE_PATCH_VERSION': version[2], | |
'INSTALL_C_DRIVER': 1 if install_c_driver else 0, | |
}, | |
), | |
] |
You can also rewrite 1 if foo else 0
to int(foo)
if foo
is just a plain boolean.
@@ -1,3 +1,3 @@ | |||
include(CMakeFindDependencyMacro) | |||
@BSONCXX_PKG_DEP@ | |||
find_dependency(bson @BSON_REQUIRED_VERSION@ REQUIRED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The REQUIRED
keyword is not necessary for find_dependency
, IIUC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit I don't understand how this is meant to work per docs:
find_dependency
forwards the correct parameters forQUIET
andREQUIRED
which were passed to the originalfind_package()
call.
I do not see how this call to find_dependency()
can know what the original parameters to a find_package()
would have been, so I included REQUIRED
for assurance. However, local testing appears to enforce the REQUIRED
behavior even without it being included in this command, so I am fine with removing it.
Resolves CXX-3103. Followup to CDRIVER-4742.
Bumps the minimum required C Driver version from 1.30.0 to 2.0.0.
Additionally sets the CMake "maximum policy version" to 4.0 to communicate CMake 4.0 compatibility and test coverage.
Important
These changes do NOT cause API or ABI breaking changes for the C++ Driver libraries themselves. However, they do change dynamic linking requirements for dependent code (e.g.
libbson-1.0.so.0
->bson2.so.2
forlibbsoncxx.so._noabi
).References to CMake package names and targets are updated for C Driver v2 compatibility:
find_package(bson-${LIBBSON_REQUIRED_ABI_VERSION})
->find_package(bson)
.${LIBBSON_REQUIRED_ABI_VERSION}
variable is removed: no reason to parameterize on ABI version number given API == ABI equivalent going forward for the C Driver.Note
Considered adding
CONFIG
tofind_package()
for C Driver packages, but decided against to allow users to customize lookup using module search mode (defining their ownFindbson.cmake
) when necessary for their circumstances.find_dependency(bson-1.0 REQUIRED)
->find_dependency(bson 2.0.0 REQUIRED)
.BUILD_VERSION
inheritance addressed by CXX-3266 avoid inheriting BUILD_VERSION by auto-downloaded C Driver #1373 (e.g. a dependent project would fail configuration due to finding bson 0.0.0 instead of the expected bson 2.0.0).find_dependency(bsoncxx 4.0.0 REQUIRED)
in themongocxx-config.cmake
file.Important
To allow
find_dependency(bsoncxx @BSONCXX_VERSION_NO_EXTRA@ REQUIRED)
,BSONCXX_VERSION
andBSONCXX_VERSION_NO_EXTRA
(+ mongocxx equivalents) are now internal cache variables so they are accessible across project scopes. All references use$CACHE{VARNAME}
syntax to clearly communicate the variable type and to avoid potential conflict/confusion with normal variables. NoteINTERNAL
impliesFORCE
(user override is not supported).mongo::bson_shared
andmongo::bson_static
withbson::shared
andbson::static
when referencing targets imported byfind_package()
.bson_static
andbson_shared
are still used to reference targets imported viaadd_subdirectory()
.Note
Considered refactoring the C++ Driver CMake config to support the
bson::bson
target (perBSON_DEFAULT_IMPORTED_LIBRARY_TYPE
), but decided against to avoid complicating the current configuration which still distinguishes shared vs. static linkage viaBUILD_SHARED_LIBS_WITH_STATIC_MONGOC
.${LIBBSON_REQUIRED_VERSION}
->${BSON_REQUIRED_VERSION}
${LIBMONGOC_REQUIRED_VERSION}
->${MONGOC_REQUIRED_VERSION}
${LIBMONGOC_DOWNLOAD_VERSION}
->${MONGOC_DOWNLOAD_VERSION}
${libbson_target}
->${bson_target}
${libmongoc_target}
->${mongoc_target}
Note
Considered a similar rename of C++ Driver targets, libraries, and package config files, but decided against to avoid introducing too many significant build system breaking changes. These changes can be addressed in a subsequent release (v5?).
libbson-static-${LIBBSON_REQUIRED_ABI_VERSION}
tobson2
.CMake configuration messages are also updated to better communicate behavior pertaining to how C Driver libraries are imported, as well as to avoid being excessively descriptive about the method by which the required libraries are found (considering the numerous options which can control
find_package()
andFetchContent
behavior beyond justCMAKE_PREFIX_PATHS
). e.g. givenfind_package()
success:and given
find_package()
failure and subsequent auto-download behavior:Removed obsolete branches which supported old C Driver CMake package config files:
find_package(libbson-1.0)
are removed following CDRIVER-3414.${BSONCXX_PKG_DEP}
is no longer necessary: dependency specification is now the same regardless of how C Driver libraries are imported.${libbson_include_directories}
and${libbson_definitions}
are no longer necessary: only CMake target properties are required and used.The C++ Driver CMake config now sets
<policy_max>
in its call tocmake_minimum_required()
. This feature is supported since 3.12; we require 3.15 or newer.The "maximum policy version" is set to 4.0, which is now tested by the new "cmake-compat" EVG task matrix. These tasks test various CMake configurations (currently: polyfill selection x C Driver import method x C++ Driver import method) against our minimum supported CMake version (3.15), the latest CMake v3 version (3.31), and the latest CMake version (4.0). This task coverage (which enables
-Werror=dev
and-Werror=deprecated
) should help us detect CMake compatibility issues as well as (minimally) verify correct CMake package config file behavior (i.e. the addition of API version requirements in calls tofind_dependency()
).The current combination of minimum and maximum policy versions permits the following changes:
<policy_max>
rather than using command line flags.FindPythonInterp
(likely not provided by newer CMake releases) withFindPython3
to satisfy the Python requirement for runningetc/calc_release_version.py
.Note
Removal of the
calc_release_version.py
script as done in CDRIVER-5932 is deferred.FATAL_ERROR
argument tocmake_minimum_required()
is obsolete since 2.6. Removed from example project CMake config files.Important
Setting
<policy_max>
means all CMake policies which apply up to<policy_max>
are set toNEW
. This meanscmake_policy()
should only be used to deliberately set a specific policy toOLD
.This PR also adds regression tests for the
BUILD_VERSION
inheritance bug addressed by #1373, which now assert that the bson and mongoc libraries have the expected API version number using both thebson_get_*
API as well as theBSON_VERSION_S
macro (which currently use slightly different methods to obtain their value, as noted in the PR description for #1373; this accounts for both cases):The
bsoncxx/private/version.hh
component is added to support reuse of thesplit_version()
helper function by both bsoncxx and mongocxx test binaries. It is not currently used by the library itself (similar to themongocxx/private/mock.hh
component).