281 lines
9.3 KiB
CMake
281 lines
9.3 KiB
CMake
cmake_minimum_required(VERSION 3.5)
|
|
project(
|
|
weaseljson
|
|
VERSION 0.0.1
|
|
DESCRIPTION "A constant memory streaming json parser."
|
|
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/weaseljson"
|
|
LANGUAGES C CXX)
|
|
set(CMAKE_CXX_STANDARD 20)
|
|
|
|
include(CMakePushCheckState)
|
|
include(CheckCXXCompilerFlag)
|
|
include(CheckIncludeFileCXX)
|
|
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(
|
|
-Werror=switch-enum
|
|
-Wswitch-enum
|
|
-Wunused-variable
|
|
-fPIC
|
|
-fdata-sections
|
|
-ffunction-sections
|
|
-fno-jump-tables # https://github.com/llvm/llvm-project/issues/54247
|
|
-fno-omit-frame-pointer
|
|
-g)
|
|
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
add_link_options("-Wno-unused-command-line-argument")
|
|
find_program(LLVM_OBJCOPY llvm-objcopy)
|
|
if(LLVM_OBJCOPY)
|
|
set(CMAKE_OBJCOPY
|
|
${LLVM_OBJCOPY}
|
|
CACHE FILEPATH "path to objcopy binary" FORCE)
|
|
endif()
|
|
endif()
|
|
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
add_compile_options("-Wno-maybe-uninitialized")
|
|
endif()
|
|
|
|
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()
|
|
|
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL
|
|
arm64)
|
|
add_compile_options(-mbranch-protection=standard)
|
|
else()
|
|
add_compile_options(-fcf-protection)
|
|
set(rewrite_endbr_flags "-fuse-ld=mold;LINKER:-z,rewrite-endbr")
|
|
cmake_push_check_state()
|
|
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${rewrite_endbr_flags})
|
|
check_cxx_source_compiles("int main(){}" HAS_REWRITE_ENDBR FAIL_REGEX
|
|
"warning:")
|
|
if(HAS_REWRITE_ENDBR)
|
|
add_link_options(${rewrite_endbr_flags})
|
|
endif()
|
|
cmake_pop_check_state()
|
|
endif()
|
|
|
|
set(version_script_flags
|
|
LINKER:--version-script=${CMAKE_CURRENT_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()
|
|
|
|
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
|
|
add_link_options(LINKER:--gc-sections)
|
|
endif()
|
|
|
|
# This is encouraged according to
|
|
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
|
|
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/valgrind)
|
|
|
|
add_subdirectory(third_party)
|
|
|
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
|
|
|
include(CTest)
|
|
include(doctest)
|
|
|
|
add_library(${PROJECT_NAME}-object OBJECT src/lib.cpp)
|
|
target_compile_options(${PROJECT_NAME}-object PRIVATE -fno-exceptions
|
|
-fvisibility=hidden)
|
|
target_include_directories(${PROJECT_NAME}-object
|
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
|
|
|
if(NOT LD_EXE)
|
|
set(LD_EXE ld)
|
|
endif()
|
|
|
|
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
|
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o
|
|
COMMAND ${LD_EXE} -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)
|
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)
|
|
else()
|
|
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
|
|
endif()
|
|
|
|
if(HAS_VERSION_SCRIPT)
|
|
target_link_options(
|
|
${PROJECT_NAME} PRIVATE
|
|
LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/linker.map)
|
|
endif()
|
|
|
|
add_library(${PROJECT_NAME}-static STATIC ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.o)
|
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
set_target_properties(${PROJECT_NAME}-static PROPERTIES LINKER_LANGUAGE CXX)
|
|
else()
|
|
set_target_properties(${PROJECT_NAME}-static PROPERTIES LINKER_LANGUAGE C)
|
|
endif()
|
|
if(NOT APPLE)
|
|
add_custom_command(
|
|
TARGET ${PROJECT_NAME}-static
|
|
POST_BUILD
|
|
COMMAND
|
|
${CMAKE_OBJCOPY}
|
|
--keep-global-symbols=${CMAKE_CURRENT_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)
|
|
|
|
add_executable(mytest src/test.cpp)
|
|
target_include_directories(mytest PRIVATE include)
|
|
target_link_libraries(mytest PRIVATE ${PROJECT_NAME} doctest nanobench simdjson)
|
|
target_compile_options(mytest PRIVATE ${TEST_FLAGS})
|
|
doctest_discover_tests(mytest WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
|
|
include(CMakePushCheckState)
|
|
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(fuzz src/fuzz.cpp src/lib.cpp)
|
|
target_include_directories(fuzz PRIVATE include)
|
|
target_link_libraries(fuzz PRIVATE simdjson)
|
|
target_compile_options(fuzz PRIVATE -fsanitize=fuzzer ${TEST_FLAGS})
|
|
target_link_options(fuzz PRIVATE -fsanitize=fuzzer)
|
|
endif()
|
|
|
|
add_executable(validate src/validate.cpp)
|
|
target_link_libraries(validate ${PROJECT_NAME}-static)
|
|
target_include_directories(validate PRIVATE include)
|
|
|
|
# symbol visibility tests
|
|
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
if(APPLE)
|
|
set(symbol_exports ${CMAKE_CURRENT_SOURCE_DIR}/apple-symbol-exports.txt)
|
|
set(symbol_imports ${CMAKE_CURRENT_SOURCE_DIR}/apple-symbol-imports.txt)
|
|
else()
|
|
set(symbol_exports ${CMAKE_CURRENT_SOURCE_DIR}/symbol-exports.txt)
|
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
|
|
set(symbol_imports ${CMAKE_CURRENT_SOURCE_DIR}/aarch64-symbol-imports.txt)
|
|
else()
|
|
set(symbol_imports ${CMAKE_CURRENT_SOURCE_DIR}/symbol-imports.txt)
|
|
endif()
|
|
endif()
|
|
add_test(
|
|
NAME conflict_set_shared_symbols
|
|
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test_symbols.sh
|
|
$<TARGET_FILE:${PROJECT_NAME}> ${symbol_exports} ${symbol_imports})
|
|
add_test(
|
|
NAME conflict_set_static_symbols
|
|
COMMAND
|
|
${CMAKE_CURRENT_SOURCE_DIR}/test_symbols.sh
|
|
$<TARGET_FILE:${PROJECT_NAME}-static> ${symbol_exports} ${symbol_imports})
|
|
endif()
|
|
|
|
if(NOT CMAKE_CROSSCOMPILING)
|
|
find_program(HARDENING_CHECK hardening-check)
|
|
if(HARDENING_CHECK)
|
|
add_test(NAME hardening_check
|
|
COMMAND ${HARDENING_CHECK} $<TARGET_FILE:${PROJECT_NAME}>
|
|
--nofortify --nostackprotector)
|
|
endif()
|
|
endif()
|
|
|
|
# packaging
|
|
|
|
set(CPACK_PACKAGE_CONTACT andrew@weaselab.dev)
|
|
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME all)
|
|
|
|
set(CPACK_PACKAGE_VENDOR "Weaselab")
|
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
|
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
|
|
|
# rpm
|
|
set(CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
|
set(CPACK_RPM_SPEC_INSTALL_POST "/bin/true") # avoid stripping
|
|
set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0")
|
|
set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
|
|
|
|
# deb
|
|
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
|
# see *-imports.txt - dependency versions need to be synced with symbol versions
|
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
|
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17)")
|
|
else()
|
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.14)")
|
|
endif()
|
|
|
|
# macos
|
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
|
|
if(APPLE)
|
|
find_program(PANDOC_EXE pandoc)
|
|
if(PANDOC_EXE)
|
|
execute_process(COMMAND ${PANDOC_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/README.md
|
|
-o ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
|
|
set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
|
|
endif()
|
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/LICENSE
|
|
${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt COPYONLY)
|
|
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt)
|
|
endif()
|
|
|
|
include(CPack)
|
|
|
|
include(GNUInstallDirs)
|
|
|
|
target_include_directories(
|
|
${PROJECT_NAME}
|
|
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>)
|
|
|
|
target_include_directories(
|
|
${PROJECT_NAME}-static
|
|
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>)
|
|
|
|
set_target_properties(
|
|
${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION}
|
|
SOVERSION ${PROJECT_VERSION_MAJOR})
|
|
|
|
install(
|
|
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-static
|
|
EXPORT ${PROJECT_NAME}Config
|
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
|
|
install(DIRECTORY include/
|
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
|
|
|
|
install(EXPORT ${PROJECT_NAME}Config
|
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
|
|
|
cpack_add_component(all)
|