258 lines
9.6 KiB
CMake
258 lines
9.6 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)
|
|
|
|
set(SOURCES VersionedMap.cpp RootSet.cpp)
|
|
|
|
add_executable(versioned_map_main ${SOURCES})
|
|
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 ${SOURCES})
|
|
|
|
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}/${PROJECT_NAME}")
|
|
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
|
|
|
|
# Not thread-safe
|
|
add_library(fdb-${PROJECT_NAME} SHARED FdbVersionedMap.cpp)
|
|
target_include_directories(
|
|
fdb-${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>)
|
|
set_target_properties(fdb-${PROJECT_NAME} PROPERTIES OUTPUT_NAME
|
|
${PROJECT_NAME})
|
|
set_target_properties(
|
|
fdb-${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
|
"${CMAKE_BINARY_DIR}/fdb-${PROJECT_NAME}")
|
|
|
|
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 ${SOURCES})
|
|
target_include_directories(facade_fuzz
|
|
PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
|
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)
|
|
add_dependencies(driver fdb-${PROJECT_NAME})
|
|
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 blackbox_${hash} COMMAND driver ${TEST})
|
|
set_tests_properties(
|
|
blackbox_${hash}
|
|
PROPERTIES ENVIRONMENT ${LD_PATH}=${CMAKE_BINARY_DIR}/${PROJECT_NAME})
|
|
add_test(NAME fdb_blackbox_${hash} COMMAND driver ${TEST})
|
|
set_tests_properties(
|
|
fdb_blackbox_${hash}
|
|
PROPERTIES ENVIRONMENT ${LD_PATH}=${CMAKE_BINARY_DIR}/fdb-${PROJECT_NAME})
|
|
endforeach()
|
|
|
|
# whitebox tests
|
|
add_executable(whitebox_driver TestDriver.cpp FacadeFuzz.cpp ${SOURCES})
|
|
target_compile_options(whitebox_driver PRIVATE ${TEST_FLAGS})
|
|
target_include_directories(whitebox_driver
|
|
PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
|
foreach(TEST ${CORPUS_TESTS})
|
|
get_filename_component(hash ${TEST} NAME)
|
|
add_test(NAME whitebox_${hash} COMMAND whitebox_driver ${TEST})
|
|
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()
|