15d3e7166SEd Mastecmake_minimum_required(VERSION 3.0) 2*abd87254SEd Maste 310ff414cSEd Masteproject(libcbor) 45d3e7166SEd Masteset(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/") 510ff414cSEd Masteinclude(CTest) 6*abd87254SEd Masteinclude(GNUInstallDirs) # Provides CMAKE_INSTALL_ variables 710ff414cSEd Maste 810ff414cSEd MasteSET(CBOR_VERSION_MAJOR "0") 9*abd87254SEd MasteSET(CBOR_VERSION_MINOR "11") 10*abd87254SEd MasteSET(CBOR_VERSION_PATCH "0") 1110ff414cSEd MasteSET(CBOR_VERSION ${CBOR_VERSION_MAJOR}.${CBOR_VERSION_MINOR}.${CBOR_VERSION_PATCH}) 1210ff414cSEd Maste 13*abd87254SEd Masteoption(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY "cmake --build --target install does not depend on cmake --build" true) 14*abd87254SEd Masteoption(BUILD_SHARED_LIBS "Build as a shared library" false) 15*abd87254SEd Maste 1610ff414cSEd Masteinclude(CheckIncludeFiles) 1710ff414cSEd Maste 1810ff414cSEd Masteinclude(TestBigEndian) 1910ff414cSEd Mastetest_big_endian(BIG_ENDIAN) 2010ff414cSEd Masteif(BIG_ENDIAN) 2110ff414cSEd Maste add_definitions(-DIS_BIG_ENDIAN) 2210ff414cSEd Masteendif() 2310ff414cSEd Maste 2410ff414cSEd Masteoption(CBOR_CUSTOM_ALLOC "Custom, dynamically defined allocator support" OFF) 255d3e7166SEd Masteif(CBOR_CUSTOM_ALLOC) 265d3e7166SEd Maste message(WARNING 275d3e7166SEd Maste "CBOR_CUSTOM_ALLOC has been deprecated. Custom allocators are now enabled by default." 285d3e7166SEd Maste "The flag is a no-op and will be removed in the next version. " 29*abd87254SEd Maste "Please remove CBOR_CUSTOM_ALLOC from your build configuration.") 305d3e7166SEd Masteendif(CBOR_CUSTOM_ALLOC) 315d3e7166SEd Maste 3210ff414cSEd Masteoption(CBOR_PRETTY_PRINTER "Include a pretty-printing routine" ON) 3310ff414cSEd Masteset(CBOR_BUFFER_GROWTH "2" CACHE STRING "Factor for buffer growth & shrinking") 3410ff414cSEd Masteset(CBOR_MAX_STACK_SIZE "2048" CACHE STRING "maximum size for decoding context stack") 3510ff414cSEd Maste 3610ff414cSEd Masteoption(WITH_TESTS "[TEST] Build unit tests (requires CMocka)" OFF) 3710ff414cSEd Masteif(WITH_TESTS) 3810ff414cSEd Maste add_definitions(-DWITH_TESTS) 3910ff414cSEd Masteendif(WITH_TESTS) 4010ff414cSEd Maste 4110ff414cSEd Masteoption(WITH_EXAMPLES "Build examples" ON) 4210ff414cSEd Maste 4310ff414cSEd Masteoption(HUGE_FUZZ "[TEST] Fuzz through 8GB of data in the test. Do not use with memory instrumentation!" OFF) 4410ff414cSEd Masteif(HUGE_FUZZ) 4510ff414cSEd Maste add_definitions(-DHUGE_FUZZ) 4610ff414cSEd Masteendif(HUGE_FUZZ) 4710ff414cSEd Maste 4810ff414cSEd Masteoption(SANE_MALLOC "[TEST] Assume that malloc will not allocate multi-GB blocks. Tests only, platform specific" OFF) 4910ff414cSEd Masteif(SANE_MALLOC) 5010ff414cSEd Maste add_definitions(-DSANE_MALLOC) 5110ff414cSEd Masteendif(SANE_MALLOC) 5210ff414cSEd Maste 5310ff414cSEd Masteoption(PRINT_FUZZ "[TEST] Print the fuzzer input" OFF) 5410ff414cSEd Masteif(PRINT_FUZZ) 5510ff414cSEd Maste add_definitions(-DPRINT_FUZZ) 5610ff414cSEd Masteendif(PRINT_FUZZ) 5710ff414cSEd Maste 5810ff414cSEd Masteoption(SANITIZE "Enable ASan & a few compatible sanitizers in Debug mode" ON) 5910ff414cSEd Maste 6010ff414cSEd Masteset(CPACK_GENERATOR "DEB" "TGZ" "RPM") 6110ff414cSEd Masteset(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") 6210ff414cSEd Masteset(CPACK_DEBIAN_PACKAGE_MAINTAINER "Pavel Kalvoda") 6310ff414cSEd Masteset(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") 6410ff414cSEd Masteset(CPACK_PACKAGE_VERSION_MAJOR ${CBOR_VERSION_MAJOR}) 6510ff414cSEd Masteset(CPACK_PACKAGE_VERSION_MINOR ${CBOR_VERSION_MINOR}) 6610ff414cSEd Masteset(CPACK_PACKAGE_VERSION_PATCH ${CBOR_VERSION_PATCH}) 6710ff414cSEd Maste 6810ff414cSEd Masteinclude(CPack) 6910ff414cSEd Maste 7010ff414cSEd Masteif(MINGW) 7110ff414cSEd Maste # https://github.com/PJK/libcbor/issues/13 7210ff414cSEd Maste set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") 7310ff414cSEd Masteelseif(NOT MSVC) 7410ff414cSEd Maste set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -pedantic") 7510ff414cSEd Masteendif() 7610ff414cSEd Maste 7710ff414cSEd Masteif(MSVC) 7810ff414cSEd Maste # This just doesn't work right -- https://msdn.microsoft.com/en-us/library/5ft82fed.aspx 7910ff414cSEd Maste set(CBOR_RESTRICT_SPECIFIER "") 8010ff414cSEd Masteelse() 8110ff414cSEd Maste set(CBOR_RESTRICT_SPECIFIER "restrict") 8210ff414cSEd Maste 8310ff414cSEd Maste set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -Wall -g -ggdb -DDEBUG=true") 8410ff414cSEd Maste set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Wall -DNDEBUG") 8510ff414cSEd Maste 8610ff414cSEd Maste if(SANITIZE) 8710ff414cSEd Maste set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} \ 8810ff414cSEd Maste -fsanitize=undefined -fsanitize=address \ 8910ff414cSEd Maste -fsanitize=bounds -fsanitize=alignment") 9010ff414cSEd Maste endif() 9110ff414cSEd Masteendif() 9210ff414cSEd Maste 9310ff414cSEd Masteset(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g") 9410ff414cSEd Maste 9510ff414cSEd Maste 9610ff414cSEd Masteinclude(CheckTypeSize) 9710ff414cSEd Mastecheck_type_size("size_t" SIZEOF_SIZE_T) 9810ff414cSEd Masteif(SIZEOF_SIZE_T LESS 8) 995d3e7166SEd Maste message(WARNING "Your size_t is less than 8 bytes. Decoding of huge items that would exceed the memory address space will always fail. Consider implementing a custom streaming decoder if you need to deal with huge items.") 10010ff414cSEd Masteelse() 10110ff414cSEd Maste add_definitions(-DEIGHT_BYTE_SIZE_T) 10210ff414cSEd Masteendif() 10310ff414cSEd Maste 10410ff414cSEd Masteenable_testing() 10510ff414cSEd Maste 10610ff414cSEd Masteset(CTEST_MEMORYCHECK_COMMAND "/usr/bin/valgrind") 10710ff414cSEd Masteset(MEMORYCHECK_COMMAND_OPTIONS "--tool=memcheck --track-origins=yes --leak-check=full --error-exitcode=1") 10810ff414cSEd Maste 10910ff414cSEd Masteadd_custom_target(coverage 11010ff414cSEd Maste COMMAND ctest 11110ff414cSEd Maste COMMAND lcov --capture --directory . --output-file coverage.info 11210ff414cSEd Maste COMMAND genhtml coverage.info --highlight --legend --output-directory coverage_html 1135d3e7166SEd Maste COMMAND echo "Coverage report ready: ${CMAKE_CURRENT_BINARY_DIR}/coverage_html/index.html") 1145d3e7166SEd Maste 1155d3e7166SEd Masteadd_custom_target(llvm-coverage 1165d3e7166SEd Maste COMMAND make -j 16 1175d3e7166SEd Maste COMMAND rm -rf coverage_profiles 1185d3e7166SEd Maste COMMAND mkdir coverage_profiles 1195d3e7166SEd Maste COMMAND bash -c [[ for TEST in $(ls test/*_test); do LLVM_PROFILE_FILE="coverage_profiles/$(basename -- ${TEST}).profraw" ./${TEST}; done ]] 1205d3e7166SEd Maste # VERBATIM makes escaping working, but breaks shell expansions, so we need to explicitly use bash 1215d3e7166SEd Maste COMMAND bash -c [[ llvm-profdata merge -sparse $(ls coverage_profiles/*.profraw) -o coverage_profiles/combined.profdata ]] 1225d3e7166SEd Maste COMMAND bash -c [[ llvm-cov show -instr-profile=coverage_profiles/combined.profdata test/*_test -format=html > coverage_profiles/report.html ]] 1235d3e7166SEd Maste COMMAND bash -c [[ llvm-cov report -instr-profile=coverage_profiles/combined.profdata test/*_test ]] 1245d3e7166SEd Maste COMMAND echo "Coverage report ready: ${CMAKE_CURRENT_BINARY_DIR}/coverage_profiles/report.html" 1255d3e7166SEd Maste VERBATIM) 1265d3e7166SEd Maste 12710ff414cSEd Masteinclude_directories(src) 12810ff414cSEd Maste 12910ff414cSEd Maste 1305d3e7166SEd Masteoption(c "Enable code coverage instrumentation" OFF) 13110ff414cSEd Masteif (COVERAGE) 13210ff414cSEd Maste message("Configuring code coverage instrumentation") 1335d3e7166SEd Maste if(CMAKE_C_COMPILER_ID MATCHES "GNU") 13410ff414cSEd Maste # https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html 13510ff414cSEd Maste set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fprofile-arcs -ftest-coverage --coverage") 13610ff414cSEd Maste set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage --coverage") 1375d3e7166SEd Maste elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") 1385d3e7166SEd Maste set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-instr-generate -fcoverage-mapping") 1395d3e7166SEd Maste set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate") 1405d3e7166SEd Maste else() 1415d3e7166SEd Maste message(WARNING "Code coverage build not implemented for compiler ${CMAKE_C_COMPILER_ID}") 1425d3e7166SEd Maste endif() 14310ff414cSEd Masteendif (COVERAGE) 14410ff414cSEd Maste 14510ff414cSEd Maste# We want to generate configuration.h from the template and make it so that it is accessible using the same 14610ff414cSEd Maste# path during both library build and installed header use, without littering the source dir. 14710ff414cSEd Masteconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/cbor/configuration.h.in ${PROJECT_BINARY_DIR}/cbor/configuration.h) 148*abd87254SEd Masteinstall(FILES ${PROJECT_BINARY_DIR}/cbor/configuration.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cbor) 14910ff414cSEd Maste# Make the header visible at compile time 15010ff414cSEd Masteinclude_directories(${PROJECT_BINARY_DIR}) 15110ff414cSEd Maste 15210ff414cSEd Maste# CMake >= 3.9.0 enables LTO for GCC and Clang with INTERPROCEDURAL_OPTIMIZATION 15310ff414cSEd Maste# Policy CMP0069 enables this behavior when we set the minimum CMake version < 3.9.0 15410ff414cSEd Maste# Checking for LTO support before setting INTERPROCEDURAL_OPTIMIZATION is mandatory with CMP0069 set to NEW. 15510ff414cSEd Masteset(use_lto FALSE) 15610ff414cSEd Masteif(${CMAKE_VERSION} VERSION_GREATER "3.9.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.9.0") 15710ff414cSEd Maste cmake_policy(SET CMP0069 NEW) 15810ff414cSEd Maste # Require LTO support to build libcbor with newer CMake versions 15910ff414cSEd Maste include(CheckIPOSupported) 16010ff414cSEd Maste check_ipo_supported(RESULT use_lto) 16110ff414cSEd Masteendif(${CMAKE_VERSION} VERSION_GREATER "3.9.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.9.0") 16210ff414cSEd Masteif(use_lto) 16310ff414cSEd Maste message(STATUS "LTO is enabled") 16410ff414cSEd Masteelse() 16510ff414cSEd Maste message(STATUS "LTO is not enabled") 16610ff414cSEd Masteendif(use_lto) 16710ff414cSEd Maste 1685d3e7166SEd Masteadd_subdirectory(src) 16910ff414cSEd Masteif(use_lto) 17010ff414cSEd Maste set_property(DIRECTORY src PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) 17110ff414cSEd Masteendif(use_lto) 17210ff414cSEd Maste 17310ff414cSEd Masteif (WITH_TESTS) 1745d3e7166SEd Maste add_subdirectory(test) 17510ff414cSEd Maste if(use_lto) 17610ff414cSEd Maste set_property(DIRECTORY test PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) 17710ff414cSEd Maste endif(use_lto) 17810ff414cSEd Masteendif (WITH_TESTS) 17910ff414cSEd Maste 18010ff414cSEd Masteif (WITH_EXAMPLES) 1815d3e7166SEd Maste add_subdirectory(examples) 18210ff414cSEd Maste if(use_lto) 18310ff414cSEd Maste set_property(DIRECTORY examples PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) 18410ff414cSEd Maste endif(use_lto) 18510ff414cSEd Masteendif (WITH_EXAMPLES) 186