|
| 1 | +cmake_minimum_required(VERSION 3.1) |
| 2 | + |
| 3 | +if(CMAKE_VERSION VERSION_GREATER 3.14) |
| 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 | +# The package (a.k.a. release) version is based on semantic versioning 2.0.0 of |
| 11 | +# the API. All changes in experimental modules are treated as |
| 12 | +# backwards-compatible and therefore at most increase the minor version. |
| 13 | +project(secp256k1 VERSION 0.2.1 LANGUAGES C) |
| 14 | + |
| 15 | +# The library version is based on libtool versioning of the ABI. The set of |
| 16 | +# rules for updating the version can be found here: |
| 17 | +# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html |
| 18 | +# All changes in experimental modules are treated as if they don't affect the |
| 19 | +# interface and therefore only increase the revision. |
| 20 | +set(${PROJECT_NAME}_LIB_VERSION_CURRENT 1) |
| 21 | +set(${PROJECT_NAME}_LIB_VERSION_REVISION 1) |
| 22 | +set(${PROJECT_NAME}_LIB_VERSION_AGE 0) |
| 23 | + |
| 24 | +set(CMAKE_C_STANDARD 90) |
| 25 | +set(CMAKE_C_EXTENSIONS OFF) |
| 26 | + |
| 27 | +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) |
| 28 | + |
| 29 | +# We do not use CMake's BUILD_SHARED_LIBS option. |
| 30 | +option(SECP256K1_BUILD_SHARED "Build shared library." ON) |
| 31 | +option(SECP256K1_BUILD_STATIC "Build static library." ON) |
| 32 | +if(NOT SECP256K1_BUILD_SHARED AND NOT SECP256K1_BUILD_STATIC) |
| 33 | + message(FATAL_ERROR "At least one of SECP256K1_BUILD_SHARED and SECP256K1_BUILD_STATIC must be enabled.") |
| 34 | +endif() |
| 35 | + |
| 36 | +option(SECP256K1_ENABLE_MODULE_ECDH "Enable ECDH module." ON) |
| 37 | +if(SECP256K1_ENABLE_MODULE_ECDH) |
| 38 | + add_definitions(-DENABLE_MODULE_ECDH=1) |
| 39 | +endif() |
| 40 | + |
| 41 | +option(SECP256K1_ENABLE_MODULE_RECOVERY "Enable ECDSA pubkey recovery module." OFF) |
| 42 | +if(SECP256K1_ENABLE_MODULE_RECOVERY) |
| 43 | + add_definitions(-DENABLE_MODULE_RECOVERY=1) |
| 44 | +endif() |
| 45 | + |
| 46 | +option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON) |
| 47 | +option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON) |
| 48 | +if(SECP256K1_ENABLE_MODULE_SCHNORRSIG) |
| 49 | + set(SECP256K1_ENABLE_MODULE_EXTRAKEYS ON) |
| 50 | + add_definitions(-DENABLE_MODULE_SCHNORRSIG=1) |
| 51 | +endif() |
| 52 | +if(SECP256K1_ENABLE_MODULE_EXTRAKEYS) |
| 53 | + add_definitions(-DENABLE_MODULE_EXTRAKEYS=1) |
| 54 | +endif() |
| 55 | + |
| 56 | +option(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS "Enable external default callback functions." OFF) |
| 57 | +if(SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS) |
| 58 | + add_definitions(-DUSE_EXTERNAL_DEFAULT_CALLBACKS=1) |
| 59 | +endif() |
| 60 | + |
| 61 | +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]") |
| 62 | +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) |
| 63 | +include(CheckStringOptionValue) |
| 64 | +check_string_option_value(SECP256K1_ECMULT_WINDOW_SIZE) |
| 65 | +if(SECP256K1_ECMULT_WINDOW_SIZE STREQUAL "AUTO") |
| 66 | + set(SECP256K1_ECMULT_WINDOW_SIZE 15) |
| 67 | +endif() |
| 68 | +add_definitions(-DECMULT_WINDOW_SIZE=${SECP256K1_ECMULT_WINDOW_SIZE}) |
| 69 | + |
| 70 | +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]") |
| 71 | +set_property(CACHE SECP256K1_ECMULT_GEN_PREC_BITS PROPERTY STRINGS "AUTO" 2 4 8) |
| 72 | +check_string_option_value(SECP256K1_ECMULT_GEN_PREC_BITS) |
| 73 | +if(SECP256K1_ECMULT_GEN_PREC_BITS STREQUAL "AUTO") |
| 74 | + set(SECP256K1_ECMULT_GEN_PREC_BITS 4) |
| 75 | +endif() |
| 76 | +add_definitions(-DECMULT_GEN_PREC_BITS=${SECP256K1_ECMULT_GEN_PREC_BITS}) |
| 77 | + |
| 78 | +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]") |
| 79 | +set_property(CACHE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY PROPERTY STRINGS "OFF" "int128_struct" "int128" "int64") |
| 80 | +check_string_option_value(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) |
| 81 | +if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) |
| 82 | + string(TOUPPER "${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}" widemul_upper_value) |
| 83 | + add_definitions(-DUSE_FORCE_WIDEMUL_${widemul_upper_value}=1) |
| 84 | +endif() |
| 85 | +mark_as_advanced(FORCE SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) |
| 86 | + |
| 87 | +set(SECP256K1_ASM "AUTO" CACHE STRING "Assembly optimizations to use: \"AUTO\", \"OFF\", \"x86_64\" or \"arm\" (experimental). [default=AUTO]") |
| 88 | +set_property(CACHE SECP256K1_ASM PROPERTY STRINGS "AUTO" "OFF" "x86_64" "arm") |
| 89 | +check_string_option_value(SECP256K1_ASM) |
| 90 | +if(SECP256K1_ASM STREQUAL "arm") |
| 91 | + enable_language(ASM) |
| 92 | + add_definitions(-DUSE_EXTERNAL_ASM=1) |
| 93 | +elseif(SECP256K1_ASM) |
| 94 | + include(Check64bitAssembly) |
| 95 | + check_64bit_assembly() |
| 96 | + if(HAS_64BIT_ASM) |
| 97 | + set(SECP256K1_ASM "x86_64") |
| 98 | + add_definitions(-DUSE_ASM_X86_64=1) |
| 99 | + elseif(SECP256K1_ASM STREQUAL "AUTO") |
| 100 | + set(SECP256K1_ASM "OFF") |
| 101 | + else() |
| 102 | + message(FATAL_ERROR "x86_64 assembly optimization requested but not available.") |
| 103 | + endif() |
| 104 | +endif() |
| 105 | + |
| 106 | +option(SECP256K1_EXPERIMENTAL "Allow experimental configuration options." OFF) |
| 107 | +if(NOT SECP256K1_EXPERIMENTAL) |
| 108 | + if(SECP256K1_ASM STREQUAL "arm") |
| 109 | + message(FATAL_ERROR "ARM assembly optimization is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.") |
| 110 | + endif() |
| 111 | +endif() |
| 112 | + |
| 113 | +set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]") |
| 114 | +set_property(CACHE SECP256K1_VALGRIND PROPERTY STRINGS "AUTO" "OFF" "ON") |
| 115 | +check_string_option_value(SECP256K1_VALGRIND) |
| 116 | +if(SECP256K1_VALGRIND) |
| 117 | + find_package(Valgrind MODULE) |
| 118 | + if(Valgrind_FOUND) |
| 119 | + set(SECP256K1_VALGRIND ON) |
| 120 | + include_directories(${Valgrind_INCLUDE_DIR}) |
| 121 | + add_definitions(-DVALGRIND) |
| 122 | + elseif(SECP256K1_VALGRIND STREQUAL "AUTO") |
| 123 | + set(SECP256K1_VALGRIND OFF) |
| 124 | + else() |
| 125 | + message(FATAL_ERROR "Valgrind support requested but valgrind/memcheck.h header not available.") |
| 126 | + endif() |
| 127 | +endif() |
| 128 | + |
| 129 | +option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON) |
| 130 | +option(SECP256K1_BUILD_TESTS "Build tests." ON) |
| 131 | +option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON) |
| 132 | +option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND}) |
| 133 | +option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF) |
| 134 | + |
| 135 | +# Redefine configuration flags. |
| 136 | +# We leave assertions on, because they are only used in the examples, and we want them always on there. |
| 137 | +if(MSVC) |
| 138 | + string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") |
| 139 | + string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") |
| 140 | + string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") |
| 141 | +else() |
| 142 | + string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") |
| 143 | + string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") |
| 144 | + string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}") |
| 145 | + # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.) |
| 146 | + string(REGEX REPLACE "-O3[ \t\r\n]*" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") |
| 147 | +endif() |
| 148 | + |
| 149 | +# Define custom "Coverage" build type. |
| 150 | +set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage -Wno-unused-parameter" CACHE STRING |
| 151 | + "Flags used by the C compiler during \"Coverage\" builds." |
| 152 | + FORCE |
| 153 | +) |
| 154 | +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING |
| 155 | + "Flags used for linking binaries during \"Coverage\" builds." |
| 156 | + FORCE |
| 157 | +) |
| 158 | +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING |
| 159 | + "Flags used by the shared libraries linker during \"Coverage\" builds." |
| 160 | + FORCE |
| 161 | +) |
| 162 | +mark_as_advanced( |
| 163 | + CMAKE_C_FLAGS_COVERAGE |
| 164 | + CMAKE_EXE_LINKER_FLAGS_COVERAGE |
| 165 | + CMAKE_SHARED_LINKER_FLAGS_COVERAGE |
| 166 | +) |
| 167 | + |
| 168 | +if(CMAKE_CONFIGURATION_TYPES) |
| 169 | + set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo" "Release" "Debug" "MinSizeRel" "Coverage") |
| 170 | +endif() |
| 171 | + |
| 172 | +get_property(cached_cmake_build_type CACHE CMAKE_BUILD_TYPE PROPERTY TYPE) |
| 173 | +if(cached_cmake_build_type) |
| 174 | + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY |
| 175 | + STRINGS "RelWithDebInfo" "Release" "Debug" "MinSizeRel" "Coverage" |
| 176 | + ) |
| 177 | +endif() |
| 178 | + |
| 179 | +set(default_build_type "RelWithDebInfo") |
| 180 | +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) |
| 181 | + message(STATUS "Setting build type to \"${default_build_type}\" as none was specified") |
| 182 | + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE) |
| 183 | +endif() |
| 184 | + |
| 185 | +include(TryAddCompileOption) |
| 186 | +if(MSVC) |
| 187 | + try_add_compile_option(/W2) |
| 188 | + try_add_compile_option(/wd4146) |
| 189 | +else() |
| 190 | + try_add_compile_option(-pedantic) |
| 191 | + try_add_compile_option(-Wall) |
| 192 | + try_add_compile_option(-Wcast-align) |
| 193 | + try_add_compile_option(-Wcast-align=strict) |
| 194 | + try_add_compile_option(-Wconditional-uninitialized) |
| 195 | + try_add_compile_option(-Wextra) |
| 196 | + try_add_compile_option(-Wnested-externs) |
| 197 | + try_add_compile_option(-Wno-long-long) |
| 198 | + try_add_compile_option(-Wno-overlength-strings) |
| 199 | + try_add_compile_option(-Wno-unused-function) |
| 200 | + try_add_compile_option(-Wreserved-identifier) |
| 201 | + try_add_compile_option(-Wshadow) |
| 202 | + try_add_compile_option(-Wstrict-prototypes) |
| 203 | + try_add_compile_option(-Wundef) |
| 204 | +endif() |
| 205 | + |
| 206 | +if(CMAKE_VERSION VERSION_GREATER 3.2) |
| 207 | + # Honor visibility properties for all target types. |
| 208 | + # See: https://cmake.org/cmake/help/latest/policy/CMP0063.html |
| 209 | + cmake_policy(SET CMP0063 NEW) |
| 210 | +endif() |
| 211 | +set(CMAKE_C_VISIBILITY_PRESET hidden) |
| 212 | + |
| 213 | +# Ask CTest to create a "check" target (e.g., make check) as alias for the "test" target. |
| 214 | +# CTEST_TEST_TARGET_ALIAS is not documented but supposed to be user-facing. |
| 215 | +# See: https://gitlab.kitware.com/cmake/cmake/-/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d2 |
| 216 | +set(CTEST_TEST_TARGET_ALIAS check) |
| 217 | +include(CTest) |
| 218 | +# We do not use CTest's BUILD_TESTING because a single toggle for all tests is too coarse for our needs. |
| 219 | +mark_as_advanced(BUILD_TESTING) |
| 220 | +if(SECP256K1_BUILD_BENCHMARK OR SECP256K1_BUILD_TESTS OR SECP256K1_BUILD_EXHAUSTIVE_TESTS OR SECP256K1_BUILD_CTIME_TESTS OR SECP256K1_BUILD_EXAMPLES) |
| 221 | + enable_testing() |
| 222 | +endif() |
| 223 | + |
| 224 | +add_subdirectory(src) |
| 225 | +if(SECP256K1_BUILD_EXAMPLES) |
| 226 | + add_subdirectory(examples) |
| 227 | +endif() |
| 228 | + |
| 229 | +message("\n") |
| 230 | +message("secp256k1 configure summary") |
| 231 | +message("===========================") |
| 232 | +message("Build artifacts:") |
| 233 | +message(" shared library ...................... ${SECP256K1_BUILD_SHARED}") |
| 234 | +message(" static library ...................... ${SECP256K1_BUILD_STATIC}") |
| 235 | +message("Optional modules:") |
| 236 | +message(" ECDH ................................ ${SECP256K1_ENABLE_MODULE_ECDH}") |
| 237 | +message(" ECDSA pubkey recovery ............... ${SECP256K1_ENABLE_MODULE_RECOVERY}") |
| 238 | +message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRAKEYS}") |
| 239 | +message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}") |
| 240 | +message("Parameters:") |
| 241 | +message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}") |
| 242 | +message(" ecmult gen precision bits ........... ${SECP256K1_ECMULT_GEN_PREC_BITS}") |
| 243 | +message("Optional features:") |
| 244 | +message(" assembly optimization ............... ${SECP256K1_ASM}") |
| 245 | +message(" external callbacks .................. ${SECP256K1_USE_EXTERNAL_DEFAULT_CALLBACKS}") |
| 246 | +if(SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY) |
| 247 | + message(" wide multiplication (test-only) ..... ${SECP256K1_TEST_OVERRIDE_WIDE_MULTIPLY}") |
| 248 | +endif() |
| 249 | +message("Optional binaries:") |
| 250 | +message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}") |
| 251 | +message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}") |
| 252 | +set(tests_status "${SECP256K1_BUILD_TESTS}") |
| 253 | +if(CMAKE_BUILD_TYPE STREQUAL "Coverage") |
| 254 | + set(tests_status OFF) |
| 255 | +endif() |
| 256 | +message(" tests ............................... ${tests_status}") |
| 257 | +message(" exhaustive tests .................... ${SECP256K1_BUILD_EXHAUSTIVE_TESTS}") |
| 258 | +message(" ctime_tests ......................... ${SECP256K1_BUILD_CTIME_TESTS}") |
| 259 | +message(" examples ............................ ${SECP256K1_BUILD_EXAMPLES}") |
| 260 | +message("") |
| 261 | +if(CMAKE_CROSSCOMPILING) |
| 262 | + set(cross_status "TRUE, for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}") |
| 263 | +else() |
| 264 | + set(cross_status "FALSE") |
| 265 | +endif() |
| 266 | +message("Cross compiling ....................... ${cross_status}") |
| 267 | +message("Valgrind .............................. ${SECP256K1_VALGRIND}") |
| 268 | +get_directory_property(definitions COMPILE_DEFINITIONS) |
| 269 | +string(REPLACE ";" " " definitions "${definitions}") |
| 270 | +message("Preprocessor defined macros ........... ${definitions}") |
| 271 | +message("C compiler ............................ ${CMAKE_C_COMPILER}") |
| 272 | +message("CFLAGS ................................ ${CMAKE_C_FLAGS}") |
| 273 | +get_directory_property(compile_options COMPILE_OPTIONS) |
| 274 | +string(REPLACE ";" " " compile_options "${compile_options}") |
| 275 | +message("Compile options ....................... " ${compile_options}) |
| 276 | +if(DEFINED CMAKE_BUILD_TYPE) |
| 277 | + message("Build type:") |
| 278 | + message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") |
| 279 | + string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) |
| 280 | + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}") |
| 281 | + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}") |
| 282 | + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}") |
| 283 | +else() |
| 284 | + message("Available configurations .............. ${CMAKE_CONFIGURATION_TYPES}") |
| 285 | + message("RelWithDebInfo configuration:") |
| 286 | + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}") |
| 287 | + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}") |
| 288 | + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}") |
| 289 | + message("Debug configuration:") |
| 290 | + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}") |
| 291 | + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") |
| 292 | + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") |
| 293 | +endif() |
| 294 | +message("\n") |
| 295 | +if(SECP256K1_EXPERIMENTAL) |
| 296 | + message( |
| 297 | + " ******\n" |
| 298 | + " WARNING: experimental build\n" |
| 299 | + " Experimental features do not have stable APIs or properties, and may not be safe for production use.\n" |
| 300 | + " ******\n" |
| 301 | + ) |
| 302 | +endif() |
0 commit comments