diff --git a/CMakeLists.txt b/CMakeLists.txt index f3906a6..e9cb7de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,19 @@ project( LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 20) +include(CMakePushCheckState) +include(CheckCXXCompilerFlag) +include(CheckIncludeFileCXX) +include(CheckCXXSourceCompiles) + set(DEFAULT_BUILD_TYPE "Release") +if(EMSCRIPTEN OR CMAKE_SYSTEM_NAME STREQUAL WASI) + set(WASM ON) +else() + set(WASM OFF) +endif() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message( STATUS @@ -23,7 +34,24 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum - -Werror=switch-enum) + -Werror=switch-enum -fPIC) +add_link_options(-pie) + +set(full_relro_flags "LINKER:-z,relro,-z,now,-z,noexecstack") +cmake_push_check_state() +list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${full_relro_flags}) +check_cxx_source_compiles("int main(){}" HAS_FULL_RELRO FAIL_REGEX "warning:") +if(HAS_FULL_RELRO) + add_link_options(${full_relro_flags}) +endif() +cmake_pop_check_state() + +set(version_script_flags LINKER:--version-script=${CMAKE_SOURCE_DIR}/linker.map) +cmake_push_check_state() +list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${version_script_flags}) +check_cxx_source_compiles("int main(){}" HAS_VERSION_SCRIPT FAIL_REGEX + "warning:") +cmake_pop_check_state() option(USE_SIMD_FALLBACK "Use fallback implementations of functions that use SIMD" OFF) @@ -46,12 +74,10 @@ if(EMSCRIPTEN) add_link_options(-s ALLOW_MEMORY_GROWTH) endif() -include(CheckIncludeFileCXX) -include(CMakePushCheckState) - if(NOT USE_SIMD_FALLBACK) - if(EMSCRIPTEN) - # https://emscripten.org/docs/porting/simd.html#using-simd-with-webassembly + check_include_file_cxx("wasm_simd128.h" HAS_WASM_SIMD) + if(HAS_WASM_SIMD) + add_compile_definitions(HAS_WASM_SIMD) add_compile_options(-msimd128) endif() @@ -73,7 +99,7 @@ endif() set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") add_library(${PROJECT_NAME}_object OBJECT ConflictSet.cpp) -target_compile_options(${PROJECT_NAME}_object PRIVATE -fPIC -fno-exceptions +target_compile_options(${PROJECT_NAME}_object PRIVATE -fno-exceptions -fvisibility=hidden) target_include_directories(${PROJECT_NAME}_object PRIVATE ${CMAKE_SOURCE_DIR}/include) @@ -86,11 +112,9 @@ if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) endif() -if(NOT APPLE) - target_link_options( - ${PROJECT_NAME} PRIVATE - LINKER:--version-script=${CMAKE_SOURCE_DIR}/linker.map - LINKER:-z,relro,-z,now,-z,noexecstack) +if(HAS_VERSION_SCRIPT) + target_link_options(${PROJECT_NAME} PRIVATE + LINKER:--version-script=${CMAKE_SOURCE_DIR}/linker.map) endif() add_library(${PROJECT_NAME}-static STATIC @@ -99,15 +123,14 @@ if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) set_target_properties(${PROJECT_NAME}-static PROPERTIES LINKER_LANGUAGE C) endif() -if(NOT EMSCRIPTEN - AND NOT APPLE - AND CMAKE_OBJCOPY) +if(CMAKE_OBJCOPY) add_custom_command( TARGET conflict-set-static POST_BUILD COMMAND ${CMAKE_OBJCOPY} --keep-global-symbols=${CMAKE_SOURCE_DIR}/symbols.txt - $) + $ || echo + "Proceeding with all symbols global in static library") endif() set(TEST_FLAGS -Wall -Wextra -Wunreachable-code -Wpedantic -UNDEBUG) @@ -116,16 +139,17 @@ include(CTest) if(BUILD_TESTING) - # corpus tests, which are test + # corpus tests, which are tests curated by libfuzzer. The goal is to get broad + # coverage with a small number of tests. file(GLOB CORPUS_TESTS ${CMAKE_SOURCE_DIR}/corpus/*) # extra testing that relies on shared libraries, which aren't available with - # emscripten - if(NOT EMSCRIPTEN) + # wasm + if(NOT WASM) # Shared library version of FoundationDB's skip list implementation add_library(skip_list SHARED SkipList.cpp) - target_compile_options(skip_list PRIVATE -fPIC -fno-exceptions + target_compile_options(skip_list PRIVATE -fno-exceptions -fvisibility=hidden) target_include_directories(skip_list PUBLIC ${CMAKE_SOURCE_DIR}/include) set_target_properties(skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY @@ -138,7 +162,7 @@ if(BUILD_TESTING) # Shared library version of a std::unordered_map-based conflict set (point # queries only) add_library(hash_table SHARED HashTable.cpp) - target_compile_options(hash_table PRIVATE -fPIC -fno-exceptions + target_compile_options(hash_table PRIVATE -fno-exceptions -fvisibility=hidden) target_include_directories(hash_table PUBLIC ${CMAKE_SOURCE_DIR}/include) set_target_properties( @@ -186,7 +210,7 @@ if(BUILD_TESTING) endif() endif() - # fuzz/whitebox tests + # whitebox tests add_executable(fuzz_driver ConflictSet.cpp FuzzTestDriver.cpp) target_compile_options(fuzz_driver PRIVATE ${TEST_FLAGS}) if(NOT CMAKE_CROSSCOMPILING) @@ -224,10 +248,11 @@ if(BUILD_TESTING) add_test(NAME conflict_set_blackbox_${hash} COMMAND driver ${TEST}) endforeach() + # scripted tests. Written manually to fill in anything libfuzzer couldn't + # find. add_executable(script_test ScriptTest.cpp) target_compile_options(script_test PRIVATE ${TEST_FLAGS}) target_link_libraries(script_test PRIVATE ${PROJECT_NAME}) - file(GLOB SCRIPT_TESTS ${CMAKE_SOURCE_DIR}/script_tests/*) foreach(TEST ${SCRIPT_TESTS}) get_filename_component(name ${TEST} NAME) @@ -261,7 +286,8 @@ if(BUILD_TESTING) PROPERTIES CXX_STANDARD_REQUIRED ON) add_test(NAME conflict_set_cxx_api_test COMMAND conflict_set_cxx_api_test) - if(NOT EMSCRIPTEN + # symbol visibility tests + if(NOT WASM AND NOT APPLE AND NOT CMAKE_BUILD_TYPE STREQUAL Debug) add_test( @@ -276,15 +302,14 @@ if(BUILD_TESTING) endif() # bench - add_executable(conflict_set_bench Bench.cpp) target_link_libraries(conflict_set_bench PRIVATE ${PROJECT_NAME}) set_target_properties(conflict_set_bench PROPERTIES SKIP_BUILD_RPATH ON) - add_executable(real_data_bench RealDataBench.cpp) target_link_libraries(real_data_bench PRIVATE ${PROJECT_NAME}) set_target_properties(real_data_bench PROPERTIES SKIP_BUILD_RPATH ON) endif() + # packaging set(CPACK_PACKAGE_CONTACT andrew@weaselab.dev)