Skip to content

Commit

Permalink
build: Add CMake-based build system
Browse files Browse the repository at this point in the history
  • Loading branch information
hebasto committed Jun 29, 2022
1 parent 44c2452 commit ff836b6
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,6 @@ build-aux/compile
build-aux/test-driver
src/stamp-h1
libsecp256k1.pc

# Default CMake build directory.
/build
119 changes: 119 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Copyright 2022
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php.

cmake_minimum_required(VERSION 3.1)
if(CMAKE_VERSION VERSION_GREATER 3.14)
cmake_policy(SET CMP0092 NEW)
endif()
project(secp256k1 VERSION 0.1.0 LANGUAGES C)

set(CMAKE_C_STANDARD 90)
set(CMAKE_C_EXTENSIONS OFF)

option(ENABLE_DEV_MODE "enable all binaries and modules by default but individual options can still be overridden explicitly" OFF)

option(BUILD_BENCHMARK "build benchmarks" ON)
option(BUILD_TESTS "build tests" ON)
option(BUILD_EXHAUSTIVE_TESTS "build exhaustive tests" ON)
option(BUILD_EXAMPLES "build examples" ${ENABLE_DEV_MODE})

option(ENABLE_MODULE_ECDH "enable ECDH module" ${ENABLE_DEV_MODE})
option(ENABLE_MODULE_RECOVERY "enable ECDSA pubkey recovery module" ${ENABLE_DEV_MODE})
option(ENABLE_MODULE_EXTRAKEYS "enable extrakeys module" ${ENABLE_DEV_MODE})
option(ENABLE_MODULE_SCHNORRSIG "enable schnorrsig module" ${ENABLE_DEV_MODE})

option(ALLOW_EXPERIMENTAL "allow experimental configure options" ${ENABLE_DEV_MODE})
option(USE_EXTERNAL_DEFAULT_CALLBACKS "enable external default callback functions" OFF)
option(COVERAGE "enable compiler flags to support coverage analysis" ${ENABLE_DEV_MODE})

set(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]")
if(ECMULT_WINDOW_SIZE STREQUAL auto)
set(ECMULT_WINDOW_SIZE 15)
endif()
if(NOT ECMULT_WINDOW_SIZE MATCHES ^[1-9][0-9]*$ OR ECMULT_WINDOW_SIZE LESS 2 OR ECMULT_WINDOW_SIZE GREATER 24)
message(FATAL_ERROR "ECMULT_WINDOW_SIZE value is \"${ECMULT_WINDOW_SIZE}\", but must an integer in range [2..24] or \"auto\".")
endif()

set(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]")
if(ECMULT_GEN_PREC_BITS STREQUAL auto)
set(ECMULT_GEN_PREC_BITS 4)
endif()
if(NOT ECMULT_GEN_PREC_BITS STREQUAL 2 AND NOT ECMULT_GEN_PREC_BITS STREQUAL 4 AND NOT ECMULT_GEN_PREC_BITS STREQUAL 8)
message(FATAL_ERROR "ECMULT_GEN_PREC_BITS value is \"${ECMULT_GEN_PREC_BITS}\", but must an integer 2, 4, 8, or \"auto\".")
endif()

option(USE_FORCE_WIDEMUL_INT128 "force the use of the (unsigned) __int128 based wide multiplication implementation" OFF)
option(USE_FORCE_WIDEMUL_INT64 "force the use of the (u)int64_t based wide multiplication implementation" OFF)
if (USE_FORCE_WIDEMUL_INT128 AND USE_FORCE_WIDEMUL_INT64)
message(FATAL_ERROR "USE_FORCE_WIDEMUL_INT128 and USE_FORCE_WIDEMUL_INT64 cannot be enabled simultaneously.")
endif()

mark_as_advanced(FORCE
ENABLE_DEV_MODE
USE_FORCE_WIDEMUL_INT128
USE_FORCE_WIDEMUL_INT64
)

configure_file(
"cmake/libsecp256k1-config.h.in"
"${PROJECT_BINARY_DIR}/src/libsecp256k1-config.h"
)

include(cmake/secp_try_append_cflag.cmake)
secp_try_append_cflag(-pedantic)
secp_try_append_cflag(-Wno-long-long)
secp_try_append_cflag(-Wnested-externs)
secp_try_append_cflag(-Wshadow)
secp_try_append_cflag(-Wstrict-prototypes)
secp_try_append_cflag(-Wundef)
secp_try_append_cflag(-Wno-overlength-strings)
secp_try_append_cflag(-Wall)
secp_try_append_cflag(-Wno-unused-function)
secp_try_append_cflag(-Wextra)
secp_try_append_cflag(-Wcast-align)
secp_try_append_cflag(-Wcast-align=strict)
secp_try_append_cflag(-Wconditional-uninitialized)

if(CMAKE_VERSION VERSION_GREATER 3.2)
cmake_policy(SET CMP0063 NEW)
endif()
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)

add_subdirectory(src)

message("\n")
message("Configure summary")
message("=================")
if(CMAKE_CROSSCOMPILING)
message("Cross compiling for ${CMAKE_SYSTEM_NAME}, ${CMAKE_SYSTEM_PROCESSOR}")
endif()
message("Optional binaries:")
message(" benchmark ........................ ${BUILD_BENCHMARK}")
message(" tests ............................ ${BUILD_TESTS}")
message(" exhaustive tests ................. ${BUILD_EXHAUSTIVE_TESTS}")
message(" examples ......................... ${BUILD_EXAMPLES}")
message("Optional modules:")
message(" ECDH ............................. ${ENABLE_MODULE_ECDH}")
message(" ECDSA pubkey recovery ............ ${ENABLE_MODULE_RECOVERY}")
message(" extrakeys ........................ ${ENABLE_MODULE_EXTRAKEYS}")
message(" schnorrsig ....................... ${ENABLE_MODULE_SCHNORRSIG}")
message("Parameters:")
message(" ecmult window size ............... ${ECMULT_WINDOW_SIZE}")
message(" ecmult gen precision bits ........ ${ECMULT_GEN_PREC_BITS}")
message("Optional features:")
message(" external callbacks ............... ${USE_EXTERNAL_DEFAULT_CALLBACKS}")
if(BUILD_TESTS OR BUILD_EXHAUSTIVE_TESTS)
message(" support kcov coverage analysis ... ${COVERAGE}")
endif()
if(USE_FORCE_WIDEMUL_INT128)
message(" override wide multiplication ..... int128")
endif()
if(USE_FORCE_WIDEMUL_INT64)
message(" override wide multiplication ..... int64")
endif()
message("\n")
message("CC: ${CMAKE_C_COMPILER}")
message("CFLAGS: ${CMAKE_C_FLAGS}")
message("\n")
58 changes: 54 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@ Implementation details
* Optional runtime blinding which attempts to frustrate differential power analysis.
* The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.

Build steps
-----------

libsecp256k1 is built using autotools:
Building with Autotools
-----------------------

$ ./autogen.sh
$ ./configure
Expand All @@ -70,6 +68,58 @@ libsecp256k1 is built using autotools:

To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags.

Building with CMake
-------------------

To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.

### Building on POSIX systems

$ rm -rf build && mkdir build && cd build
$ cmake ..
$ make
$ sudo make install # optional

To adjust the build system configuration, the following options can be provided to `cmake` call:

| Option | Default value | Description |
|--------|:-------------:|-------------|
| BUILD_BENCHMARK | ON | compile benchmark |
| BUILD_TESTS | ON | compile tests |
| BUILD_EXHAUSTIVE_TESTS | ON | compile exhaustive tests |
| BUILD_EXAMPLES | OFF | compile examples |
| ENABLE_MODULE_ECDH | OFF | enable ECDH module |
| ENABLE_MODULE_RECOVERY | OFF | enable ECDSA pubkey recovery module |
| ENABLE_MODULE_EXTRAKEYS | OFF |enable extrakeys module |
| ENABLE_MODULE_SCHNORRSIG | OFF | enable schnorrsig module |

For example:

$ cmake .. -DBUILD_BENCHMARK=OFF -DENABLE_MODULE_ECDH=ON

### Cross compiling

To alleviate cross compiling, preconfigured toolchain files are available in the `toolchain` directory.
For example, to cross compile for Windows:

$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain/x86_64-w64-mingw32.cmake

To compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set):

$ cmake .. -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28

### Building on Windows

To build on Windows with Visual Studio, a proper [generator](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators) must be specified for a new build tree.

The following example assumes using of Visual Studio 2022 and CMake v3.21+.

In "Developer Command Prompt for VS 2022":

>rd /s /q build && mkdir build && cd build
>cmake .. -G "Visual Studio 17 2022" -A x64 -DBUILD_BENCHMARK=OFF
>cmake --build . --target ALL_BUILD --config Release -- /nologo

Usage examples
-----------
Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
Expand Down
55 changes: 55 additions & 0 deletions cmake/libsecp256k1-config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/***********************************************************************
* Copyright (c) 2022 *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/

#ifndef LIBSECP256K1_CONFIG_H

#define LIBSECP256K1_CONFIG_H

/* Define this symbol to enable the ECDH module */
#cmakedefine ENABLE_MODULE_ECDH

/* Define this symbol to enable the ECDSA pubkey recovery module */
#cmakedefine ENABLE_MODULE_RECOVERY

/* Define this symbol to enable the extrakeys module */
#cmakedefine ENABLE_MODULE_EXTRAKEYS

/* Define this symbol to enable the schnorrsig module */
#cmakedefine ENABLE_MODULE_SCHNORRSIG

/* Define this symbol if an external implementation of the default callbacks
is used */
#cmakedefine USE_EXTERNAL_DEFAULT_CALLBACKS

/* Define this symbol to compile out all VERIFY code */
#cmakedefine COVERAGE

/* Set window size for ecmult precomputation */
#cmakedefine ECMULT_WINDOW_SIZE @ECMULT_WINDOW_SIZE@

/* Set ecmult gen precision bits */
#cmakedefine ECMULT_GEN_PREC_BITS @ECMULT_GEN_PREC_BITS@

/* Define this symbol if valgrind is installed, and it supports the host
platform */
#cmakedefine HAVE_VALGRIND

/* Define this symbol to enable x86_64 assembly optimizations */
#cmakedefine USE_ASM_X86_64

/* Define this symbol if an external (non-inline) assembly implementation is
used */
#cmakedefine USE_EXTERNAL_ASM

/* Define this symbol to force the use of the (unsigned) __int128 based wide
multiplication implementation */
#cmakedefine USE_FORCE_WIDEMUL_INT128

/* Define this symbol to force the use of the (u)int64_t based wide
multiplication implementation */
#cmakedefine USE_FORCE_WIDEMUL_INT64

#endif /*LIBSECP256K1_CONFIG_H*/
14 changes: 14 additions & 0 deletions cmake/secp_try_append_cflag.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2022
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php.

include(CheckCCompilerFlag)

function(secp_try_append_cflag dashed_flag)
string(REGEX REPLACE "^(-)" "" flag ${dashed_flag})
check_c_compiler_flag(${dashed_flag} ${flag})
if(${flag})
string(STRIP "${CMAKE_C_FLAGS} ${dashed_flag}" CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} PARENT_SCOPE)
endif()
endfunction()
71 changes: 71 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2022
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php.

add_definitions(-DHAVE_CONFIG_H)
include_directories(${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_BINARY_DIR}/src)

add_library(secp256k1 "")
target_sources(secp256k1
PRIVATE
secp256k1.c
precomputed_ecmult.c
precomputed_ecmult_gen.c
)

if(BUILD_BENCHMARK)
add_executable(bench bench.c)
target_link_libraries(bench PRIVATE secp256k1)
add_executable(bench_internal bench_internal.c)
target_link_libraries(bench_internal PRIVATE secp256k1)
add_executable(bench_ecmult bench_ecmult.c)
target_link_libraries(bench_ecmult PRIVATE secp256k1)
endif()

if(BUILD_TESTS)
add_executable(tests tests.c)
if(NOT COVERAGE)
target_compile_definitions(tests PRIVATE -DVERIFY)
endif()
target_link_libraries(tests PRIVATE secp256k1)
target_link_options(tests
PRIVATE
$<$<NOT:$<PLATFORM_ID:Darwin>>:-static>
)
endif()

if(BUILD_EXHAUSTIVE_TESTS)
add_executable(exhaustive_tests tests_exhaustive.c)
if(NOT COVERAGE)
target_compile_definitions(exhaustive_tests PRIVATE -DVERIFY)
endif()
target_link_libraries(exhaustive_tests PRIVATE secp256k1)
target_link_options(tests
PRIVATE
$<$<NOT:$<PLATFORM_ID:Darwin>>:-static>
)
endif()

include(GNUInstallDirs)
install(
TARGETS secp256k1
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
set(secp_headers "../include/secp256k1.h" "../include/secp256k1_preallocated.h")
if(ENABLE_MODULE_ECDH)
list(APPEND secp_headers "../include/secp256k1_ecdh.h")
endif()
if(ENABLE_MODULE_RECOVERY)
list(APPEND secp_headers "../include/secp256k1_recovery.h")
endif()
if(ENABLE_MODULE_EXTRAKEYS)
list(APPEND secp_headers "../include/secp256k1_extrakeys.h")
endif()
if(ENABLE_MODULE_SCHNORRSIG)
list(APPEND secp_headers "../include/secp256k1_schnorrsig.h")
endif()
install(
FILES ${secp_headers}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
7 changes: 7 additions & 0 deletions toolchain/arm-linux-gnueabihf.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2022
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php.

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
7 changes: 7 additions & 0 deletions toolchain/x86_64-w64-mingw32.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright 2022
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php.

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)

0 comments on commit ff836b6

Please sign in to comment.