1cmake_minimum_required(VERSION 3.0) 2project(libcbor) 3set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/") 4include(CTest) 5 6SET(CBOR_VERSION_MAJOR "0") 7SET(CBOR_VERSION_MINOR "10") 8SET(CBOR_VERSION_PATCH "2") 9SET(CBOR_VERSION ${CBOR_VERSION_MAJOR}.${CBOR_VERSION_MINOR}.${CBOR_VERSION_PATCH}) 10 11set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true) 12include(CheckIncludeFiles) 13 14include(TestBigEndian) 15test_big_endian(BIG_ENDIAN) 16if(BIG_ENDIAN) 17 add_definitions(-DIS_BIG_ENDIAN) 18endif() 19 20option(CBOR_CUSTOM_ALLOC "Custom, dynamically defined allocator support" OFF) 21if(CBOR_CUSTOM_ALLOC) 22 message(WARNING 23 "CBOR_CUSTOM_ALLOC has been deprecated. Custom allocators are now enabled by default." 24 "The flag is a no-op and will be removed in the next version. " 25 "Please remove CBOR_CUSTOM_ALLOC from your build configuation.") 26endif(CBOR_CUSTOM_ALLOC) 27 28option(CBOR_PRETTY_PRINTER "Include a pretty-printing routine" ON) 29set(CBOR_BUFFER_GROWTH "2" CACHE STRING "Factor for buffer growth & shrinking") 30set(CBOR_MAX_STACK_SIZE "2048" CACHE STRING "maximum size for decoding context stack") 31 32option(WITH_TESTS "[TEST] Build unit tests (requires CMocka)" OFF) 33if(WITH_TESTS) 34 add_definitions(-DWITH_TESTS) 35endif(WITH_TESTS) 36 37option(WITH_EXAMPLES "Build examples" ON) 38 39option(HUGE_FUZZ "[TEST] Fuzz through 8GB of data in the test. Do not use with memory instrumentation!" OFF) 40if(HUGE_FUZZ) 41 add_definitions(-DHUGE_FUZZ) 42endif(HUGE_FUZZ) 43 44option(SANE_MALLOC "[TEST] Assume that malloc will not allocate multi-GB blocks. Tests only, platform specific" OFF) 45if(SANE_MALLOC) 46 add_definitions(-DSANE_MALLOC) 47endif(SANE_MALLOC) 48 49option(PRINT_FUZZ "[TEST] Print the fuzzer input" OFF) 50if(PRINT_FUZZ) 51 add_definitions(-DPRINT_FUZZ) 52endif(PRINT_FUZZ) 53 54option(SANITIZE "Enable ASan & a few compatible sanitizers in Debug mode" ON) 55 56set(CPACK_GENERATOR "DEB" "TGZ" "RPM") 57set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") 58set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Pavel Kalvoda") 59set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") 60set(CPACK_PACKAGE_VERSION_MAJOR ${CBOR_VERSION_MAJOR}) 61set(CPACK_PACKAGE_VERSION_MINOR ${CBOR_VERSION_MINOR}) 62set(CPACK_PACKAGE_VERSION_PATCH ${CBOR_VERSION_PATCH}) 63 64include(CPack) 65 66if(MINGW) 67 # https://github.com/PJK/libcbor/issues/13 68 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") 69elseif(NOT MSVC) 70 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -pedantic") 71endif() 72 73if(MSVC) 74 # This just doesn't work right -- https://msdn.microsoft.com/en-us/library/5ft82fed.aspx 75 set(CBOR_RESTRICT_SPECIFIER "") 76else() 77 set(CBOR_RESTRICT_SPECIFIER "restrict") 78 79 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -Wall -g -ggdb -DDEBUG=true") 80 set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Wall -DNDEBUG") 81 82 if(SANITIZE) 83 set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} \ 84 -fsanitize=undefined -fsanitize=address \ 85 -fsanitize=bounds -fsanitize=alignment") 86 endif() 87endif() 88 89set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-g") 90 91 92include(CheckTypeSize) 93check_type_size("size_t" SIZEOF_SIZE_T) 94if(SIZEOF_SIZE_T LESS 8) 95 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.") 96else() 97 add_definitions(-DEIGHT_BYTE_SIZE_T) 98endif() 99 100enable_testing() 101 102set(CTEST_MEMORYCHECK_COMMAND "/usr/bin/valgrind") 103set(MEMORYCHECK_COMMAND_OPTIONS "--tool=memcheck --track-origins=yes --leak-check=full --error-exitcode=1") 104 105add_custom_target(coverage 106 COMMAND ctest 107 COMMAND lcov --capture --directory . --output-file coverage.info 108 COMMAND genhtml coverage.info --highlight --legend --output-directory coverage_html 109 COMMAND echo "Coverage report ready: ${CMAKE_CURRENT_BINARY_DIR}/coverage_html/index.html") 110 111add_custom_target(llvm-coverage 112 COMMAND make -j 16 113 COMMAND rm -rf coverage_profiles 114 COMMAND mkdir coverage_profiles 115 COMMAND bash -c [[ for TEST in $(ls test/*_test); do LLVM_PROFILE_FILE="coverage_profiles/$(basename -- ${TEST}).profraw" ./${TEST}; done ]] 116 # VERBATIM makes escaping working, but breaks shell expansions, so we need to explicitly use bash 117 COMMAND bash -c [[ llvm-profdata merge -sparse $(ls coverage_profiles/*.profraw) -o coverage_profiles/combined.profdata ]] 118 COMMAND bash -c [[ llvm-cov show -instr-profile=coverage_profiles/combined.profdata test/*_test -format=html > coverage_profiles/report.html ]] 119 COMMAND bash -c [[ llvm-cov report -instr-profile=coverage_profiles/combined.profdata test/*_test ]] 120 COMMAND echo "Coverage report ready: ${CMAKE_CURRENT_BINARY_DIR}/coverage_profiles/report.html" 121 VERBATIM) 122 123include_directories(src) 124 125 126option(c "Enable code coverage instrumentation" OFF) 127if (COVERAGE) 128 message("Configuring code coverage instrumentation") 129 if(CMAKE_C_COMPILER_ID MATCHES "GNU") 130 # https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html 131 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fprofile-arcs -ftest-coverage --coverage") 132 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -g -fprofile-arcs -ftest-coverage --coverage") 133 elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") 134 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-instr-generate -fcoverage-mapping") 135 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate") 136 else() 137 message(WARNING "Code coverage build not implemented for compiler ${CMAKE_C_COMPILER_ID}") 138 endif() 139endif (COVERAGE) 140 141 142# We want to generate configuration.h from the template and make it so that it is accessible using the same 143# path during both library build and installed header use, without littering the source dir. 144# Using cbor/configuration.h in the build dir works b/c headers will be installed to <prefix>/cbor 145configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/cbor/configuration.h.in ${PROJECT_BINARY_DIR}/cbor/configuration.h) 146install(FILES ${PROJECT_BINARY_DIR}/cbor/configuration.h DESTINATION include/cbor) 147# Make the header visible at compile time 148include_directories(${PROJECT_BINARY_DIR}) 149 150# CMake >= 3.9.0 enables LTO for GCC and Clang with INTERPROCEDURAL_OPTIMIZATION 151# Policy CMP0069 enables this behavior when we set the minimum CMake version < 3.9.0 152# Checking for LTO support before setting INTERPROCEDURAL_OPTIMIZATION is mandatory with CMP0069 set to NEW. 153set(use_lto FALSE) 154if(${CMAKE_VERSION} VERSION_GREATER "3.9.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.9.0") 155 cmake_policy(SET CMP0069 NEW) 156 # Require LTO support to build libcbor with newer CMake versions 157 include(CheckIPOSupported) 158 check_ipo_supported(RESULT use_lto) 159endif(${CMAKE_VERSION} VERSION_GREATER "3.9.0" OR ${CMAKE_VERSION} VERSION_EQUAL "3.9.0") 160if(use_lto) 161 message(STATUS "LTO is enabled") 162else() 163 message(STATUS "LTO is not enabled") 164endif(use_lto) 165 166add_subdirectory(src) 167if(use_lto) 168 set_property(DIRECTORY src PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) 169endif(use_lto) 170 171if (WITH_TESTS) 172 add_subdirectory(test) 173 if(use_lto) 174 set_property(DIRECTORY test PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) 175 endif(use_lto) 176endif (WITH_TESTS) 177 178if (WITH_EXAMPLES) 179 add_subdirectory(examples) 180 if(use_lto) 181 set_property(DIRECTORY examples PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) 182 endif(use_lto) 183endif (WITH_EXAMPLES) 184