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 199 200 201 202 203 204 205 206 207 208
|
include (FetchContent)
# When updating the version of IntelDFP, also update the version in etc/purls.txt
set (_default_url "${PROJECT_SOURCE_DIR}/third-party/IntelRDFPMathLib20U2.tar.xz")
set (INTEL_DFP_LIBRARY_URL "${_default_url}"
CACHE STRING "The URL of an Intel DFP library to use")
set (INTEL_DFP_LIBRARY_URL_HASH
"SHA256=ac157e69c05556f3fa468ab34caeb1114a3b88ae18241bd41cc57b85a02dd314"
CACHE STRING "The hash of the archive that lives at INTEL_DFP_LIBRARY_URL (Spelled: <ALGO>=<digest>)")
option (INTEL_DFP_LIBRARY_PATCH_ENABLED
"Whether to apply patches to the Intel DFP library" ON)
set (_hash_arg)
if (NOT INTEL_DFP_LIBRARY_URL_SHA256 STREQUAL "no-verify")
set (_hash_arg URL_HASH "${INTEL_DFP_LIBRARY_URL_HASH}")
endif ()
set (patch_disabled OFF)
if (NOT INTEL_DFP_LIBRARY_PATCH_ENABLED)
set (patch_disabled ON)
endif ()
include (Patch)
make_patch_command (patch_command
STRIP_COMPONENTS 4
DIRECTORY "<SOURCE_DIR>"
DISABLED "${patch_disabled}"
PATCHES
"${PROJECT_SOURCE_DIR}/etc/mongo-inteldfp-s390x.patch"
"${PROJECT_SOURCE_DIR}/etc/mongo-inteldfp-MONGOCRYPT-571.patch"
"${PROJECT_SOURCE_DIR}/etc/mongo-inteldfp-libmongocrypt-pr-625.patch"
"${PROJECT_SOURCE_DIR}/etc/mongo-inteldfp-alpine-arm-fix.patch"
)
# NOTE: The applying of the patch expects the correct input directly from the
# expanded archive. If the patch needs to be reapplied, you may see errors
# about trying to update the intel_dfp component. If you are seeing such
# errors, delete the `_deps/` subdirectory in the build tree and
# re-run CMake the project.
FetchContent_Declare (
intel_dfp
URL "${_default_url}"
${_hash_arg}
PATCH_COMMAND ${patch_command} --verbose
SOURCE_SUBDIR "NO_ADD_SUBDIRECTORY" # Targets are manually defined below.
)
FetchContent_GetProperties (intel_dfp)
if (NOT intel_dfp_POPULATED)
message (STATUS "Obtaining Intel Decimal FP library: ${INTEL_DFP_LIBRARY_URL}")
if("${CMAKE_VERSION}" VERSION_LESS "3.18.0")
# SOURCE_SUBDIR is not yet supported.
FetchContent_Populate(intel_dfp)
else()
FetchContent_MakeAvailable(intel_dfp)
endif()
endif ()
# This list of sources was generated by copying the MongoDB server and removing any unnecessary.
# Carefully add sources if more functionality is needed. Bundled sources are checked by static analysis, and may result in a larger binary.
# The "<library>" prefix is replaced below.
# Refer: https://github.com/mongodb/mongo/blob/e9be40f47a77af1931773ad671d4927c0fe6969a/src/third_party/IntelRDFPMathLib20U1/SConscript
set (_dfp_sources
"<library>/float128/dpml_exception.c"
"<library>/float128/dpml_ux_bid.c"
"<library>/float128/dpml_ux_log.c"
"<library>/float128/dpml_ux_ops.c"
"<library>/float128/dpml_ux_ops_64.c"
"<library>/src/bid128.c"
"<library>/src/bid128_2_str_tables.c"
"<library>/src/bid128_add.c"
"<library>/src/bid128_compare.c"
"<library>/src/bid128_div.c"
"<library>/src/bid128_fma.c"
"<library>/src/bid128_fmod.c"
"<library>/src/bid128_log10.c"
"<library>/src/bid128_log2.c"
"<library>/src/bid128_modf.c"
"<library>/src/bid128_mul.c"
"<library>/src/bid128_noncomp.c"
"<library>/src/bid128_round_integral.c"
"<library>/src/bid128_scalb.c"
"<library>/src/bid128_scalbl.c"
"<library>/src/bid128_string.c"
"<library>/src/bid128_to_int64.c"
"<library>/src/bid64_to_bid128.c"
"<library>/src/bid_binarydecimal.c"
"<library>/src/bid_convert_data.c"
"<library>/src/bid_decimal_data.c"
"<library>/src/bid_flag_operations.c"
"<library>/src/bid_round.c"
)
# Put in the actual library path:
string (REPLACE "<library>" "${intel_dfp_SOURCE_DIR}/LIBRARY" _dfp_sources "${_dfp_sources}")
#[[
Intel DFP gives us a very blunt yet powerful hammer to avoid symbol
collision, since other library may also want a conflicting
DFP version: Just rename everything!
All function names are #defined with a `bid` or `binary` prefix, and are
aliased to their "actual" names with a `__bid` or `__binary` prefix,
respectively.
So we can ship our own decimal library without worry, we'll rename those
hidden symbols.
]]
file (READ "${intel_dfp_SOURCE_DIR}/LIBRARY/src/bid_conf.h" dfp_conf_content)
string (REGEX REPLACE
#[[
Match every "#define X Y" where X begins with `"bid" or "binary", and Y
begins with "__bid" or "__binary". X and Y must be separated by one or
more spaces.
]]
"#define ((bid|binary)[^ ]+ +)__(bid|binary)([^ +])"
# Replace Y with "__mongocrypt_bid" or "__mongocrypt_binary" as the new prefix.
"#define \\1 __mongocrypt_\\3\\4"
new_content "${dfp_conf_content}"
)
if (NOT new_content STREQUAL dfp_conf_content)
# Only rewrite the file if we changed anything, otherwise we update build
# input timestamps and will trigger a rebuild of DFP.
file (WRITE "${intel_dfp_SOURCE_DIR}/LIBRARY/src/bid_conf.h" "${new_content}")
endif ()
# Define the object library
add_library (intel_dfp_obj OBJECT ${_dfp_sources})
# Build with -fPIC, since these objects may go into a static OR dynamic library.
set_property (TARGET intel_dfp_obj PROPERTY POSITION_INDEPENDENT_CODE TRUE)
# DFP needs information about the build target platform. Compute that:
set (proc_lower $<LOWER_CASE:${CMAKE_SYSTEM_PROCESSOR}>)
set (ia32_list i386 i486 i586 i686 pentium3 pentium4 athlon geode emscripted x86 arm)
set (efi2_list aarch64 arm64 x86_64 ppc64le riscv64)
set (is_linux $<PLATFORM_ID:Linux>)
set (is_windows $<PLATFORM_ID:Windows>)
set (is_unix $<NOT:${is_windows}>)
# These compiler definitions may seem a bit strange, but the whole DFP library's
# config process is strange. These options match those used in MongoDB server.
target_compile_definitions (intel_dfp_obj PUBLIC
DECIMAL_CALL_BY_REFERENCE=0
DECIMAL_GLOBAL_ROUNDING=0
DECIMAL_GLOBAL_EXCEPTION_FLAGS=0
UNCHANGED_BINARY_STATUS_FLAGS=0
USE_COMPILER_F128_TYPE=0
USE_COMPILER_F80_TYPE=0
USE_NATIVE_QUAD_TYPE=0
$<${is_unix}:LINUX=1>
$<$<PLATFORM_ID:Darwin>:mach=1>
$<$<PLATFORM_ID:FreeBSD>:freebsd=1>
$<$<PLATFORM_ID:Linux>:linux=1>
$<${is_windows}:
WINDOWS=1
WNT=1
winnt=1
>
$<$<IN_LIST:${proc_lower},${ia32_list}>:
IA32=1
ia32=1
>
$<$<IN_LIST:${proc_lower},${efi2_list}>:
EFI2=1
efi2=1
>
$<$<STREQUAL:${proc_lower},s390x>:
s390x=1
BID_BIG_ENDIAN=1
>
)
# Suppress warnings in the Intel library, as it generates a lot that aren't of interest
target_compile_options (intel_dfp_obj PRIVATE -w)
target_include_directories(intel_dfp_obj PUBLIC ${intel_dfp_SOURCE_DIR}/LIBRARY/src)
# Define an interface library that attaches the built TUs to the consumer
add_library (_mongocrypt_intel_dfp INTERFACE)
add_library (mongocrypt::intel_dfp ALIAS _mongocrypt_intel_dfp)
# Notify in-tree consumers that IntelDFP is available:
target_compile_definitions (_mongocrypt_intel_dfp INTERFACE $<BUILD_INTERFACE:MONGOCRYPT_INTELDFP>)
target_sources (_mongocrypt_intel_dfp
#[[
For targets *within this build* that link with mongocrypt::intel_dfp,
inject the generated TUs (object files) from the intel_dfp_obj library.
This will be stripped out of the interface library when it is installed,
since we don't want to ship the DFP object separately. Instead, users
will link to libmongocrypt, which will contain the necessary TUs for
the library (because they link to this interface library).
]]
INTERFACE $<BUILD_INTERFACE:$<TARGET_OBJECTS:intel_dfp_obj>>
)
target_link_libraries (_mongocrypt_intel_dfp
INTERFACE
$<BUILD_INTERFACE:intel_dfp_obj>
# We do want to propagate an interface requirement: Some platforms need a
# separate link library to support special math functions.
$<$<PLATFORM_ID:Linux>:m>
)
# Give the installed target a name to indicate its hidden-ness
set_property (TARGET _mongocrypt_intel_dfp PROPERTY EXPORT_NAME private::intel_dfp_interface)
install (TARGETS _mongocrypt_intel_dfp EXPORT mongocrypt_targets)
|