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 $ -o ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o DEPENDS $ COMMAND_EXPAND_LISTS) add_library(${PROJECT_NAME} SHARED ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o) target_include_directories( ${PROJECT_NAME} PUBLIC $) 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 $) 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 $ || 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) 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) # 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 $ ${symbol_exports} ${symbol_imports}) add_test( NAME static_symbols COMMAND ${CMAKE_SOURCE_DIR}/test_symbols.sh $ ${symbol_exports} ${symbol_imports}) endif() endif()