CMakeLists.txt (16952B)
1 cmake_minimum_required(VERSION 3.13) 2 3 if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) 4 # MSVC runtime library flags are selected by the CMAKE_MSVC_RUNTIME_LIBRARY abstraction. 5 cmake_policy(SET CMP0091 NEW) 6 # MSVC warning flags are not in CMAKE_<LANG>_FLAGS by default. 7 cmake_policy(SET CMP0092 NEW) 8 endif() 9 10 project(libsecp256k1 11 # The package (a.k.a. release) version is based on semantic versioning 2.0.0 of 12 # the API. All changes in experimental modules are treated as 13 # backwards-compatible and therefore at most increase the minor version. 14 VERSION 0.4.2 15 DESCRIPTION "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1." 16 HOMEPAGE_URL "https://github.com/bitcoin-core/secp256k1" 17 LANGUAGES C 18 ) 19 20 if(CMAKE_VERSION VERSION_LESS 3.21) 21 get_directory_property(parent_directory PARENT_DIRECTORY) 22 if(parent_directory) 23 set(PROJECT_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.") 24 set(${PROJECT_NAME}_IS_TOP_LEVEL OFF CACHE INTERNAL "Emulates CMake 3.21+ behavior.") 25 else() 26 set(PROJECT_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.") 27 set(${PROJECT_NAME}_IS_TOP_LEVEL ON CACHE INTERNAL "Emulates CMake 3.21+ behavior.") 28 endif() 29 unset(parent_directory) 30 endif() 31 32 # The library version is based on libtool versioning of the ABI. The set of 33 # rules for updating the version can be found here: 34 # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html 35 # All changes in experimental modules are treated as if they don't affect the 36 # interface and therefore only increase the revision. 37 set(${PROJECT_NAME}_LIB_VERSION_CURRENT 3) 38 set(${PROJECT_NAME}_LIB_VERSION_REVISION 2) 39 set(${PROJECT_NAME}_LIB_VERSION_AGE 1) 40 41 set(CMAKE_C_STANDARD 90) 42 set(CMAKE_C_EXTENSIONS OFF) 43 44 list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 45 46 option(BUILD_SHARED_LIBS "Build shared libraries." ON) 47 option(SECP256K1_DISABLE_SHARED "Disable shared library. Overrides BUILD_SHARED_LIBS." OFF) 48 if(SECP256K1_DISABLE_SHARED) 49 set(BUILD_SHARED_LIBS OFF) 50 endif() 51 52 option(SECP256K1_INSTALL "Enable installation." ${PROJECT_IS_TOP_LEVEL}) 53 54 ## Modules 55 56 # We declare all options before processing them, to make sure we can express 57 # dependendencies while processing. 58 option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON) 59 option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF) 60 option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON) 61 option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON) 62 option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON) 63 64 # Processing must be done in a topological sorting of the dependency graph 65 # (dependent module first). 66 if(SECP256K1_ENABLE_MODULE_ELLSWIFT) 67 add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1) 68 endif() 69 70 if(SECP256K1_ENABLE_MODULE_SCHNORRSIG) 71 if(DEFINED SECP256K1_ENABLE_MODULE_EXTRAKEYS AND NOT SECP256K1_ENABLE_MODULE_EXTRAKEYS) 72 message(FATAL_ERROR "Module dependency error: You have disabled the extrakeys module explicitly, but it is required by the schnorrsig module.") 73 endif() 74 set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON) 75 add_compile_definitions(ENABLE_MODULE_SCHNORRSIG=1) 76 endif() 77 78 if(SECP256K1_ENABLE_MODULE_EXTRAKEYS) 79 add_compile_definitions(ENABLE_MODULE_EXTRAKEYS=1) 80 endif() 81 82 if(SECP256K1_ENABLE_MODULE_RECOVERY) 83 add_compile_definitions(ENABLE_MODULE_RECOVERY=1) 84 endif() 85 86 if(SECP256K1_ENABLE_MODULE_ECDH) 87 add_compile_definitions(ENABLE_MODULE_ECDH=1) 88 endif() 89 90 option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF) 91 if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS) 92 add_compile_definitions(USE_EXTERNAL_DEFAULT_CALLBACKS=1) 93 endif() 94 95 set(SECP256K1_ECMULT_WINDOW_SIZE "AUTO" CACHE STRING "Window size for ecmult precomputation for verification, specified as integer in range [2..24]. \"AUTO\" is a reasonable setting for desktop machines (currently 15). [default=AUTO]") 96 set_property(CACHE SECP256K1_ECMULT_WINDOW_SIZE PROPERTY STRINGS "AUTO" 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) 97 include(CheckStringOptionValue) 98 check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE) 99 if(SECP256K1_ECMULT_WINDOW_SIZE STREQUAL "AUTO") 100 set(SECP256K1_ECMULT_WINDOW_SIZE 15) 101 endif() 102 add_compile_definitions(ECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE}) 103 104 set(SECP256K1_ECMULT_GEN_PREC_BITS "AUTO" CACHE STRING "Precision bits to tune the precomputed table size for signing, specified as integer 2, 4 or 8. \"AUTO\" is a reasonable setting for desktop machines (currently 4). [default=AUTO]") 105 set_property(CACHE SECP256K1_ECMULT_GEN_PREC_BITS PROPERTY STRINGS "AUTO" 2 4 8) 106 check_string_option_value(SECP256K1_ECMULT_GEN_PREC_BITS) 107 if(SECP256K1_ECMULT_GEN_PREC_BITS STREQUAL "AUTO") 108 set(SECP256K1_ECMULT_GEN_PREC_BITS 4) 109 endif() 110 add_compile_definitions(ECMULT_GEN_PREC_BITS=${SECP256K1_ECMULT_GEN_PREC_BITS}) 111 112 set(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY "OFF" CACHE STRING "Test-only override of the (autodetected by the C code) \"widemul\" setting. Legal values are: \"OFF\", \"int128_struct\", \"int128\" or \"int64\". [default=OFF]") 113 set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64") 114 check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) 115 if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) 116 string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value) 117 add_compile_definitions(USE_FORCE_WIDEMUL_${widemul_upper_value}=1) 118 endif() 119 mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) 120 121 set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm32\" (experimental). [default=AUTO]") 122 set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm32") 123 check_string_option_value(SECP256K1_ASM) 124 if(SECP256K1_ASM STREQUAL "arm32") 125 enable_language(ASM) 126 include(CheckArm32Assembly) 127 check_arm32_assembly() 128 if(HAVE_ARM32_ASM) 129 add_compile_definitions(USE_EXTERNAL_ASM=1) 130 else() 131 message(FATAL_ERROR "ARM32 assembly requested but not available.") 132 endif() 133 elseif(SECP256K1_ASM) 134 include(CheckX86_64Assembly) 135 check_x86_64_assembly() 136 if(HAVE_X86_64_ASM) 137 set(SECP256K1_ASM "x86_64") 138 add_compile_definitions(USE_ASM_X86_64=1) 139 elseif(SECP256K1_ASM STREQUAL "AUTO") 140 set(SECP256K1_ASM "OFF") 141 else() 142 message(FATAL_ERROR "x86_64 assembly requested but not available.") 143 endif() 144 endif() 145 146 option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF) 147 if(NOT SECP256K1_EXPERIMENTAL) 148 if(SECP256K1_ASM STREQUAL "arm32") 149 message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.") 150 endif() 151 endif() 152 153 set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]") 154 set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON") 155 check_string_option_value(SECP256K1_VALGRIND) 156 if(SECP256K1_VALGRIND) 157 find_package(Valgrind MODULE) 158 if(Valgrind_FOUND) 159 set(SECP256K1_VALGRIND ON) 160 include_directories(${Valgrind_INCLUDE_DIR}) 161 add_compile_definitions(VALGRIND) 162 elseif(SECP256K1_VALGRIND STREQUAL "AUTO") 163 set(SECP256K1_VALGRIND OFF) 164 else() 165 message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.") 166 endif() 167 endif() 168 169 option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON) 170 option(SECP256K1_BUILD_TESTS "Build tests." ON) 171 option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON) 172 option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND}) 173 option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF) 174 175 # Redefine configuration flags. 176 # We leave assertions on, because they are only used in the examples, and we want them always on there. 177 if(MSVC) 178 string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") 179 string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") 180 string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") 181 else() 182 string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") 183 string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") 184 string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") 185 # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.) 186 string(REGEX REPLACE "-O3[ \t\r\n]*" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") 187 endif() 188 189 # Define custom "Coverage" build type. 190 set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING 191 "Flags used by the C compiler during \"Coverage\" builds." 192 FORCE 193 ) 194 set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING 195 "Flags used for linking binaries during \"Coverage\" builds." 196 FORCE 197 ) 198 set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING 199 "Flags used by the shared libraries linker during \"Coverage\" builds." 200 FORCE 201 ) 202 mark_as_advanced( 203 CMAKE_C_FLAGS_COVERAGE 204 CMAKE_EXE_LINKER_FLAGS_COVERAGE 205 CMAKE_SHARED_LINKER_FLAGS_COVERAGE 206 ) 207 208 get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 209 set(default_build_type "RelWithDebInfo") 210 if(is_multi_config) 211 set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING 212 "Supported configuration types." 213 FORCE 214 ) 215 else() 216 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY 217 STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" 218 ) 219 if(NOT CMAKE_BUILD_TYPE) 220 message(STATUS "Setting build type to \"${default_build_type}\" as none was specified") 221 set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING 222 "Choose the type of build." 223 FORCE 224 ) 225 endif() 226 endif() 227 228 include(TryAppendCFlags) 229 if(MSVC) 230 # Keep the following commands ordered lexicographically. 231 try_append_c_flags(/W3) # Production quality warning level. 232 try_append_c_flags(/wd4146) # Disable warning C4146 "unary minus operator applied to unsigned type, result still unsigned". 233 try_append_c_flags(/wd4244) # Disable warning C4244 "'conversion' conversion from 'type1' to 'type2', possible loss of data". 234 try_append_c_flags(/wd4267) # Disable warning C4267 "'var' : conversion from 'size_t' to 'type', possible loss of data". 235 # Eliminate deprecation warnings for the older, less secure functions. 236 add_compile_definitions(_CRT_SECURE_NO_WARNINGS) 237 else() 238 # Keep the following commands ordered lexicographically. 239 try_append_c_flags(-pedantic) 240 try_append_c_flags(-Wall) # GCC >= 2.95 and probably many other compilers. 241 try_append_c_flags(-Wcast-align) # GCC >= 2.95. 242 try_append_c_flags(-Wcast-align=strict) # GCC >= 8.0. 243 try_append_c_flags(-Wconditional-uninitialized) # Clang >= 3.0 only. 244 try_append_c_flags(-Wextra) # GCC >= 3.4, this is the newer name of -W, which we don't use because older GCCs will warn about unused functions. 245 try_append_c_flags(-Wnested-externs) 246 try_append_c_flags(-Wno-long-long) # GCC >= 3.0, -Wlong-long is implied by -pedantic. 247 try_append_c_flags(-Wno-overlength-strings) # GCC >= 4.2, -Woverlength-strings is implied by -pedantic. 248 try_append_c_flags(-Wno-unused-function) # GCC >= 3.0, -Wunused-function is implied by -Wall. 249 try_append_c_flags(-Wreserved-identifier) # Clang >= 13.0 only. 250 try_append_c_flags(-Wshadow) 251 try_append_c_flags(-Wstrict-prototypes) 252 try_append_c_flags(-Wundef) 253 endif() 254 255 set(CMAKE_C_VISIBILITY_PRESET hidden) 256 257 # Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target. 258 # CTEST_TEST_TARGET_ALIAS is not documented but supposed to be user-facing. 259 # See: https://gitlab.kitware.com/cmake/cmake/-/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d2 260 set(CTEST_TEST_TARGET_ALIAS check) 261 include(CTest) 262 # We do not use CTest's BUILD_TESTING because a single toggle for all tests is too coarse for our needs. 263 mark_as_advanced(BUILD_TESTING) 264 if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUSTIVE_TESTS OR SECP256K1_BUILD_CTIME_TESTS OR SECP256K1_BUILD_EXAMPLES) 265 enable_testing() 266 endif() 267 268 set(SECP256K1_LATE_CFLAGS "" CACHE STRING "Compiler flags that are added to the command line after all other flags added by the build system.") 269 include(AllTargetsCompileOptions) 270 271 add_subdirectory(src) 272 all_targets_compile_options(src "${SECP256K1_LATE_CFLAGS}") 273 if(SECP256K1_BUILD_EXAMPLES) 274 add_subdirectory(examples) 275 all_targets_compile_options(examples "${SECP256K1_LATE_CFLAGS}") 276 endif() 277 278 message("\n") 279 message("secp256k1 configure summary") 280 message("===========================") 281 message("Build artifacts:") 282 if(BUILD_SHARED_LIBS) 283 set(library_type "Shared") 284 else() 285 set(library_type "Static") 286 endif() 287 288 message(" library type ........................ ${library_type}") 289 message("Optional modules:") 290 message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}") 291 message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}") 292 message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}") 293 message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}") 294 message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}") 295 message("Parameters:") 296 message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}") 297 message(" ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}") 298 message("Optional features:") 299 message(" assembly ............................ ${SECP256K1_ASM}") 300 message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}") 301 if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) 302 message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}") 303 endif() 304 message("Optional binaries:") 305 message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}") 306 message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}") 307 set(tests_status "${SECP256K1_BUILD_TESTS}") 308 if(CMAKE_BUILD_TYPE STREQUAL "Coverage") 309 set(tests_status OFF) 310 endif() 311 message(" tests ............................... ${tests_status}") 312 message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}") 313 message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}") 314 message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}") 315 message("") 316 if(CMAKE_CROSSCOMPILING) 317 set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") 318 else() 319 set(cross_status "FALSE") 320 endif() 321 message("Cross compiling ....................... ${cross_status}") 322 message("Valgrind .............................. ${SECP256K1_VALGRIND}") 323 get_directory_property(definitions COMPILE_DEFINITIONS) 324 string(REPLACE ";" " " definitions "${definitions}") 325 message("Preprocessor defined macros ........... ${definitions}") 326 message("C compiler ............................ ${CMAKE_C_COMPILER}") 327 message("CFLAGS ................................ ${CMAKE_C_FLAGS}") 328 get_directory_property(compile_options COMPILE_OPTIONS) 329 string(REPLACE ";" " " compile_options "${compile_options}") 330 message("Compile options ....................... " ${compile_options}) 331 if(NOT is_multi_config) 332 message("Build type:") 333 message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") 334 string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) 335 message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}") 336 message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}") 337 message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}") 338 else() 339 message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}") 340 message("RelWithDebInfo configuration:") 341 message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}") 342 message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") 343 message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}") 344 message("Debug configuration:") 345 message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}") 346 message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") 347 message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") 348 endif() 349 if(SECP256K1_LATE_CFLAGS) 350 message("SECP256K1_LATE_CFLAGS ................. ${SECP256K1_LATE_CFLAGS}") 351 endif() 352 message("\n") 353 if(SECP256K1_EXPERIMENTAL) 354 message( 355 " ******\n" 356 " WARNING: experimental build\n" 357 " Experimental features do not have stable APIs or properties, and may not be safe for production use.\n" 358 " ******\n" 359 ) 360 endif()