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