• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 2022-09-06, CMake 3.10 is the minimum supported version.
19cmake_minimum_required(VERSION 3.10)
20
21# Compiler id for Apple Clang is now AppleClang.
22if (POLICY CMP0025)
23  cmake_policy(SET CMP0025 NEW)
24endif (POLICY CMP0025)
25
26# if command can use IN_LIST
27if (POLICY CMP0057)
28  cmake_policy(SET CMP0057 NEW)
29endif (POLICY CMP0057)
30
31# Project version variables are the empty string if version is unspecified
32if (POLICY CMP0048)
33  cmake_policy(SET CMP0048 NEW)
34endif (POLICY CMP0048)
35
36# Honor the GTest_ROOT variable if specified
37if (POLICY CMP0074)
38  cmake_policy(SET CMP0074 NEW)
39endif (POLICY CMP0074)
40
41# option() honor variables
42if (POLICY CMP0077)
43  cmake_policy(SET CMP0077 NEW)
44endif (POLICY CMP0077)
45
46# Allow the user to specify the MSVC runtime
47if (POLICY CMP0091)
48  cmake_policy(SET CMP0091 NEW)
49endif (POLICY CMP0091)
50
51# try_compile() honors the CMAKE_CXX_STANDARD value
52if (POLICY CMP0067)
53  cmake_policy(SET CMP0067 NEW)
54endif (POLICY CMP0067)
55
56# Allow the user to specify the CMAKE_MSVC_DEBUG_INFORMATION_FORMAT
57if (POLICY CMP0141)
58  cmake_policy(SET CMP0141 NEW)
59endif (POLICY CMP0141)
60
61project(absl LANGUAGES CXX)
62set(ABSL_SOVERSION 0)
63include(CTest)
64
65# Output directory is correct by default for most build setups. However, when
66# building Abseil as a DLL, it is important to have the DLL in the same
67# directory as the executable using it. Thus, we put all executables in a single
68# /bin directory.
69set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
70
71# when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp))
72# in the source tree of a project that uses it, install rules are disabled.
73if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
74  option(ABSL_ENABLE_INSTALL "Enable install rule" OFF)
75else()
76  option(ABSL_ENABLE_INSTALL "Enable install rule" ON)
77endif()
78
79option(ABSL_PROPAGATE_CXX_STD
80  "Use CMake C++ standard meta features (e.g. cxx_std_14) that propagate to targets that link to Abseil"
81  OFF)  # TODO: Default to ON for CMake 3.8 and greater.
82if(NOT ABSL_PROPAGATE_CXX_STD)
83  message(WARNING "A future Abseil release will default ABSL_PROPAGATE_CXX_STD to ON for CMake 3.8 and up. We recommend enabling this option to ensure your project still builds correctly.")
84endif()
85
86option(ABSL_USE_SYSTEM_INCLUDES
87  "Silence warnings in Abseil headers by marking them as SYSTEM includes"
88  OFF)
89
90list(APPEND CMAKE_MODULE_PATH
91  ${CMAKE_CURRENT_LIST_DIR}/CMake
92  ${CMAKE_CURRENT_LIST_DIR}/absl/copts
93)
94
95include(CMakePackageConfigHelpers)
96include(GNUInstallDirs)
97include(AbseilDll)
98include(AbseilHelpers)
99
100
101##
102## Using absl targets
103##
104## all public absl targets are
105## exported with the absl:: prefix
106##
107## e.g absl::base absl::synchronization absl::strings ....
108##
109## DO NOT rely on the internal targets outside of the prefix
110
111
112# include current path
113list(APPEND ABSL_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
114
115if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
116  set(ABSL_USING_CLANG ON)
117else()
118  set(ABSL_USING_CLANG OFF)
119endif()
120
121# find dependencies
122## pthread
123find_package(Threads REQUIRED)
124
125include(CMakeDependentOption)
126
127option(ABSL_BUILD_TESTING
128  "If ON, Abseil will build all of Abseil's own tests." OFF)
129
130option(ABSL_BUILD_TEST_HELPERS
131  "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."
132  OFF)
133
134option(ABSL_USE_EXTERNAL_GOOGLETEST
135  "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)
136
137cmake_dependent_option(ABSL_FIND_GOOGLETEST
138  "If ON, Abseil will use find_package(GTest) rather than assuming that GoogleTest is already provided by the including project."
139  ON
140  "ABSL_USE_EXTERNAL_GOOGLETEST"
141  OFF)
142
143
144option(ABSL_USE_GOOGLETEST_HEAD
145  "If ON, abseil will download HEAD from GoogleTest at config time." OFF)
146
147set(ABSL_GOOGLETEST_DOWNLOAD_URL "" CACHE STRING "If set, download GoogleTest from this URL")
148
149set(ABSL_LOCAL_GOOGLETEST_DIR "/usr/src/googletest" CACHE PATH
150  "If ABSL_USE_GOOGLETEST_HEAD is OFF and ABSL_GOOGLETEST_URL is not set, specifies the directory of a local GoogleTest checkout."
151  )
152
153option(ABSL_BUILD_MONOLITHIC_SHARED_LIBS
154  "Build Abseil as a single shared library (always enabled for Windows)"
155  OFF
156)
157if(NOT BUILD_SHARED_LIBS AND ABSL_BUILD_MONOLITHIC_SHARED_LIBS)
158  message(WARNING "Not building a shared library because BUILD_SHARED_LIBS is not set. Ignoring ABSL_BUILD_MONOLITHIC_SHARED_LIBS.")
159endif()
160
161if((BUILD_TESTING AND ABSL_BUILD_TESTING) OR ABSL_BUILD_TEST_HELPERS)
162  if (ABSL_USE_EXTERNAL_GOOGLETEST)
163    if (ABSL_FIND_GOOGLETEST)
164      find_package(GTest REQUIRED)
165    elseif(NOT TARGET GTest::gtest)
166      if(TARGET gtest)
167        # When Google Test is included directly rather than through find_package, the aliases are missing.
168        add_library(GTest::gtest ALIAS gtest)
169        add_library(GTest::gtest_main ALIAS gtest_main)
170        add_library(GTest::gmock ALIAS gmock)
171        add_library(GTest::gmock_main ALIAS gmock_main)
172      else()
173        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.")
174      endif()
175    endif()
176  else()
177    set(absl_gtest_build_dir ${CMAKE_BINARY_DIR}/googletest-build)
178    if(ABSL_USE_GOOGLETEST_HEAD AND ABSL_GOOGLETEST_DOWNLOAD_URL)
179      message(FATAL_ERROR "Do not set both ABSL_USE_GOOGLETEST_HEAD and ABSL_GOOGLETEST_DOWNLOAD_URL")
180    endif()
181    if(ABSL_USE_GOOGLETEST_HEAD)
182      set(absl_gtest_download_url "https://github.com/google/googletest/archive/main.zip")
183    elseif(ABSL_GOOGLETEST_DOWNLOAD_URL)
184      set(absl_gtest_download_url ${ABSL_GOOGLETEST_DOWNLOAD_URL})
185    endif()
186    if(absl_gtest_download_url)
187      set(absl_gtest_src_dir ${CMAKE_BINARY_DIR}/googletest-src)
188    else()
189      set(absl_gtest_src_dir ${ABSL_LOCAL_GOOGLETEST_DIR})
190    endif()
191    include(CMake/Googletest/DownloadGTest.cmake)
192  endif()
193endif()
194
195add_subdirectory(absl)
196
197if(ABSL_ENABLE_INSTALL)
198  # absl:lts-remove-begin(system installation is supported for LTS releases)
199  # We don't support system-wide installation
200  list(APPEND SYSTEM_INSTALL_DIRS "/usr/local" "/usr" "/opt/" "/opt/local" "c:/Program Files/${PROJECT_NAME}")
201  if(NOT DEFINED CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX IN_LIST SYSTEM_INSTALL_DIRS)
202    message(WARNING "\
203  The default and system-level install directories are unsupported except in LTS \
204  releases of Abseil.  Please set CMAKE_INSTALL_PREFIX to install Abseil in your \
205  source or build tree directly.\
206    ")
207  endif()
208  # absl:lts-remove-end
209
210  # install as a subdirectory only
211  install(EXPORT ${PROJECT_NAME}Targets
212    NAMESPACE absl::
213    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
214  )
215
216  configure_package_config_file(
217    CMake/abslConfig.cmake.in
218    "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
219    INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
220  )
221  install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
222    DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
223  )
224
225  # Abseil only has a version in LTS releases.  This mechanism is accomplished
226  # Abseil's internal Copybara (https://github.com/google/copybara) workflows and
227  # isn't visible in the CMake buildsystem itself.
228  if(absl_VERSION)
229    write_basic_package_version_file(
230      "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
231      COMPATIBILITY ExactVersion
232    )
233
234    install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
235      DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
236    )
237  endif()  # absl_VERSION
238
239  install(DIRECTORY absl
240    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
241    FILES_MATCHING
242      PATTERN "*.inc"
243      PATTERN "*.h"
244      PATTERN "copts" EXCLUDE
245      PATTERN "testdata" EXCLUDE
246    )
247
248  # Rewrite options.h to use the compiled ABI.
249  file(READ "absl/base/options.h" ABSL_INTERNAL_OPTIONS_H_CONTENTS)
250
251  # Handle features that require at least C++20.
252  if (ABSL_INTERNAL_AT_LEAST_CXX20)
253    foreach(FEATURE "ORDERING")
254      string(REPLACE
255      "#define ABSL_OPTION_USE_STD_${FEATURE} 2"
256      "#define ABSL_OPTION_USE_STD_${FEATURE} 1"
257      ABSL_INTERNAL_OPTIONS_H_PINNED
258      "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}")
259      set(ABSL_INTERNAL_OPTIONS_H_CONTENTS "${ABSL_INTERNAL_OPTIONS_H_PINNED}")
260    endforeach()
261  endif()
262
263  # Handle features that require at least C++17.
264  if (ABSL_INTERNAL_AT_LEAST_CXX17)
265    foreach(FEATURE "ANY" "OPTIONAL" "STRING_VIEW" "VARIANT")
266      string(REPLACE
267      "#define ABSL_OPTION_USE_STD_${FEATURE} 2"
268      "#define ABSL_OPTION_USE_STD_${FEATURE} 1"
269      ABSL_INTERNAL_OPTIONS_H_PINNED
270      "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}")
271      set(ABSL_INTERNAL_OPTIONS_H_CONTENTS "${ABSL_INTERNAL_OPTIONS_H_PINNED}")
272    endforeach()
273  endif()
274
275  # Any feature that still has the value of 2 (because it was not handled above)
276  # should be set to 0.
277  string(REGEX REPLACE
278    "#define ABSL_OPTION_USE_STD_([^ ]*) 2"
279    "#define ABSL_OPTION_USE_STD_\\1 0"
280    ABSL_INTERNAL_OPTIONS_H_PINNED
281    "${ABSL_INTERNAL_OPTIONS_H_CONTENTS}")
282
283  file(WRITE "${CMAKE_BINARY_DIR}/options-pinned.h" "${ABSL_INTERNAL_OPTIONS_H_PINNED}")
284
285  install(FILES "${CMAKE_BINARY_DIR}/options-pinned.h"
286         DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/absl/base
287         RENAME "options.h")
288
289endif()  # ABSL_ENABLE_INSTALL
290