Skip to content

WIP: visibility example for cmake #1695

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

Draft
wants to merge 1 commit 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
7 changes: 2 additions & 5 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
function(add_example name)
set(target_name ${name}_example)
add_executable(${target_name} ${name}.c)
target_include_directories(${target_name} PRIVATE
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(${target_name}
secp256k1
target_link_libraries(${target_name} PRIVATE
libsecp256k1::secp256k1
$<$<PLATFORM_ID:Windows>:bcrypt>
)
set(test_name ${name}_example)
Expand Down
50 changes: 13 additions & 37 deletions include/secp256k1.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,45 +121,21 @@ typedef int (*secp256k1_nonce_function)(
#endif

/* Symbol visibility. */
#if defined(_WIN32)
/* GCC for Windows (e.g., MinGW) accepts the __declspec syntax
* for MSVC compatibility. A __declspec declaration implies (but is not
* exactly equivalent to) __attribute__ ((visibility("default"))), and so we
* actually want __declspec even on GCC, see "Microsoft Windows Function
* Attributes" in the GCC manual and the recommendations in
* https://gcc.gnu.org/wiki/Visibility. */
# if defined(SECP256K1_BUILD)
# if defined(DLL_EXPORT) || defined(SECP256K1_DLL_EXPORT)
/* Building libsecp256k1 as a DLL.
* 1. If using Libtool, it defines DLL_EXPORT automatically.
* 2. In other cases, SECP256K1_DLL_EXPORT must be defined. */
# define SECP256K1_API extern __declspec (dllexport)
# else
/* Building libsecp256k1 as a static library on Windows.
* No declspec is needed, and so we would want the non-Windows-specific
* logic below take care of this case. However, this may result in setting
* __attribute__ ((visibility("default"))), which is supposed to be a noop
* on Windows but may trigger warnings when compiling with -flto due to a
* bug in GCC, see
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116478 . */
# define SECP256K1_API extern
# endif
/* The user must define SECP256K1_STATIC when consuming libsecp256k1 as a static
* library on Windows. */
# elif !defined(SECP256K1_STATIC)
/* Consuming libsecp256k1 as a DLL. */
# define SECP256K1_API extern __declspec (dllimport)
# endif
#if defined(_WIN32) || defined(__CYGWIN__)
# define SECP256K1_EXPORT __declspec(dllexport)
# define SECP256K1_IMPORT __declspec(dllimport)
#else
# define SECP256K1_EXPORT __attribute__((visibility("default")))
# define SECP256K1_IMPORT __attribute__((visibility("default")))
#endif
#ifndef SECP256K1_API
/* All cases not captured by the Windows-specific logic. */
# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
/* Building libsecp256k1 using GCC or compatible. */
# define SECP256K1_API extern __attribute__ ((visibility ("default")))
# else
/* Fall back to standard C's extern. */
# define SECP256K1_API extern
# endif
# if defined(SECP256K1_STATIC)
# define SECP256K1_API extern
# elif defined(SECP256K1_BUILD)
# define SECP256K1_API extern SECP256K1_EXPORT
# else
# define SECP256K1_API extern SECP256K1_IMPORT
# endif
#endif

/* Warning attributes
Expand Down
48 changes: 21 additions & 27 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
add_library(secp256k1)

# Allow projects in the same source tree to use this as if it had been imported.
# The prefix has to match the NAMESPACE in `install(EXPORT)` further down.
add_library(${PROJECT_NAME}::secp256k1 ALIAS secp256k1)

set_property(TARGET secp256k1 PROPERTY PUBLIC_HEADER
${PROJECT_SOURCE_DIR}/include/secp256k1.h
${PROJECT_SOURCE_DIR}/include/secp256k1_preallocated.h
Expand Down Expand Up @@ -54,40 +58,24 @@ add_library(secp256k1_precomputed OBJECT EXCLUDE_FROM_ALL
# from being exported.
target_sources(secp256k1 PRIVATE secp256k1.c $<TARGET_OBJECTS:secp256k1_precomputed>)

# Create a helper lib that parent projects can use to link secp256k1 into a
# static lib.
add_library(secp256k1_objs INTERFACE)
target_sources(secp256k1_objs INTERFACE $<TARGET_OBJECTS:secp256k1> $<TARGET_OBJECTS:secp256k1_precomputed>)

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_sources(secp256k1_objs INTERFACE $<TARGET_OBJECTS:secp256k1_asm_arm>)
target_link_libraries(secp256k1_asm INTERFACE secp256k1_asm_arm)
add_library(secp256k1_asm OBJECT EXCLUDE_FROM_ALL asm/field_10x26_arm.s)
else()
add_library(secp256k1_asm INTERFACE)
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()
# When building a static libary, SECP256K1_STATIC must be defined both for itself and downstream.
# Note that the generator expression is evaluated in the context of the consuming target!
target_compile_definitions(secp256k1 PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:secp256k1,TYPE>,STATIC_LIBRARY>:SECP256K1_STATIC>)
set_target_properties(secp256k1 PROPERTIES C_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON)

# 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)
set_target_properties(secp256k1_precomputed PROPERTIES POSITION_INDEPENDENT_CODE ${use_pic})

# Add the include path for parent projects so that they don't have to manually add it.
target_include_directories(secp256k1 INTERFACE
$<BUILD_INTERFACE:$<$<NOT:$<BOOL:${PROJECT_IS_TOP_LEVEL}>>:${PROJECT_SOURCE_DIR}/include>>
)
set_target_properties(secp256k1_objs PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "$<TARGET_PROPERTY:secp256k1,INTERFACE_INCLUDE_DIRECTORIES>"
)
# Add the include path for projects in the same source tree.
target_include_directories(secp256k1 INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)

# 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.
Expand Down Expand Up @@ -123,18 +111,21 @@ if(SECP256K1_BUILD_BENCHMARK)
add_executable(bench bench.c)
target_link_libraries(bench secp256k1)
add_executable(bench_internal bench_internal.c)
target_compile_definitions(bench_internal PRIVATE $<TARGET_PROPERTY:secp256k1,INTERFACE_COMPILE_DEFINITIONS>)
target_link_libraries(bench_internal secp256k1_precomputed secp256k1_asm)
add_executable(bench_ecmult bench_ecmult.c)
target_compile_definitions(bench_ecmult PRIVATE $<TARGET_PROPERTY:secp256k1,INTERFACE_COMPILE_DEFINITIONS>)
target_link_libraries(bench_ecmult secp256k1_precomputed secp256k1_asm)
endif()

if(SECP256K1_BUILD_TESTS)
add_executable(noverify_tests tests.c)
target_compile_definitions(noverify_tests PRIVATE $<TARGET_PROPERTY:secp256k1,INTERFACE_COMPILE_DEFINITIONS>)
target_link_libraries(noverify_tests secp256k1_precomputed secp256k1_asm)
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_compile_definitions(tests PRIVATE VERIFY $<TARGET_PROPERTY:secp256k1,INTERFACE_COMPILE_DEFINITIONS>)
target_link_libraries(tests secp256k1_precomputed secp256k1_asm)
add_test(NAME secp256k1_tests COMMAND tests)
endif()
Expand All @@ -144,7 +135,10 @@ 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)
target_compile_definitions(exhaustive_tests PRIVATE $<$<NOT:$<CONFIG:Coverage>>:VERIFY>)
target_compile_definitions(exhaustive_tests PRIVATE
$<$<NOT:$<CONFIG:Coverage>>:VERIFY>
$<TARGET_PROPERTY:secp256k1,INTERFACE_COMPILE_DEFINITIONS>
)
add_test(NAME secp256k1_exhaustive_tests COMMAND exhaustive_tests)
endif()

Expand Down
Loading