Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: Add unified docs for configuration autotools/CMake/manual builds #1372

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 23 additions & 66 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,65 +156,39 @@ if(SECP256K1_VALGRIND)
endif()

option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." ON)

include(CMakeDependentOption)
cmake_dependent_option(SECP256K1_COVERAGE "Enable coverage analysis support." OFF "NOT MSVC" OFF)
include(TryAppendCFlags)
if(SECP256K1_COVERAGE)
add_compile_definitions(COVERAGE)
try_append_c_flags(-O0 --coverage)
add_link_options(--coverage)
endif()

option(SECP256K1_BUILD_TESTS "Build tests." ON)
option(SECP256K1_BUILD_EXHAUSTIVE_TESTS "Build exhaustive tests." ON)
option(SECP256K1_BUILD_CTIME_TESTS "Build constant-time tests." ${SECP256K1_VALGRIND})

option(SECP256K1_BUILD_EXAMPLES "Build examples." OFF)

include(ProcessConfigurations)
set_default_config(RelWithDebInfo)

# Redefine configuration flags.
# We leave assertions on, because they are only used in the examples, and we want them always on there.
if(MSVC)
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "/DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
else()
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REGEX REPLACE "-DNDEBUG[ \t\r\n]*" "" CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL}")
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
string(REGEX REPLACE "-O3[ \t\r\n]*" "-O2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
endif()

# Define custom "Coverage" build type.
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O0 -DCOVERAGE=1 --coverage" CACHE STRING
"Flags used by the C compiler during \"Coverage\" builds."
FORCE
)
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
"Flags used for linking binaries during \"Coverage\" builds."
FORCE
)
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} --coverage" CACHE STRING
"Flags used by the shared libraries linker during \"Coverage\" builds."
FORCE
)
mark_as_advanced(
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE
)

get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
set(default_build_type "RelWithDebInfo")
if(is_multi_config)
set(CMAKE_CONFIGURATION_TYPES "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage" CACHE STRING
"Supported configuration types."
FORCE
)
remove_flag_from_all_configs(/DNDEBUG)
else()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "${default_build_type}" "Release" "Debug" "MinSizeRel" "Coverage"
)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to \"${default_build_type}\" as none was specified")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING
"Choose the type of build."
FORCE
)
remove_flag_from_all_configs(-DNDEBUG)
if(SECP256K1_COVERAGE)
remove_flag_from_all_configs(-O[s0-9])
else()
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
replace_flag_in_config(Release -O3 -O2)
endif()
endif()

include(TryAppendCFlags)
if(MSVC)
# Keep the following commands ordered lexicographically.
try_append_c_flags(/W3) # Production quality warning level.
Expand Down Expand Up @@ -289,7 +263,7 @@ message("Optional binaries:")
message(" benchmark ........................... ${SECP256K1_BUILD_BENCHMARK}")
message(" noverify_tests ...................... ${SECP256K1_BUILD_TESTS}")
set(tests_status "${SECP256K1_BUILD_TESTS}")
if(CMAKE_BUILD_TYPE STREQUAL "Coverage")
if(SECP256K1_COVERAGE)
set(tests_status OFF)
endif()
message(" tests ............................... ${tests_status}")
Expand All @@ -312,24 +286,7 @@ message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
get_directory_property(compile_options COMPILE_OPTIONS)
string(REPLACE ";" " " compile_options "${compile_options}")
message("Compile options ....................... " ${compile_options})
if(NOT is_multi_config)
message("Build type:")
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
else()
message("Supported configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
message("RelWithDebInfo configuration:")
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
message("Debug configuration:")
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
endif()
print_config_flags()
message("\n")
if(SECP256K1_EXPERIMENTAL)
message(
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Building with Autotools
$ make check # run the test suite
$ sudo make install # optional

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.
To configure the build system, run the `./configure` script with additional [options](/doc/build-options.md).

Building with CMake (experimental)
----------------------------------
Expand All @@ -84,7 +84,7 @@ To maintain a pristine source tree, CMake encourages to perform an out-of-source
$ make check # run the test suite
$ sudo make install # optional

To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake .. -LH` to see the full list of available flags.
To generate a non-default build system, run the `cmake` command with additional [options](/doc/build-options.md).

### Cross compiling

Expand Down
86 changes: 86 additions & 0 deletions cmake/ProcessConfigurations.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
function(get_all_configs output)
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
set(all_configs ${CMAKE_CONFIGURATION_TYPES})
else()
get_property(all_configs CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS)
if(NOT all_configs)
# See https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#default-and-custom-configurations
set(all_configs Debug Release RelWithDebInfo MinSizeRel)
endif()
endif()
set(${output} "${all_configs}" PARENT_SCOPE)
endfunction()

# When used with multi-configuration generators, this function rearranges
# the CMAKE_CONFIGURATION_TYPES list, ensuring that the default configuration type
# appears first while maintaining the order of the remaining configuration types.
function(set_default_config config)
get_all_configs(all_configs)
if(NOT ${config} IN_LIST all_configs)
message(FATAL_ERROR "The default config is \"${config}\", but must be one of ${all_configs}.")
endif()

list(REMOVE_ITEM all_configs ${config})
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15)
list(PREPEND all_configs ${config})
else()
set(all_configs ${config} ${all_configs})
endif()

get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
get_property(help_string CACHE CMAKE_CONFIGURATION_TYPES PROPERTY HELPSTRING)
set(CMAKE_CONFIGURATION_TYPES "${all_configs}" CACHE STRING "${help_string}" FORCE)
else()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "${all_configs}"
)
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Setting build type to \"${config}\" as none was specified")
get_property(help_string CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING)
set(CMAKE_BUILD_TYPE "${config}" CACHE STRING "${help_string}" FORCE)
endif()
endif()
endfunction()

function(remove_flag_from_all_configs flag)
get_all_configs(all_configs)
foreach(config IN LISTS all_configs)
string(TOUPPER "${config}" config_uppercase)
set(flags "${CMAKE_C_FLAGS_${config_uppercase}}")
separate_arguments(flags)
list(FILTER flags EXCLUDE REGEX "${flag}")
list(JOIN flags " " new_flags)
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
endforeach()
endfunction()

function(replace_flag_in_config config old_flag new_flag)
string(TOUPPER "${config}" config_uppercase)
string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_C_FLAGS_${config_uppercase}}")
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
endfunction()

function(print_config_flags)
macro(print_flags config)
string(TOUPPER "${config}" config_uppercase)
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${config_uppercase}}")
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${config_uppercase}}")
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${config_uppercase}}")
endmacro()

get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(is_multi_config)
list(JOIN CMAKE_CONFIGURATION_TYPES " " configs)
message("Supported configuration types ......... ${configs}")
foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
message("'${config}' configuration type:")
print_flags(${config})
endforeach()
else()
message("Build type:")
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
print_flags(${CMAKE_BUILD_TYPE})
endif()
endfunction()
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ AC_ARG_ENABLE(benchmark,
[SECP_SET_DEFAULT([enable_benchmark], [yes], [yes])])

AC_ARG_ENABLE(coverage,
AS_HELP_STRING([--enable-coverage],[enable compiler flags to support kcov coverage analysis [default=no]]), [],
AS_HELP_STRING([--enable-coverage],[enable coverage analysis support [default=no]]), [],
[SECP_SET_DEFAULT([enable_coverage], [no], [no])])

AC_ARG_ENABLE(tests,
Expand Down
Loading