xref: /aosp_15_r20/external/google-fruit/CMakeLists.txt (revision a65addddcf69f38db5b288d787b6b7571a57bb8f)
1cmake_minimum_required(VERSION 3.2)
2
3project(Fruit VERSION 3.7.1 LANGUAGES CXX)
4
5set(FRUIT_IS_BEING_BUILT_BY_CONAN FALSE CACHE BOOL "This is set in Conan builds.")
6if("${FRUIT_IS_BEING_BUILT_BY_CONAN}")
7  include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
8  conan_basic_setup()
9endif()
10
11if (POLICY CMP0054)
12    cmake_policy(SET CMP0054 NEW)
13endif()
14
15if ("${CMAKE_CXX_STANDARD}" STREQUAL "")
16    set(CMAKE_CXX_STANDARD 11)
17endif()
18set(CMAKE_CXX_STANDARD_REQUIRED ON)
19
20# CMake on OSX likes to see this set explicitly, otherwise it outputs a warning.
21set(CMAKE_MACOSX_RPATH 1)
22
23if(NOT "${CMAKE_BUILD_TYPE}" MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$")
24  message(FATAL_ERROR "Please re-run CMake, specifying -DCMAKE_BUILD_TYPE=Debug , -DCMAKE_BUILD_TYPE=Release , -DCMAKE_BUILD_TYPE=RelWithDebInfo or -DCMAKE_BUILD_TYPE=MinSizeRel .")
25endif()
26
27get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
28option(FRUIT_ALLOW_MULTI_CONFIG "Allow multi-configuration generator. If this option is OFF, enforces that a single configuration is used." OFF)
29if(FRUIT_ALLOW_MULTI_CONFIG)
30  if(isMultiConfig)
31    message(STATUS "${CMAKE_PROJECT_NAME} supports the CMake multi-configuration generator,"
32                   " but is optimized for the `CMAKE_BUILD_TYPE` specified in the CMake configuration step,"
33                   " and tests will only work in this configuration.")
34  endif()
35else()
36  # For backward compatibility, only `CMAKE_BUILD_TYPE` configurations can be
37  # used with the multi-configuration generator. This makes it look like
38  # single-configuration generator.
39  set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}")
40endif()
41
42option(BUILD_SHARED_LIBS "Build shared library" ON)
43
44set(FRUIT_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX compiler flags." FORCE)
45
46set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_CXX_FLAGS}")
47
48if(NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "^(GNU|Clang|AppleClang|MSVC)$")
49  message(WARNING "Compiler not officially supported: ${CMAKE_CXX_COMPILER_ID}")
50  # Full list of possible values at https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html .
51  # Major compilers not currently supported:
52  # * "Intel": not supported ATM due to compiler bugs:
53  #   - https://software.intel.com/en-us/forums/intel-c-compiler/topic/606048
54  #   - https://software.intel.com/en-us/forums/intel-c-compiler/topic/606049
55endif()
56
57option(FRUIT_ADD_WNO_UNKNOWN_WARNING_OPTION "Add -Wno-unknown-warning-option to the compiler options for GCC, Clang, ICC and AppleClang" ON)
58if (${FRUIT_ADD_WNO_UNKNOWN_WARNING_OPTION})
59  set(FRUIT_NO_UNKNOWN_WARNING_FLAGS -Wno-unknown-warning-option)
60endif()
61
62# Get C++ standard flags.
63set(FRUIT_CXX_STANDARD_FLAGS ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION})
64
65set(FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS})
66set(FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS})
67set(FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS})
68set(FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang -W -Wall -Wno-missing-braces ${FRUIT_NO_UNKNOWN_WARNING_FLAGS})
69
70# TODO: we currently disable the warning C4709 because MSVC emits it even when there is no reason to. Re-enable it when possible.
71# TODO: the warning C4141 is disabled, because MSVC emits it ("'inline': used more than once") when a function/method is marked with both __forceinline and inline.
72# TODO: the warning C4714 is disabled, MSVC emits it when it decides not to inline a __forceinline function/method.
73# The warning C4577 is disabled because we don't need a termination guarantee on exceptions for functions marked with
74# 'noexcept'.
75# The warning C4530 is disabled because it's triggered by MSVC's STL.
76# The warning C5205 is disabled, MSVC emits it for abstract classes in example code with non-virtual destructors, but we never call delete on those (even though std::default_delete<Scaler> is instantiated for those types).
77set(FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC /nologo /FS /W4 /wd4324 /wd4709 /wd4459 /wd4141 /wd4714 /wd4577 /wd4530 /wd5205 /D_SCL_SECURE_NO_WARNINGS)
78
79list(APPEND FRUIT_ADDITIONAL_COMPILE_FLAGS
80  $<$<CXX_COMPILER_ID:GNU>:${FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU}>
81  $<$<CXX_COMPILER_ID:Clang>:${FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang}>
82  $<$<CXX_COMPILER_ID:Intel>:${FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel}>
83  $<$<CXX_COMPILER_ID:AppleClang>:${FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang}>
84  $<$<CXX_COMPILER_ID:MSVC>:${FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC}>)
85
86option(FRUIT_ENABLE_COVERAGE "Enable collection of test coverage. This is meant to be used by Fruit developers. It's only supported when using GCC on Linux." OFF)
87if("${FRUIT_ENABLE_COVERAGE}")
88  # We also disable exceptions because otherwise GCC considers every function/method call that could throw as an
89  # additional branch.
90  set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} -fprofile-arcs -ftest-coverage -fno-exceptions -fno-inline -O0")
91  set(FRUIT_ADDITIONAL_LINKER_FLAGS "${FRUIT_ADDITIONAL_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-exceptions -fno-inline -O0")
92endif()
93
94set(FRUIT_USES_BOOST TRUE CACHE BOOL
95        "Whether to use Boost (specifically, boost::unordered_set and boost::unordered_map).
96        If this is false, Fruit will use std::unordered_set and std::unordered_map instead (however this causes injection to be a bit slower).")
97
98if(${FRUIT_USES_BOOST})
99
100  if(DEFINED BOOST_DIR)
101    message(DEPRECATION "BOOST_DIR is deprecated. Use Boost_INCLUDE_DIR instead.")
102    set(Boost_INCLUDE_DIR "${BOOST_DIR}" CACHE PATH "")
103  endif()
104
105  find_package(Boost)
106  if(NOT Boost_FOUND)
107    message(FATAL_ERROR "Please re-run CMake, specifying the boost library path as Boost_INCLUDE_DIR, e.g. -DBoost_INCLUDE_DIR=C:\\boost\\boost_1_62_0, or specify -DFRUIT_USES_BOOST=False to not use boost.")
108  endif()
109endif()
110
111set(RUN_TESTS_UNDER_VALGRIND FALSE CACHE BOOL "Whether to run Fruit tests under valgrind")
112if ("${RUN_TESTS_UNDER_VALGRIND}")
113  set(RUN_TESTS_UNDER_VALGRIND_FLAG "1")
114endif()
115
116# Unsafe, only for debugging/benchmarking.
117#set(FRUIT_ADDITIONAL_COMPILE_FLAGS "${FRUIT_ADDITIONAL_COMPILE_FLAGS} -DFRUIT_NO_LOOP_CHECK=1")
118
119set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FRUIT_ADDITIONAL_LINKER_FLAGS}")
120set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FRUIT_ADDITIONAL_LINKER_FLAGS}")
121set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FRUIT_ADDITIONAL_LINKER_FLAGS}")
122
123set(FRUIT_CLANG_TIDY_CHECKS
124    bugprone*,-bugprone-reserved-identifier,-bugprone-exception-escape,clang-analyzer*,performance*,google*,-google-readability*,-google-runtime-references,clang-diagnostic-unused-command-line-argument,misc-macro-parentheses,-clang-diagnostic-dtor-name,-performance-avoid-endl,-performance-enum-size)
125
126set(FRUIT_ENABLE_CLANG_TIDY FALSE CACHE BOOL "Whether to run clang-tidy on the Fruit codebase during the build")
127if(${FRUIT_ENABLE_CLANG_TIDY})
128  set(CMAKE_CXX_CLANG_TIDY
129    clang-tidy;
130    -header-filter=fruit;
131    -checks=${FRUIT_CLANG_TIDY_CHECKS};
132    -warnings-as-errors=*;)
133endif()
134
135set(FRUIT_INCLUDE_DIRS
136  "${CMAKE_CURRENT_SOURCE_DIR}/include"
137  "${CMAKE_CURRENT_BINARY_DIR}/include")
138
139# (debug-only) compile switch to get deep template instantiation stacktraces for errors (instead
140# of the user-friendly default that hides Fruit internals).
141#add_definitions(-DFRUIT_DEEP_TEMPLATE_INSTANTIATION_STACKTRACES_FOR_ERRORS=1)
142
143include(GNUInstallDirs)
144
145add_subdirectory(configuration)
146add_subdirectory(src)
147
148if(NOT "${FRUIT_IS_BEING_BUILT_BY_CONAN}")
149  if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
150    # Do not exclude these from "make all" in debug mode, they must build.
151    add_subdirectory(examples)
152    add_subdirectory(tests)
153  else()
154    add_subdirectory(examples EXCLUDE_FROM_ALL)
155    add_subdirectory(tests)
156  endif()
157
158  add_subdirectory(extras EXCLUDE_FROM_ALL)
159endif()
160
161install(DIRECTORY include/fruit/
162  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fruit
163  FILES_MATCHING PATTERN "*.h")
164
165set(CPACK_PACKAGE_NAME "Fruit")
166set(CPACK_PACKAGE_VENDOR "Marco Poletti")
167set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Fruit - Dependency Injection Framework For C++")
168set(CPACK_PACKAGE_INSTALL_DIRECTORY "Fruit")
169