xref: /freebsd/contrib/libcbor/CMakeLists.txt (revision abd872540f24cfc7dbd1ea29b6918c7082a22108)
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