Skip to content

Commit e8d90fe

Browse files
committed
Add CMake File
1 parent 1e6f1f5 commit e8d90fe

File tree

3 files changed

+349
-1
lines changed

3 files changed

+349
-1
lines changed

CMakeLists.txt

+340
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
cmake_minimum_required(VERSION 3.12)
2+
3+
project(libsecp256k1 VERSION 0.1 LANGUAGES C)
4+
set(CMAKE_C_STANDARD 90)
5+
set(CMAKE_C_STANDARD_REQUIRED ON)
6+
7+
if (CMAKE_C_FLAGS STREQUAL "")
8+
set(CMAKE_C_FLAGS "-g")
9+
endif()
10+
11+
if (CMAKE_CROSSCOMPILING)
12+
message(FATAL_ERROR "Currently Cmake makefile doesn't support cross compiling.")
13+
endif()
14+
15+
if (APPLE)
16+
find_program ("brew" brew)
17+
if (NOT brew STREQUAL "")
18+
# These Homebrew packages may be keg-only, meaning that they won't be found
19+
# in expected paths because they may conflict with system files. Ask
20+
# Homebrew where each one is located, then adjust paths accordingly.
21+
execute_process(COMMAND "${brew} --prefix openssl 2>/dev/null" OUTPUT_VARIABLE openssl_prefix)
22+
execute_process(COMMAND "${brew} --prefix gmp 2>/dev/null" OUTPUT_VARIABLE gmp_prefix)
23+
if (NOT openssl_prefix STREQUAL "")
24+
set(ENV{PKG_CONFIG_PATH} "${openssl_prefix}/lib/pkgconfig:$PKG_CONFIG_PATH")
25+
endif()
26+
if (NOT gmp_prefix STREQUAL "")
27+
set(ENV{PKG_CONFIG_PATH} "${gmp_prefix}/lib/pkgconfig:$PKG_CONFIG_PATH")
28+
set(GMP_C_FLAGS "-I${$gmp_prefix}/include")
29+
set(GMP_LIBS "-L${$gmp_prefix}/lib")
30+
endif()
31+
else()
32+
find_program ("port" port)
33+
# if homebrew isn't installed and macports is, add the macports default paths
34+
# as a last resort.
35+
if (NOT port STREQUAL "")
36+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem /opt/local/include")
37+
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -L/opt/local/lib")
38+
endif()
39+
endif()
40+
endif()
41+
42+
include(CheckCCompilerFlag)
43+
44+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W")
45+
set(WARN_C_FLAGS "-std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings")
46+
set(SAVED_C_FLAGS "${CMAKE_C_FLAGS}")
47+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARN_C_FLAGS}")
48+
check_c_compiler_flag(CMAKE_C_FLAGS USE_WARN_CFLAGS)
49+
if (NOT USE_WARN_CFLAGS)
50+
set(CMAKE_C_FLAGS "${SAVED_C_FLAGS}")
51+
endif()
52+
53+
set(SAVED_C_FLAGS "${CMAKE_C_FLAGS}")
54+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
55+
check_c_compiler_flag(CMAKE_C_FLAGS USE_OPAQUE_CFLAGS)
56+
if (NOT USE_OPAQUE_CFLAGS)
57+
set(CMAKE_C_FLAGS "${SAVED_C_FLAGS}")
58+
endif()
59+
60+
option(BENCHMARK "compile benchmark (default is on)" ON)
61+
option(COVERAGE "enable compiler flags to support kcov coverage analysis" OFF)
62+
option(TESTS "compile tests (default is on)" ON)
63+
option(OPENSSL_TESTS "enable OpenSSL tests, if OpenSSL is available (default is auto)" OFF)
64+
option(EXPERIMENTAL "allow experimental configure options (default is off)" OFF)
65+
option(EXHAUSTIVE_TESTS "compile exhaustive tests (default is on)" ON)
66+
option(ENDOMORPHISM "enable endomorphism (default is off)" OFF)
67+
option(ECMULT_STATIC_PRECOMPUTATION "enable precomputed ecmult table for signing (default is on)" ON)
68+
option(MODULE_ECDH "enable ECDH shared secret computation (experimental)" OFF)
69+
option(MODULE_RECOVERY "enable ECDSA pubkey recovery module (default is off)" OFF)
70+
option(JNI "enable libsecp256k1_jni (default is off)" OFF)
71+
72+
option(FIELD_64BIT "enable 64 bit field implementation (default is auto)" OFF)
73+
option(FIELD_32BIT "enable 32 bit field implementation (default is auto)" OFF)
74+
75+
option(BIGNUM_GMP "enable GMP bignum implementation (default is auto)" OFF)
76+
option(BIGNUM_NO "don't use any bignum implementation (default is auto)" OFF)
77+
78+
option(SCALAR_64BIT "enable 64 bit scalar implementation (default is auto)" OFF)
79+
option(SCALAR_32BIT "enable 32 bit scalar implementation (default is auto)" OFF)
80+
81+
option(ASM_x86_64 "enable x86_64 assembly optimization (default is auto)" OFF)
82+
option(ASM_ARM "enable ARM assembly optimization (default is auto)" OFF)
83+
option(ASM_NO "don't use any assembly optimization (default is auto)" OFF)
84+
85+
include(CheckTypeSize)
86+
check_type_size("__int128" INT128)
87+
if (NOT INT128 STREQUAL "")
88+
set(INT128 ON)
89+
else()
90+
set(INT128 OFF)
91+
endif()
92+
93+
include(CheckCSourceCompiles)
94+
check_c_source_compiles("int main() {__builtin_expect(0,0);return 0;}" BUILTIN_EXPECT)
95+
96+
if (COVERAGE)
97+
# Define this symbol to compile out all VERIFY code
98+
add_compile_definitions(COVERAGE=1)
99+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 --coverage")
100+
set(CMAKE_MODULE_LINKER_FLAGS "${LDFLAGS} --coverage")
101+
else()
102+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
103+
endif()
104+
105+
# TODO: cross-compiler compatiblity
106+
if (ECMULT_STATIC_PRECOMPUTATION)
107+
set(PRECOMP ON)
108+
else()
109+
set(PRECOMP OFF)
110+
endif()
111+
112+
if (NOT ASM_NO)
113+
check_c_source_compiles("int main() {__builtin_expect(0,0);return 0;}" BUILTIN_EXPECT)
114+
if (NOT ASM_x86_64)
115+
if (NOT ASM_ARM)
116+
# TODO: this doesn't work
117+
check_c_source_compiles("\
118+
#include <stdint.h> \n\
119+
uint64_t a = 11, tmp; \n\
120+
int main(void) {__asm__ __volatile__(\"movq \\@S|@0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\");return 0;}" 64BIT_ASM_CHECK)
121+
if (64BIT_ASM_CHECK)
122+
set(ASM_x86_64 ON)
123+
else()
124+
set(ASM_NO ON)
125+
endif()
126+
endif()
127+
else()
128+
check_c_source_compiles("\
129+
#include <stdint.h> \n\
130+
uint64_t a = 11, tmp; \n\
131+
int main(void) {__asm__ __volatile__(\"movq \\@S|@0x100000000,%1; mulq %%rsi\" : \"+a\"(a) : \"S\"(tmp) : \"cc\", \"%rdx\");return 0;}" 64BIT_ASM_CHECK)
132+
if (NOT 64BIT_ASM_CHECK)
133+
message(FATAL_ERROR "x86_64 assembly optimization requested but not available.")
134+
endif()
135+
endif()
136+
endif()
137+
138+
if (NOT FIELD_64BIT AND NOT FIELD_32BIT)
139+
if (ASM_x86_64)
140+
set(FIELD_64BIT ON)
141+
else()
142+
if (INT128)
143+
set(FIELD_64BIT ON)
144+
else()
145+
set(FIELD_32BIT ON)
146+
endif()
147+
endif()
148+
else ()
149+
if (FIELD_64BIT)
150+
if (NOT ASM_x86_64)
151+
if (NOT INT128)
152+
message(FATAL_ERROR "64bit field explicitly requested but neither __int128 support or x86_64 assembly available.")
153+
endif()
154+
endif()
155+
else()
156+
set(FIELD_32BIT ON)
157+
endif()
158+
endif()
159+
160+
if (NOT SCALAR_64BIT AND NOT SCALAR_32BIT)
161+
if (INT128)
162+
set(SCALAR_64BIT ON)
163+
else()
164+
set(SCALAR_32BIT ON)
165+
endif()
166+
else()
167+
if (SCALAR_64BIT)
168+
if (NOT INT128)
169+
message(FATAL_ERROR "64bit scalar explicitly requested but __int128 support not available.")
170+
endif()
171+
else()
172+
set(SCALAR_32BIT ON)
173+
endif()
174+
endif()
175+
176+
set(CPPFLAGS_TEMP "${CMAKE_CXX_FLAGS}")
177+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GMP_C_FLAGS}")
178+
set(LIBS "${CMAKE_MODULE_LINKER_FLAGS}")
179+
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${GMP_LIBS}")
180+
# No need to append CMAKE_C_FLAGS to CMAKE_REQUIRED_FLAGS
181+
set(CMAKE_REQUIRED_FLAGS "${GMP_C_FLAGS} ${GMP_LIBS}")
182+
183+
184+
if (NOT BIGNUM_NO AND NOT BIGNUM_GMP)
185+
check_c_source_compiles("\
186+
#include <gmp.h>\
187+
mpz_t integ; int main() {return 0;};\
188+
" BIGNUM_GMP)
189+
if (NOT BIGNUM_GMP)
190+
set(BIGNUM_NO ON)
191+
else()
192+
# Define this symbol if libgmp is installed
193+
add_compile_definitions(HAVE_LIBGMP=1)
194+
endif()
195+
else()
196+
if (BIGNUM_GMP)
197+
check_c_source_compiles("\
198+
#include <gmp.h>\
199+
mpz_t integ; int main() {return 0;} \
200+
" BIGNUM_GMP)
201+
if (NOT BIGNUM_GMP)
202+
message(FATAL_ERROR "gmp bignum explicitly requested but libgmp not available.")
203+
else()
204+
# Define this symbol if libgmp is installed
205+
add_compile_definitions(HAVE_LIBGMP=1)
206+
endif()
207+
else()
208+
set(BIGNUM_NO ON)
209+
endif()
210+
endif()
211+
212+
set(CMAKE_CXX_FLAGS "${CPPFLAGS_TEMP}")
213+
set(CMAKE_MODULE_LINKER_FLAGS "${LIBS}")
214+
set(CMAKE_REQUIRED_FLAGS "")
215+
216+
set(USE_EXTERNAL_ASM OFF)
217+
if (ASM_x86_64)
218+
# Define this symbol to enable x86_64 assembly optimizations
219+
add_compile_definitions(USE_ASM_X86_64=1)
220+
else()
221+
if(ASM_ARM)
222+
set(USE_EXTERNAL_ASM ON)
223+
endif()
224+
# no asm
225+
endif()
226+
227+
if (FIELD_64BIT)
228+
# Define this symbol to use the FIELD_5X52 implementation
229+
add_compile_definitions(USE_FIELD_5X52=1)
230+
else()
231+
# Define this symbol to use the FIELD_10X26 implementation
232+
add_compile_definitions(USE_FIELD_10X26=1)
233+
endif()
234+
235+
if (BIGNUM_GMP)
236+
# Define this symbol if libgmp is installed
237+
add_compile_definitions(HAVE_LIBGMP=1)
238+
# Define this symbol to use the gmp implementation for num
239+
add_compile_definitions(USE_NUM_GMP=1)
240+
# Define this symbol to use the num-based field inverse implementation
241+
add_compile_definitions(USE_FIELD_INV_NUM=1)
242+
# Define this symbol to use the num-based scalar inverse implementation
243+
add_compile_definitions(USE_SCALAR_INV_NUM=1)
244+
else()
245+
# Define this symbol to use no num implementation
246+
add_compile_definitions(USE_NUM_NONE=1)
247+
# Define this symbol to use the native field inverse implementation
248+
add_compile_definitions(USE_FIELD_INV_BUILTIN=1)
249+
# Define this symbol to use the native scalar inverse implementation
250+
add_compile_definitions(USE_SCALAR_INV_BUILTIN=1)
251+
endif()
252+
253+
if (SCALAR_64BIT)
254+
# Define this symbol to use the 4x64 scalar implementation
255+
add_compile_definitions(USE_SCALAR_4X64=1)
256+
else()
257+
# Define this symbol to use the 8x32 scalar implementation
258+
add_compile_definitions(USE_SCALAR_8X32=1)
259+
endif()
260+
261+
if (TESTS)
262+
# TODO: here add OpenSSL tests
263+
if (MINGW)
264+
endif()
265+
else()
266+
if (OPENSSL_TESTS)
267+
message(FATAL_ERROR "OpenSSL tests requested but tests are not enabled.")
268+
endif()
269+
endif()
270+
271+
if (JNI)
272+
# TODO: add jni
273+
endif()
274+
275+
if (BIGNUM_GMP)
276+
set(SECP_LIBS "${SECP_LIBS} ${GMP_LIBS}")
277+
set(SECP_INCLUDES "${SECP_INCLUDES} ${GMP_C_FLAGS}")
278+
endif()
279+
280+
if (ENDOMORPHISM)
281+
# Define this symbol to use endomorphism optimization
282+
add_compile_definitions(USE_ENDOMORPHISM=1)
283+
endif()
284+
285+
if (PRECOMP)
286+
# Define this symbol to use a statically generated ecmult table
287+
add_compile_definitions(USE_ECMULT_STATIC_PRECOMPUTATION=1)
288+
endif()
289+
290+
if (MODULE_ECDH)
291+
# Define this symbol to enable the ECDH module
292+
add_compile_definitions(ENABLE_MODULE_ECDH=1)
293+
endif()
294+
295+
if (MODULE_RECOVERY)
296+
# Define this symbol to enable the ECDSA pubkey recovery module
297+
add_compile_definitions(ENABLE_MODULE_RECOVERY=1)
298+
endif()
299+
300+
if (USE_EXTERNAL_ASM)
301+
# Define this symbol if an external (non-inline) assembly implementation is used
302+
add_compile_definitions(USE_EXTERNAL_ASM=1)
303+
endif()
304+
305+
if (INT128)
306+
add_compile_definitions(HAVE___INT128=1)
307+
endif()
308+
309+
message("Using static precomputation: ${PRECOMP}")
310+
message("Using x86_64 ASM: ${ASM_x86_64}")
311+
message("Using ARM ASM: ${ASM_ARM}")
312+
message("Using external ASM: ${USE_EXTERNAL_ASM}")
313+
message("Using 64 bit field implementation: ${FIELD_64BIT}")
314+
message("Using GMP bignum implementation: ${BIGNUM_GMP}")
315+
message("Using 64 bit scalar implementation: ${SCALAR_64BIT}")
316+
message("Using endomorphism optimizations: ${ENDOMORPHISM}")
317+
message("Building benchmarks: ${BENCHMARK}")
318+
message("Building for coverage analysis: ${COVERAGE}")
319+
message("Building ECDH module: ${MODULE_ECDH}")
320+
message("Building ECDSA pubkey recovery module: ${MODULE_RECOVERY}")
321+
message("Using JNI: ${JNI}")
322+
323+
if (EXPERIMENTAL)
324+
message("******")
325+
message("WARNING: experimental build")
326+
message("Experimental features do not have stable APIs or properties, and may not be safe for production use.")
327+
message("Building ECDH module: ${MODULE_ECDH}.")
328+
message("******")
329+
else()
330+
if (MODULE_ECDH)
331+
message(FATAL_ERROR "ECDH module is experimental. Use -DEXPERIMENTAL to allow.")
332+
endif()
333+
if (ASM_ARM)
334+
message(FATAL_ERROR "ARM assembly optimization is experimental. Use --enable-experimental to allow.")
335+
endif()
336+
endif()
337+
338+
add_subdirectory(src)
339+
340+
# What should be here?

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_expect(0,0);}]])],
162162
if test x"$enable_coverage" = x"yes"; then
163163
AC_DEFINE(COVERAGE, 1, [Define this symbol to compile out all VERIFY code])
164164
CFLAGS="$CFLAGS -O0 --coverage"
165-
LDFLAGS="--coverage"
165+
LDFLAGS="$LDFLAGS --coverage"
166166
else
167167
CFLAGS="$CFLAGS -O3"
168168
fi

src/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include_directories(${PROJECT_SOURCE_DIR})
2+
add_library(libsecp256k1 STATIC secp256k1.c)
3+
if (TESTS)
4+
add_custom_target(test tests.c)
5+
endif()
6+
if (EXHAUSTIVE_TESTS)
7+
add_custom_target(exhaustive_test tests.c)
8+
endif()

0 commit comments

Comments
 (0)