1# 2# Copyright 2017 The Abseil Authors. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# https://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17# https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md 18# As of 2024-07-01, CMake 3.16 is the minimum supported version. 19cmake_minimum_required(VERSION 3.16) 20 21# Allow the user to specify the CMAKE_MSVC_DEBUG_INFORMATION_FORMAT 22if (POLICY CMP0141) 23 cmake_policy(SET CMP0141 NEW) 24endif (POLICY CMP0141) 25 26project(absl LANGUAGES CXX) 27set(ABSL_SOVERSION 0) 28include(CTest) 29 30# Output directory is correct by default for most build setups. However, when 31# building Abseil as a DLL, it is important to have the DLL in the same 32# directory as the executable using it. Thus, we put all executables in a single 33# /bin directory. 34set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 35 36# when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp)) 37# in the source tree of a project that uses it, install rules are disabled. 38if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) 39 option(ABSL_ENABLE_INSTALL "Enable install rule" OFF) 40else() 41 option(ABSL_ENABLE_INSTALL "Enable install rule" ON) 42endif() 43 44set(CMAKE_INSTALL_RPATH "$ORIGIN") 45set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON) 46set(CMAKE_BUILD_RPATH_USE_ORIGIN ON) 47 48option(ABSL_PROPAGATE_CXX_STD 49 "Use CMake C++ standard meta features (e.g. cxx_std_14) that propagate to targets that link to Abseil" 50 ON) 51 52option(ABSL_USE_SYSTEM_INCLUDES 53 "Silence warnings in Abseil headers by marking them as SYSTEM includes" 54 OFF) 55 56list(APPEND CMAKE_MODULE_PATH 57 ${CMAKE_CURRENT_LIST_DIR}/CMake 58 ${CMAKE_CURRENT_LIST_DIR}/absl/copts 59) 60 61option(ABSL_MSVC_STATIC_RUNTIME 62 "Link static runtime libraries" 63 OFF) 64if(ABSL_MSVC_STATIC_RUNTIME) 65 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") 66else() 67 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL") 68endif() 69 70include(CMakePackageConfigHelpers) 71include(GNUInstallDirs) 72include(AbseilDll) 73include(AbseilHelpers) 74 75 76## 77## Using absl targets 78## 79## all public absl targets are 80## exported with the absl:: prefix 81## 82## e.g absl::base absl::synchronization absl::strings .... 83## 84## DO NOT rely on the internal targets outside of the prefix 85 86 87# include current path 88list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) 89 90if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 91 set(ABSL_USING_CLANG ON) 92else() 93 set(ABSL_USING_CLANG OFF) 94endif() 95 96# find dependencies 97## pthread 98find_package(Threads REQUIRED) 99 100include(CMakeDependentOption) 101 102option(ABSL_BUILD_TESTING 103 "If ON, Abseil will build all of Abseil's own tests." OFF) 104 105option(ABSL_BUILD_TEST_HELPERS 106 "If ON, Abseil will build libraries that you can use to write tests against Abseil code. This option requires that Abseil is configured to use GoogleTest." 107 OFF) 108 109option(ABSL_USE_EXTERNAL_GOOGLETEST 110 "If ON, Abseil will assume that the targets for GoogleTest are already provided by the including project. This makes sense when Abseil is used with add_subdirectory." OFF) 111 112cmake_dependent_option(ABSL_FIND_GOOGLETEST 113 "If ON, Abseil will use find_package(GTest) rather than assuming that GoogleTest is already provided by the including project." 114 ON 115 "ABSL_USE_EXTERNAL_GOOGLETEST" 116 OFF) 117 118 119option(ABSL_USE_GOOGLETEST_HEAD 120 "If ON, abseil will download HEAD from GoogleTest at config time." OFF) 121 122set(ABSL_GOOGLETEST_DOWNLOAD_URL "" CACHE STRING "If set, download GoogleTest from this URL") 123 124set(ABSL_LOCAL_GOOGLETEST_DIR "/usr/src/googletest" CACHE PATH 125 "If ABSL_USE_GOOGLETEST_HEAD is OFF and ABSL_GOOGLETEST_URL is not set, specifies the directory of a local GoogleTest checkout." 126 ) 127 128option(ABSL_BUILD_MONOLITHIC_SHARED_LIBS 129 "Build Abseil as a single shared library (always enabled for Windows)" 130 OFF 131) 132if(NOT BUILD_SHARED_LIBS AND ABSL_BUILD_MONOLITHIC_SHARED_LIBS) 133 message(WARNING "Not building a shared library because BUILD_SHARED_LIBS is not set. Ignoring ABSL_BUILD_MONOLITHIC_SHARED_LIBS.") 134endif() 135 136if((BUILD_TESTING AND ABSL_BUILD_TESTING) OR ABSL_BUILD_TEST_HELPERS) 137 if (ABSL_USE_EXTERNAL_GOOGLETEST) 138 if (ABSL_FIND_GOOGLETEST) 139 find_package(GTest REQUIRED) 140 elseif(NOT TARGET GTest::gtest) 141 if(TARGET gtest) 142 # When Google Test is included directly rather than through find_package, the aliases are missing. 143 add_library(GTest::gtest ALIAS gtest) 144 add_library(GTest::gtest_main ALIAS gtest_main) 145 add_library(GTest::gmock ALIAS gmock) 146 add_library(GTest::gmock_main ALIAS gmock_main) 147 else() 148 message(FATAL_ERROR "ABSL_USE_EXTERNAL_GOOGLETEST is ON and ABSL_FIND_GOOGLETEST is OFF, which means that the top-level project must build the Google Test project. However, the target gtest was not found.") 149 endif() 150 endif() 151 else() 152 set(absl_gtest_build_dir ${CMAKE_BINARY_DIR}/googletest-build) 153 if(ABSL_USE_GOOGLETEST_HEAD AND ABSL_GOOGLETEST_DOWNLOAD_URL) 154 message(FATAL_ERROR "Do not set both ABSL_USE_GOOGLETEST_HEAD and ABSL_GOOGLETEST_DOWNLOAD_URL") 155 endif() 156 if(ABSL_USE_GOOGLETEST_HEAD) 157 set(absl_gtest_download_url "https://github.com/google/googletest/archive/main.zip") 158 elseif(ABSL_GOOGLETEST_DOWNLOAD_URL) 159 set(absl_gtest_download_url ${ABSL_GOOGLETEST_DOWNLOAD_URL}) 160 endif() 161 if(absl_gtest_download_url) 162 set(absl_gtest_src_dir ${CMAKE_BINARY_DIR}/googletest-src) 163 else() 164 set(absl_gtest_src_dir ${ABSL_LOCAL_GOOGLETEST_DIR}) 165 endif() 166 include(CMake/Googletest/DownloadGTest.cmake) 167 endif() 168endif() 169 170add_subdirectory(absl) 171 172if(ABSL_ENABLE_INSTALL) 173 # absl:lts-remove-begin(system installation is supported for LTS releases) 174 # We don't support system-wide installation 175 list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}") 176 if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS) 177 message(WARNING "\ 178 The default and system-level install directories are unsupported except in LTS \ 179 releases of Abseil. Please set CMAKE_INSTALL_PREFIX to install Abseil in your \ 180 source or build tree directly.\ 181 ") 182 endif() 183 # absl:lts-remove-end 184 185 # install as a subdirectory only 186 install(EXPORT ${PROJECT_NAME}Targets 187 NAMESPACE absl:: 188 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 189 ) 190 191 configure_package_config_file( 192 CMake/abslConfig.cmake.in 193 "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 194 INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 195 ) 196 install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 197 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 198 ) 199 200 # Abseil only has a version in LTS releases. This mechanism is accomplished 201 # Abseil's internal Copybara (https://github.com/google/copybara) workflows and 202 # isn't visible in the CMake buildsystem itself. 203 if(absl_VERSION) 204 write_basic_package_version_file( 205 "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 206 COMPATIBILITY ExactVersion 207 ) 208 209 install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 210 DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 211 ) 212 endif() # absl_VERSION 213 214 # Install the headers except for "options.h" which is installed separately. 215 install(DIRECTORY absl 216 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} 217 FILES_MATCHING 218 PATTERN "*.inc" 219 PATTERN "*.h" 220 PATTERN "options.h" EXCLUDE 221 PATTERN "copts" EXCLUDE 222 PATTERN "testdata" EXCLUDE 223 ) 224 225 # Rewrite options.h to use the compiled ABI. 226 file(READ "absl/base/options.h" ABSL_INTERNAL_OPTIONS_H_CONTENTS) 227 228 # Handle features that require at least C++20. 229 if (ABSL_INTERNAL_AT_LEAST_CXX20) 230 foreach(FEATURE "ORDERING") 231 string(REPLACE 232 "#define ABSL_OPTION_USE_STD_${FEATURE} 2" 233 "#define ABSL_OPTION_USE_STD_${FEATURE} 1" 234 ABSL_INTERNAL_OPTIONS_H_PINNED 235 "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}") 236 set(ABSL_INTERNAL_OPTIONS_H_CONTENTS "${ABSL_INTERNAL_OPTIONS_H_PINNED}") 237 endforeach() 238 endif() 239 240 # Handle features that require at least C++17. 241 if (ABSL_INTERNAL_AT_LEAST_CXX17) 242 foreach(FEATURE "ANY" "OPTIONAL" "STRING_VIEW" "VARIANT") 243 string(REPLACE 244 "#define ABSL_OPTION_USE_STD_${FEATURE} 2" 245 "#define ABSL_OPTION_USE_STD_${FEATURE} 1" 246 ABSL_INTERNAL_OPTIONS_H_PINNED 247 "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}") 248 set(ABSL_INTERNAL_OPTIONS_H_CONTENTS "${ABSL_INTERNAL_OPTIONS_H_PINNED}") 249 endforeach() 250 endif() 251 252 # Any feature that still has the value of 2 (because it was not handled above) 253 # should be set to 0. 254 string(REGEX REPLACE 255 "#define ABSL_OPTION_USE_STD_([^ ]*) 2" 256 "#define ABSL_OPTION_USE_STD_\\1 0" 257 ABSL_INTERNAL_OPTIONS_H_PINNED 258 "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}") 259 260 # If the file already exists, check if it matches the new contents. 261 # This avoids writing the file if it is already up-to-date when the CMake 262 # generation is triggered and triggering unnecessary rebuilds. 263 set(ABSL_INTERNAL_OPTIONS_H_PINNED_NEEDS_UPDATE TRUE) 264 if (EXISTS "${CMAKE_BINARY_DIR}/options-pinned.h") 265 file(READ "${CMAKE_BINARY_DIR}/options-pinned.h" ABSL_INTERNAL_OPTIONS_PINNED_H_CONTENTS) 266 if ("${ABSL_INTERNAL_OPTIONS_H_PINNED}" STREQUAL "${ABSL_INTERNAL_OPTIONS_PINNED_H_CONTENTS}") 267 set(ABSL_INTERNAL_OPTIONS_H_PINNED_NEEDS_UPDATE FALSE) 268 endif() 269 endif() 270 271 # If the file needs an update, generate it. 272 if (ABSL_INTERNAL_OPTIONS_H_PINNED_NEEDS_UPDATE) 273 file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/options-pinned.h" CONTENT "${ABSL_INTERNAL_OPTIONS_H_PINNED}") 274 endif() 275 276 install(FILES "${CMAKE_BINARY_DIR}/options-pinned.h" 277 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/absl/base 278 RENAME "options.h") 279 280endif() # ABSL_ENABLE_INSTALL 281