File: ImportBSON.cmake

package info (click to toggle)
libmongocrypt 1.17.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 12,572 kB
  • sloc: ansic: 70,067; python: 4,547; cpp: 615; sh: 460; makefile: 44; awk: 8
file content (198 lines) | stat: -rw-r--r-- 11,147 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#[[
   This file defines, exports, and installs two INTERFACE targets: '_mongocrypt::libbson_for_static'
   and '_mongocrypt::libbson_for_shared', that are used to link libbson correctly for the build
   configuration of libmongocrypt. At find_package() time, we can resolve these interface targets
   to link to the appropriate libbson based on the build configurations of libmongocrypt.

   mongo::mongocrypt must link to _mongocrypt::libbson_for_shared, and mongo::mongocrypt_static must
   link to _mongocrypt::libbson_for_static.

   At configure+build time, these target will create BUILD_INTERFACE-only usage requirements
   appropriate for libmongocrypt to build against a libbson. Once these targets are installed,
   they retain no usage requirements defined here.

   Instead, the installed version of these targets will be manipulated in mongocrypt-config.cmake
   based on user settings and build configuration options of the installed libmongocrypt in order
   to ensure that users have satisfied the linking requirements of libmongocrypt.
   Refer to mongocrypt-config.cmake for more information

   This file calls add_subdirectory(EXCLUDE_FROM_ALL) on a mongo-c-driver project directory. This
   will expose libbson targets that we can link and use for the libmongocrypt build.

   The boolean option USE_SHARED_LIBBSON controls the behavior of libbson_for_shared:

   If USE_SHARED_LIBBSON=FALSE:

   - libbson_for_shared will transitively link the static libbson from the MONGOCRYPT_MONGOC_DIR.
   - The result is that mongo::mongocrypt (which is a SHARED library) will have the translation
     units of libbson directly embedded into the resulting binary.
   - The symbols from libbson that are merged into mongo::mongocrypt will be suppressed using
     linker scripts such that consumers of mongo::mongocrypt will not see the libbson symbols that
     were statically linked into the shared library. This allows consumers to link against a
     completely independent libbson without interfering with the libbson symbols that were merged
     into mongo::mongocrypt
   - The installed libbson_for_shared will have no usage requirements.

   If USE_SHARED_LIBBSON=TRUE:

   - libbson_for_shared will transitively use the shared libbson library from
     the MONGOCRYPT_MONGOC_DIR.
   - mongo::mongocrypt will be built with a dynamic link requirement on a libbson dynamic
     library, which must be resolved at runtime by consumers. The translation units from the
     MONGOCRYPT_MONGOC_DIR *will not* be included in the mongo::mongocrypt library.
   - The installed libbson_for_shared will dynamically link to a libbson on the user's system by
     using a find_library() call.

   In both of the above cases, libbson_for_static will require that the final consumer
   provide their own definitions of the libbson symbols, regardless of the value
   of USE_SHARED_LIBBSON.
]]

set (init OFF)
if (DEFINED ENABLED_SHARED_BSON)
   message (STATUS "ENABLE_SHARED_BSON is now named USE_SHARED_LIBBSON")
   set (init "${ENABLE_SHARED_BSON}")
endif ()
option (USE_SHARED_LIBBSON "Dynamically link libbson for the libmongocrypt dynamic library (default is static)" ${init})

if (NOT DEFINED MONGOCRYPT_MONGOC_DIR)
   # The user did not provide a MONGOCRYPT_MONGOC_DIR, so we'll get one
   include (FetchContent OPTIONAL)
   if (NOT COMMAND FetchContent_Declare)
      # We need FetchContent in order to download the project.
      message (FATAL_ERROR
            "No MONGOCRYPT_MONGOC_DIR setting was defined, and the FetchContent.cmake "
            "module is not available. Upgrade your CMake version, or provide a "
            "MONGOCRYPT_MONGOC_DIR path to a mongo-c-driver directory (This is required "
            "for libmongocrypt to find a libbson to use and link against).")
   endif ()
   include (FetchMongoC)
   # The FetchMongoC module defines a MONGOCRYPT_MONGOC_DIR for us to use
endif ()

function (_import_bson)
   if (MONGOCRYPT_MONGOC_DIR STREQUAL "USE-SYSTEM" AND USE_SHARED_LIBBSON AND NOT ENABLE_ONLINE_TESTS)
      message (STATUS "NOTE: Using system-wide libbson library. This is intended only for package maintainers.")
      find_library (_MONGOCRYPT_SYSTEM_LIBBSON_SHARED "${CMAKE_SHARED_LIBRARY_PREFIX}bson2${CMAKE_SHARED_LIBRARY_SUFFIX}")
      find_library (_MONGOCRYPT_SYSTEM_LIBBSON_STATIC "${CMAKE_STATIC_LIBRARY_PREFIX}bson2${CMAKE_STATIC_LIBRARY_SUFFIX}")
      find_package (bson 2.0 REQUIRED)
      get_target_property (_BSON_SHARED_INCL_DIR_PROP bson::shared INTERFACE_INCLUDE_DIRECTORIES)
      set (_MONGOCRYPT_SYSTEM_LIBBSON_INCLUDE_DIR "${_BSON_SHARED_INCL_DIR_PROP}" CACHE FILEPATH "Internal use only")
      add_library (bson_shared SHARED IMPORTED)
      add_library (bson_static STATIC IMPORTED)
      set_target_properties (bson_shared bson_static PROPERTIES
         IMPORTED_CONFIGURATIONS "Release"
         INTERFACE_INCLUDE_DIRECTORIES "${_MONGOCRYPT_SYSTEM_LIBBSON_INCLUDE_DIR}"
         )
      set_property (TARGET bson_shared PROPERTY IMPORTED_LOCATION "${_MONGOCRYPT_SYSTEM_LIBBSON_SHARED}")
      set_property (TARGET bson_static PROPERTY IMPORTED_LOCATION "${_MONGOCRYPT_SYSTEM_LIBBSON_STATIC}")
      set_property (
         CACHE _MONGOCRYPT_SYSTEM_LIBBSON_SHARED
               _MONGOCRYPT_SYSTEM_LIBBSON_INCLUDE_DIR
         PROPERTY ADVANCED
         TRUE
      )
   else ()
      message (STATUS "Using [${MONGOCRYPT_MONGOC_DIR}] as a sub-project for libbson")
      # Disable AWS_AUTH, to prevent it from building the kms-message symbols, which we build ourselves
      set (ENABLE_MONGODB_AWS_AUTH OFF CACHE BOOL "Disable kms-message content in mongoc for libmongocrypt" FORCE)
      # Disable install() for the libbson static library. We'll do it ourselves
      set (ENABLE_STATIC BUILD_ONLY)
      # Disable zlib, which isn't necessary for libmongocrypt and isn't necessarily available.
      set (ENABLE_ZLIB OFF CACHE BOOL "Toggle zlib for the mongoc subproject (not required by libmongocrypt)")
      # Disable libzstd, which isn't necessary for libmongocrypt and isn't necessarily available.
      set (ENABLE_ZSTD OFF CACHE BOOL "Toggle libzstd for the mongoc subproject (not required by libmongocrypt)")
      # Disable snappy, which isn't necessary for libmongocrypt and isn't necessarily available.
      set (ENABLE_SNAPPY OFF CACHE BOOL "Toggle snappy for the mongoc subproject (not required by libmongocrypt)")
      # Disable deprecated automatic init and cleanup. (May be overridden by the user)
      set (ENABLE_AUTOMATIC_INIT_AND_CLEANUP OFF CACHE BOOL "Enable automatic init and cleanup (GCC only)")
      # We don't want the subproject to find libmongocrypt
      set (ENABLE_CLIENT_SIDE_ENCRYPTION OFF CACHE BOOL "Disable client-side encryption for the libmongoc subproject")
      # Clear `BUILD_VERSION` so C driver does not use a `BUILD_VERSION` meant for libmongocrypt.
      # Both libmongocrypt and C driver support setting a `BUILD_VERSION` to override the version.
      if (DEFINED CACHE{BUILD_VERSION})
         set (saved_cached_build_version "${BUILD_VERSION}")
         unset (BUILD_VERSION CACHE) # Undefine cache variable.
      endif ()
      if (DEFINED BUILD_VERSION)
         set (saved_build_version "${BUILD_VERSION}")
         unset (BUILD_VERSION) # Undefine normal variable.
      endif ()
      # Disable building tests in C driver:
      set (ENABLE_TESTS OFF)
      set (BUILD_TESTING OFF)
      # Disable counters in C driver. Counters are not supported on all platforms.
      set (ENABLE_SHM_COUNTERS OFF)
      # Add the subdirectory as a project. EXCLUDE_FROM_ALL to inhibit building and installing of components unless requested
      # SYSTEM (on applicable CMake versions) to prevent warnings (particularly from -Wconversion/-Wsign-conversion) from the C driver code
      if (CMAKE_VERSION VERSION_GREATER 3.25)
         add_subdirectory ("${MONGOCRYPT_MONGOC_DIR}" _mongo-c-driver EXCLUDE_FROM_ALL SYSTEM)
      else ()
         add_subdirectory ("${MONGOCRYPT_MONGOC_DIR}" _mongo-c-driver EXCLUDE_FROM_ALL)
      endif ()
      if (DEFINED saved_cached_build_version)
         set (BUILD_VERSION "${saved_cached_build_version}" CACHE STRING "Library version")
      endif ()
      if (DEFINED saved_build_version)
         set (BUILD_VERSION "${saved_build_version}")
      endif ()
      if (TARGET mongoc_static)
         # Workaround: Embedded mongoc_static does not set its INCLUDE_DIRECTORIES for user targets
         target_include_directories (mongoc_static
            PUBLIC
               "$<BUILD_INTERFACE:${MONGOCRYPT_MONGOC_DIR}/src/libmongoc/src>"
               "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/_mongo-c-driver/src/libmongoc/src/mongoc>"
            )
      endif ()
   endif ()
endfunction ()

# Do the import in a function to isolate variable scope
_import_bson ()

# Define interface targets to be used to control the libbson used at both build and import time.
# Refer to mongocrypt-config.cmake to see how these targets are used by consumers
add_library (_mongocrypt-libbson_for_static INTERFACE)
add_library (_mongocrypt-libbson_for_shared INTERFACE)
add_library (_mongocrypt::libbson_for_static ALIAS _mongocrypt-libbson_for_static)
add_library (_mongocrypt::libbson_for_shared ALIAS _mongocrypt-libbson_for_shared)
install (
   TARGETS _mongocrypt-libbson_for_static _mongocrypt-libbson_for_shared
   EXPORT mongocrypt_targets
)

# Link to the requested libbson, only exporting that usage for the local build tree.
# The mongocrypt-config file will later add the appropriate link library for downstream
# users during find_package()
if (USE_SHARED_LIBBSON)
   target_link_libraries (_mongocrypt-libbson_for_shared INTERFACE $<BUILD_INTERFACE:bson_shared>)
else ()
   target_link_libraries (_mongocrypt-libbson_for_shared INTERFACE $<BUILD_INTERFACE:bson_static>)
endif ()
# libbson_for_static always links to the static libbson:
target_link_libraries (_mongocrypt-libbson_for_static INTERFACE $<BUILD_INTERFACE:bson_static>)

if (TARGET mongoc_static)
   # And an alias to the mongoc target for use in some test cases
   add_library (_mongocrypt::mongoc ALIAS mongoc_static)
endif ()

# Put the libbson dynamic library into the current binary directory (plus possible config suffix).
# This ensures that libbson DLL will resolve on Windows when it searches during tests
set_property (TARGET bson_shared PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")

if (ENABLE_STATIC)
   # We are going to build a static libmongocrypt.
   # We want the static libbson target from the embedded mongoc. Enable the static library as
   # part of "all", and install the archive alongside the rest of our static libraries.
   # (Useful for some users for convenience of static-linking libmongocrypt: CDRIVER-3187)
   set_target_properties (bson_static PROPERTIES
      EXCLUDE_FROM_ALL FALSE
      OUTPUT_NAME bson-static-for-libmongocrypt
      )
   install (
      FILES $<TARGET_FILE:bson_static>
      DESTINATION "${CMAKE_INSTALL_LIBDIR}"
      RENAME ${CMAKE_STATIC_LIBRARY_PREFIX}bson-static-for-libmongocrypt${CMAKE_STATIC_LIBRARY_SUFFIX}
      )
endif ()