Skip to content

Commit

Permalink
secp256k1: CMake build system added
Browse files Browse the repository at this point in the history
  • Loading branch information
aleflm committed Dec 2, 2024
1 parent 2422a07 commit 3e2369a
Show file tree
Hide file tree
Showing 23 changed files with 726 additions and 1,305 deletions.
385 changes: 385 additions & 0 deletions src/secp256k1/CMakeLists.txt

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions src/secp256k1/cmake/CheckArm32Assembly.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function(check_arm32_assembly)
try_compile(HAVE_ARM32_ASM
${PROJECT_BINARY_DIR}/check_arm32_assembly
SOURCES ${PROJECT_SOURCE_DIR}/cmake/source_arm32.s
)
endfunction()
18 changes: 18 additions & 0 deletions src/secp256k1/cmake/CheckMemorySanitizer.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
include_guard(GLOBAL)
include(CheckCSourceCompiles)

function(check_memory_sanitizer output)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
check_c_source_compiles("
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
/* MemorySanitizer is enabled. */
# elif
# error \"MemorySanitizer is disabled.\"
# endif
#else
# error \"__has_feature is not defined.\"
#endif
" HAVE_MSAN)
set(${output} ${HAVE_MSAN} PARENT_SCOPE)
endfunction()
10 changes: 10 additions & 0 deletions src/secp256k1/cmake/CheckStringOptionValue.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function(check_string_option_value option)
get_property(expected_values CACHE ${option} PROPERTY STRINGS)
if(expected_values)
if(${option} IN_LIST expected_values)
return()
endif()
message(FATAL_ERROR "${option} value is \"${${option}}\", but must be one of ${expected_values}.")
endif()
message(AUTHOR_WARNING "The STRINGS property must be set before invoking `check_string_option_value' function.")
endfunction()
14 changes: 14 additions & 0 deletions src/secp256k1/cmake/CheckX86_64Assembly.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
include(CheckCSourceCompiles)

function(check_x86_64_assembly)
check_c_source_compiles("
#include <stdint.h>
int main()
{
uint64_t a = 11, tmp;
__asm__ __volatile__(\"movq $0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\");
}
" HAVE_X86_64_ASM)
set(HAVE_X86_64_ASM ${HAVE_X86_64_ASM} PARENT_SCOPE)
endfunction()
26 changes: 26 additions & 0 deletions src/secp256k1/cmake/FindGMP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Try to find the GNU Multiple Precision Arithmetic Library (GMP)
# See http://gmplib.org/

if (GMP_INCLUDES AND GMP_LIBRARIES)
set(GMP_FIND_QUIETLY TRUE)
endif (GMP_INCLUDES AND GMP_LIBRARIES)

find_path(GMP_INCLUDES
NAMES
gmp.h
PATHS
$ENV{GMPDIR}
${INCLUDE_INSTALL_DIR}
)

find_library(GMP_LIBRARIES gmp PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})

add_compile_definitions(HAVE_LIBGMP=1) # Define this symbol if libgmp is installed
add_compile_definitions(USE_NUM_GMP=1) # Define this symbol to use the gmp implementation for num
add_compile_definitions(USE_FIELD_INV_NUM=1) # Define this symbol to use the num-based field inverse implementation
add_compile_definitions(USE_SCALAR_INV_NUM=1) # Define this symbol to use the num-based scalar inverse implementation

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GMP DEFAULT_MSG
GMP_INCLUDES GMP_LIBRARIES)
mark_as_advanced(GMP_INCLUDES GMP_LIBRARIES)
41 changes: 41 additions & 0 deletions src/secp256k1/cmake/FindValgrind.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
if(CMAKE_HOST_APPLE)
find_program(BREW_COMMAND brew)
execute_process(
COMMAND ${BREW_COMMAND} --prefix valgrind
OUTPUT_VARIABLE valgrind_brew_prefix
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()

set(hints_paths)
if(valgrind_brew_prefix)
set(hints_paths ${valgrind_brew_prefix}/include)
endif()

find_path(Valgrind_INCLUDE_DIR
NAMES valgrind/memcheck.h
HINTS ${hints_paths}
)

if(Valgrind_INCLUDE_DIR)
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${Valgrind_INCLUDE_DIR})
check_c_source_compiles("
#include <valgrind/memcheck.h>
#if defined(NVALGRIND)
# error \"Valgrind does not support this platform.\"
#endif
int main() {}
" Valgrind_WORKS)
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Valgrind
REQUIRED_VARS Valgrind_INCLUDE_DIR Valgrind_WORKS
)

mark_as_advanced(
Valgrind_INCLUDE_DIR
)
8 changes: 8 additions & 0 deletions src/secp256k1/cmake/GeneratePkgConfigFile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function(generate_pkg_config_file in_file)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix \${prefix})
set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
set(PACKAGE_VERSION ${PROJECT_VERSION})
configure_file(${in_file} ${PROJECT_NAME}.pc @ONLY)
endfunction()
24 changes: 24 additions & 0 deletions src/secp256k1/cmake/TryAppendCFlags.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
include(CheckCCompilerFlag)

function(secp256k1_check_c_flags_internal flags output)
string(MAKE_C_IDENTIFIER "${flags}" result)
string(TOUPPER "${result}" result)
set(result "C_SUPPORTS_${result}")
if(NOT MSVC)
set(CMAKE_REQUIRED_FLAGS "-Werror")
endif()

# This avoids running a linker.
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
check_c_compiler_flag("${flags}" ${result})

set(${output} ${${result}} PARENT_SCOPE)
endfunction()

# Append flags to the COMPILE_OPTIONS directory property if CC accepts them.
macro(try_append_c_flags)
secp256k1_check_c_flags_internal("${ARGV}" result)
if(result)
add_compile_options(${ARGV})
endif()
endmacro()
3 changes: 3 additions & 0 deletions src/secp256k1/cmake/arm-linux-gnueabihf.toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
5 changes: 5 additions & 0 deletions src/secp256k1/cmake/config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")

check_required_components(@PROJECT_NAME@)
9 changes: 9 additions & 0 deletions src/secp256k1/cmake/source_arm32.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.syntax unified
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.text
.global main
main:
ldr r0, =0x002A
mov r7, #1
swi 0
3 changes: 3 additions & 0 deletions src/secp256k1/cmake/x86_64-w64-mingw32.toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
174 changes: 174 additions & 0 deletions src/secp256k1/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# Must be included before CMAKE_INSTALL_INCLUDEDIR is used.
include(GNUInstallDirs)

# Add objects explicitly rather than linking to the object libs to keep them
# from being exported.
add_library(secp256k1 OBJECT secp256k1.c)

target_link_libraries(secp256k1 PUBLIC gmp)

set_property(TARGET secp256k1 PROPERTY POSITION_INDEPENDENT_CODE ON)

add_library(secp256k1pp
cpp/GroupElement.cpp
cpp/MultiExponent.cpp
cpp/Scalar.cpp
)

target_link_libraries(secp256k1pp
PUBLIC secp256k1
)

add_library(secp256k1_asm INTERFACE)
if(SECP256K1_ASM STREQUAL "arm32")
add_library(secp256k1_asm_arm OBJECT EXCLUDE_FROM_ALL)
target_sources(secp256k1_asm_arm PUBLIC
asm/field_10x26_arm.s
)
target_sources(secp256k1 PRIVATE $<TARGET_OBJECTS:secp256k1_asm_arm>)
target_link_libraries(secp256k1_asm INTERFACE secp256k1_asm_arm)
endif()

if(WIN32)
# Define our export symbol only for shared libs.
set_target_properties(secp256k1 PROPERTIES DEFINE_SYMBOL SECP256K1_DLL_EXPORT)
target_compile_definitions(secp256k1 INTERFACE $<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:SECP256K1_STATIC>)
endif()

# Object libs don't know if they're being built for a shared or static lib.
# Grab the PIC property from secp256k1 which knows.
get_target_property(use_pic secp256k1 POSITION_INDEPENDENT_CODE)

target_include_directories(secp256k1 INTERFACE
# Add the include path for parent projects so that they don't have to manually add it.
$<BUILD_INTERFACE:$<$<NOT:$<BOOL:${PROJECT_IS_TOP_LEVEL}>>:${PROJECT_SOURCE_DIR}/include>>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

# This emulates Libtool to make sure Libtool and CMake agree on the ABI version,
# see below "Calculate the version variables" in build-aux/ltmain.sh.
math(EXPR ${PROJECT_NAME}_soversion "${${PROJECT_NAME}_LIB_VERSION_CURRENT} - ${${PROJECT_NAME}_LIB_VERSION_AGE}")
set_target_properties(secp256k1 PROPERTIES
SOVERSION ${${PROJECT_NAME}_soversion}
)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_target_properties(secp256k1 PROPERTIES
VERSION ${${PROJECT_NAME}_soversion}.${${PROJECT_NAME}_LIB_VERSION_AGE}.${${PROJECT_NAME}_LIB_VERSION_REVISION}
)
elseif(APPLE)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17)
math(EXPR ${PROJECT_NAME}_compatibility_version "${${PROJECT_NAME}_LIB_VERSION_CURRENT} + 1")
set_target_properties(secp256k1 PROPERTIES
MACHO_COMPATIBILITY_VERSION ${${PROJECT_NAME}_compatibility_version}
MACHO_CURRENT_VERSION ${${PROJECT_NAME}_compatibility_version}.${${PROJECT_NAME}_LIB_VERSION_REVISION}
)
unset(${PROJECT_NAME}_compatibility_version)
elseif(BUILD_SHARED_LIBS)
message(WARNING
"The 'compatibility version' and 'current version' values of the DYLIB "
"will diverge from the values set by the GNU Libtool. To ensure "
"compatibility, it is recommended to upgrade CMake to at least version 3.17."
)
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(${PROJECT_NAME}_windows "secp256k1")
if(MSVC)
set(${PROJECT_NAME}_windows "${PROJECT_NAME}")
endif()
set_target_properties(secp256k1 PROPERTIES
ARCHIVE_OUTPUT_NAME "${${PROJECT_NAME}_windows}"
RUNTIME_OUTPUT_NAME "${${PROJECT_NAME}_windows}-${${PROJECT_NAME}_soversion}"
)
unset(${PROJECT_NAME}_windows)
endif()
unset(${PROJECT_NAME}_soversion)

if(SECP256K1_BUILD_BENCHMARK)
add_executable(bench_ecdh bench_ecdh.c)
target_link_libraries(bench_ecdh PUBLIC secp256k1)
add_executable(bench_recover bench_recover.c)
target_link_libraries(bench_recover PUBLIC secp256k1)
add_executable(bench_sign bench_sign.c)
target_link_libraries(bench_sign PUBLIC secp256k1)
add_executable(bench_verify bench_verify.c)
target_link_libraries(bench_verify PUBLIC secp256k1)
add_executable(bench_internal bench_internal.c)
target_link_libraries(bench_internal PUBLIC secp256k1_asm gmp)
endif()

if(SECP256K1_BUILD_TESTS)
add_executable(noverify_tests tests.c)
target_compile_definitions(noverify_tests PRIVATE VERIFY)
target_link_libraries(noverify_tests secp256k1_asm gmp)
add_test(NAME secp256k1_noverify_tests COMMAND noverify_tests)
if(NOT CMAKE_BUILD_TYPE STREQUAL "Coverage")
add_executable(tests tests.c)
target_compile_definitions(tests PRIVATE VERIFY)
target_link_libraries(tests secp256k1_asm gmp)
add_test(NAME secp256k1_tests COMMAND tests)
endif()
endif()

if(SECP256K1_BUILD_EXHAUSTIVE_TESTS)
# Note: do not include secp256k1_precomputed in exhaustive_tests (it uses runtime-generated tables).
add_executable(exhaustive_tests tests_exhaustive.c)
target_link_libraries(exhaustive_tests secp256k1_asm gmp)
target_compile_definitions(exhaustive_tests PRIVATE $<$<NOT:$<CONFIG:Coverage>>:VERIFY>)
add_test(NAME secp256k1_exhaustive_tests COMMAND exhaustive_tests)
endif()

if(SECP256K1_INSTALL)
install(TARGETS secp256k1
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
set(${PROJECT_NAME}_headers
"${PROJECT_SOURCE_DIR}/include/secp256k1.h"
)
if(SECP256K1_ENABLE_MODULE_ECDH)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ecdh.h")
endif()
if(SECP256K1_ENABLE_MODULE_RECOVERY)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_recovery.h")
endif()
if(SECP256K1_ENABLE_MODULE_SCHNORR)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_schnorr.h")
endif()
install(FILES ${${PROJECT_NAME}_headers}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(EXPORT ${PROJECT_NAME}-targets
FILE ${PROJECT_NAME}-targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)

include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/config.cmake.in
${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
NO_SET_AND_CHECK_MACRO
)
write_basic_package_version_file(${PROJECT_NAME}-config-version.cmake
COMPATIBILITY SameMinorVersion
)

install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)

include(GeneratePkgConfigFile)
generate_pkg_config_file(${PROJECT_SOURCE_DIR}/libsecp256k1.pc.in)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)
endif()
Loading

0 comments on commit 3e2369a

Please sign in to comment.