Files
versioned-map/CMakeLists.txt
Andrew Noyes 42298a911a Prepare to add fdb implementation
Fixes a end iter deref and remove rpath from test
2024-05-28 13:23:06 -07:00

231 lines
8.5 KiB
CMake

cmake_minimum_required(VERSION 3.18)
project(
versioned-map
VERSION 0.0.1
DESCRIPTION
"A data structure for mvcc reads on bitwise-lexicographically-ordered keys."
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/versioned-map"
LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20)
file(WRITE ${CMAKE_BINARY_DIR}/version.txt ${PROJECT_VERSION})
include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
set(DEFAULT_BUILD_TYPE "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
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)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum
-Werror=switch-enum -fvisibility=hidden -fPIC)
set(full_relro_flags "-pie;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()
# This is encouraged according to
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/valgrind)
if(CMAKE_BUILD_TYPE STREQUAL Release)
if(APPLE)
add_link_options(-Wl,-dead_strip)
else()
add_link_options(-Wl,--gc-sections)
endif()
endif()
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
add_subdirectory(third_party)
add_executable(versioned_map_main VersionedMap.cpp RootSet.cpp)
target_include_directories(versioned_map_main
PRIVATE ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(versioned_map_main PRIVATE nanobench)
target_compile_definitions(versioned_map_main PRIVATE ENABLE_MAIN)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_options(versioned_map_main
PRIVATE -fsanitize=address,undefined)
target_link_options(versioned_map_main PRIVATE -fsanitize=address,undefined)
endif()
add_library(${PROJECT_NAME}-object OBJECT VersionedMap.cpp RootSet.cpp)
target_compile_options(${PROJECT_NAME}-object PRIVATE -fno-exceptions -fno-rtti)
target_include_directories(${PROJECT_NAME}-object
PRIVATE ${CMAKE_SOURCE_DIR}/include)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o
COMMAND ld -r $<TARGET_OBJECTS:${PROJECT_NAME}-object> -o
${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o
DEPENDS $<TARGET_OBJECTS:${PROJECT_NAME}-object>
COMMAND_EXPAND_LISTS)
add_library(${PROJECT_NAME} SHARED ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o)
target_include_directories(
${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>)
set_target_properties(
${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/versioned-map")
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
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 ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o)
target_include_directories(
${PROJECT_NAME}-static PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>)
set_target_properties(${PROJECT_NAME}-static PROPERTIES LINKER_LANGUAGE C)
if(NOT APPLE)
add_custom_command(
TARGET ${PROJECT_NAME}-static
POST_BUILD
COMMAND
${CMAKE_OBJCOPY}
--keep-global-symbols=${CMAKE_SOURCE_DIR}/symbol-exports.txt
$<TARGET_FILE:${PROJECT_NAME}-static> || echo
"Proceeding with all symbols global in static library")
endif()
set(TEST_FLAGS -Wall -Wextra -Wunreachable-code -Wpedantic -UNDEBUG)
include(CTest)
option(BUILD_TREE_VIS "Build tree visualization" OFF)
if(BUILD_TREE_VIS)
find_package(SDL2 REQUIRED)
find_package(SDL2_ttf REQUIRED)
add_executable(tree_vis TreeVis.cpp)
target_link_libraries(tree_vis PRIVATE SDL2::SDL2)
target_link_libraries(tree_vis PRIVATE SDL2_ttf::SDL2_ttf)
endif()
if(BUILD_TESTING)
# 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/*)
if(NOT APPLE)
# libfuzzer target, to generate/manage corpus
set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined")
include(CheckCXXCompilerFlag)
cmake_push_check_state()
set(CMAKE_REQUIRED_LINK_OPTIONS -fsanitize=fuzzer-no-link)
check_cxx_compiler_flag(-fsanitize=fuzzer-no-link HAS_LIB_FUZZER)
cmake_pop_check_state()
if(HAS_LIB_FUZZER)
add_executable(facade_fuzz FacadeFuzz.cpp)
target_link_libraries(facade_fuzz PRIVATE ${PROJECT_NAME})
target_compile_options(facade_fuzz PRIVATE ${FUZZ_FLAGS} ${TEST_FLAGS})
target_link_options(facade_fuzz PRIVATE ${FUZZ_FLAGS} -fsanitize=fuzzer)
endif()
endif()
add_executable(rootset_test RootSet.cpp)
target_compile_definitions(rootset_test PRIVATE ENABLE_ROOTSET_TESTS)
target_compile_options(rootset_test PRIVATE -fsanitize=address,undefined
${TEST_FLAGS})
target_link_options(rootset_test PRIVATE -fsanitize=address,undefined)
add_test(NAME rootset_test COMMAND rootset_test)
add_executable(rootset_test_tsan RootSet.cpp)
target_compile_definitions(rootset_test_tsan PRIVATE ENABLE_ROOTSET_TESTS)
target_compile_options(rootset_test_tsan PRIVATE -fsanitize=thread
${TEST_FLAGS})
target_link_options(rootset_test_tsan PRIVATE -fsanitize=thread)
add_test(NAME rootset_test_tsan COMMAND rootset_test)
add_executable(api_test ApiTest.cpp)
target_link_libraries(api_test PRIVATE ${PROJECT_NAME})
target_compile_options(api_test PRIVATE -fsanitize=address,undefined
${TEST_FLAGS})
target_link_options(api_test PRIVATE -fsanitize=address,undefined)
add_test(NAME api_test COMMAND api_test)
add_executable(facade_test FacadeTest.cpp)
target_link_libraries(facade_test PRIVATE ${PROJECT_NAME})
target_compile_options(facade_test PRIVATE -fsanitize=address,undefined
${TEST_FLAGS})
target_link_options(facade_test PRIVATE -fsanitize=address,undefined)
# blackbox tests
add_executable(driver TestDriver.cpp FacadeFuzz.cpp)
target_compile_options(driver PRIVATE ${TEST_FLAGS})
target_link_libraries(driver PRIVATE ${PROJECT_NAME})
set_target_properties(driver PROPERTIES SKIP_BUILD_RPATH ON)
if(APPLE)
set(LD_PATH DYLD_LIBRARY_PATH)
else()
set(LD_PATH LD_LIBRARY_PATH)
endif()
foreach(TEST ${CORPUS_TESTS})
get_filename_component(hash ${TEST} NAME)
add_test(NAME versioned_map_blackbox_${hash} COMMAND driver ${TEST})
set_tests_properties(
versioned_map_blackbox_${hash}
PROPERTIES ENVIRONMENT ${LD_PATH}=${CMAKE_BINARY_DIR}/versioned-map)
endforeach()
add_executable(bench Bench.cpp)
target_link_libraries(bench PRIVATE ${PROJECT_NAME} nanobench)
set_target_properties(bench PROPERTIES SKIP_BUILD_RPATH ON)
# symbol visibility tests
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
if(APPLE)
set(symbol_exports ${CMAKE_SOURCE_DIR}/apple-symbol-exports.txt)
set(symbol_imports ${CMAKE_SOURCE_DIR}/apple-symbol-imports.txt)
else()
set(symbol_exports ${CMAKE_SOURCE_DIR}/symbol-exports.txt)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
set(symbol_imports ${CMAKE_SOURCE_DIR}/aarch64-symbol-imports.txt)
else()
set(symbol_imports ${CMAKE_SOURCE_DIR}/symbol-imports.txt)
endif()
endif()
add_test(
NAME shared_symbols
COMMAND
${CMAKE_SOURCE_DIR}/test_symbols.sh $<TARGET_FILE:${PROJECT_NAME}>
${symbol_exports} ${symbol_imports})
add_test(
NAME static_symbols
COMMAND
${CMAKE_SOURCE_DIR}/test_symbols.sh
$<TARGET_FILE:${PROJECT_NAME}-static> ${symbol_exports}
${symbol_imports})
endif()
endif()