Austin Schuh | 36244a1 | 2019-09-21 17:52:38 -0700 | [diff] [blame^] | 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 | include(CMakeParseArguments) |
| 18 | include(AbseilConfigureCopts) |
| 19 | include(AbseilInstallDirs) |
| 20 | |
| 21 | # The IDE folder for Abseil that will be used if Abseil is included in a CMake |
| 22 | # project that sets |
| 23 | # set_property(GLOBAL PROPERTY USE_FOLDERS ON) |
| 24 | # For example, Visual Studio supports folders. |
| 25 | set(ABSL_IDE_FOLDER Abseil) |
| 26 | |
| 27 | # absl_cc_library() |
| 28 | # |
| 29 | # CMake function to imitate Bazel's cc_library rule. |
| 30 | # |
| 31 | # Parameters: |
| 32 | # NAME: name of target (see Note) |
| 33 | # HDRS: List of public header files for the library |
| 34 | # SRCS: List of source files for the library |
| 35 | # DEPS: List of other libraries to be linked in to the binary targets |
| 36 | # COPTS: List of private compile options |
| 37 | # DEFINES: List of public defines |
| 38 | # LINKOPTS: List of link options |
| 39 | # PUBLIC: Add this so that this library will be exported under absl:: |
| 40 | # Also in IDE, target will appear in Abseil folder while non PUBLIC will be in Abseil/internal. |
| 41 | # TESTONLY: When added, this target will only be built if user passes -DABSL_RUN_TESTS=ON to CMake. |
| 42 | # |
| 43 | # Note: |
| 44 | # By default, absl_cc_library will always create a library named absl_${NAME}, |
| 45 | # and alias target absl::${NAME}. The absl:: form should always be used. |
| 46 | # This is to reduce namespace pollution. |
| 47 | # |
| 48 | # absl_cc_library( |
| 49 | # NAME |
| 50 | # awesome |
| 51 | # HDRS |
| 52 | # "a.h" |
| 53 | # SRCS |
| 54 | # "a.cc" |
| 55 | # ) |
| 56 | # absl_cc_library( |
| 57 | # NAME |
| 58 | # fantastic_lib |
| 59 | # SRCS |
| 60 | # "b.cc" |
| 61 | # DEPS |
| 62 | # absl::awesome # not "awesome" ! |
| 63 | # PUBLIC |
| 64 | # ) |
| 65 | # |
| 66 | # absl_cc_library( |
| 67 | # NAME |
| 68 | # main_lib |
| 69 | # ... |
| 70 | # DEPS |
| 71 | # absl::fantastic_lib |
| 72 | # ) |
| 73 | # |
| 74 | # TODO: Implement "ALWAYSLINK" |
| 75 | function(absl_cc_library) |
| 76 | cmake_parse_arguments(ABSL_CC_LIB |
| 77 | "DISABLE_INSTALL;PUBLIC;TESTONLY" |
| 78 | "NAME" |
| 79 | "HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DEPS" |
| 80 | ${ARGN} |
| 81 | ) |
| 82 | |
| 83 | if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS) |
| 84 | if(ABSL_ENABLE_INSTALL) |
| 85 | set(_NAME "${ABSL_CC_LIB_NAME}") |
| 86 | else() |
| 87 | set(_NAME "absl_${ABSL_CC_LIB_NAME}") |
| 88 | endif() |
| 89 | |
| 90 | # Check if this is a header-only library |
| 91 | # Note that as of February 2019, many popular OS's (for example, Ubuntu |
| 92 | # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't |
| 93 | # use list(FILTER...) |
| 94 | set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}") |
| 95 | foreach(src_file IN LISTS ABSL_CC_SRCS) |
| 96 | if(${src_file} MATCHES ".*\\.(h|inc)") |
| 97 | list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}") |
| 98 | endif() |
| 99 | endforeach() |
| 100 | if("${ABSL_CC_SRCS}" STREQUAL "") |
| 101 | set(ABSL_CC_LIB_IS_INTERFACE 1) |
| 102 | else() |
| 103 | set(ABSL_CC_LIB_IS_INTERFACE 0) |
| 104 | endif() |
| 105 | |
| 106 | if(NOT ABSL_CC_LIB_IS_INTERFACE) |
| 107 | add_library(${_NAME} STATIC "") |
| 108 | target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) |
| 109 | target_include_directories(${_NAME} |
| 110 | PUBLIC |
| 111 | "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>" |
| 112 | $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}> |
| 113 | ) |
| 114 | target_compile_options(${_NAME} |
| 115 | PRIVATE ${ABSL_CC_LIB_COPTS}) |
| 116 | target_link_libraries(${_NAME} |
| 117 | PUBLIC ${ABSL_CC_LIB_DEPS} |
| 118 | PRIVATE |
| 119 | ${ABSL_CC_LIB_LINKOPTS} |
| 120 | ${ABSL_DEFAULT_LINKOPTS} |
| 121 | ) |
| 122 | target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) |
| 123 | |
| 124 | # Add all Abseil targets to a a folder in the IDE for organization. |
| 125 | if(ABSL_CC_LIB_PUBLIC) |
| 126 | set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) |
| 127 | elseif(ABSL_CC_LIB_TESTONLY) |
| 128 | set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) |
| 129 | else() |
| 130 | set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) |
| 131 | endif() |
| 132 | |
| 133 | # INTERFACE libraries can't have the CXX_STANDARD property set |
| 134 | set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) |
| 135 | set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) |
| 136 | |
| 137 | # When being installed, we lose the absl_ prefix. We want to put it back |
| 138 | # to have properly named lib files. This is a no-op when we are not being |
| 139 | # installed. |
| 140 | set_target_properties(${_NAME} PROPERTIES |
| 141 | OUTPUT_NAME "absl_${_NAME}" |
| 142 | ) |
| 143 | else() |
| 144 | # Generating header-only library |
| 145 | add_library(${_NAME} INTERFACE) |
| 146 | target_include_directories(${_NAME} |
| 147 | INTERFACE |
| 148 | "$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>" |
| 149 | $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}> |
| 150 | ) |
| 151 | target_link_libraries(${_NAME} |
| 152 | INTERFACE |
| 153 | ${ABSL_CC_LIB_DEPS} |
| 154 | ${ABSL_CC_LIB_LINKOPTS} |
| 155 | ${ABSL_DEFAULT_LINKOPTS} |
| 156 | ) |
| 157 | target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) |
| 158 | endif() |
| 159 | |
| 160 | # TODO currently we don't install googletest alongside abseil sources, so |
| 161 | # installed abseil can't be tested. |
| 162 | if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL) |
| 163 | install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets |
| 164 | RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} |
| 165 | LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} |
| 166 | ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR} |
| 167 | ) |
| 168 | endif() |
| 169 | |
| 170 | add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) |
| 171 | endif() |
| 172 | endfunction() |
| 173 | |
| 174 | # absl_cc_test() |
| 175 | # |
| 176 | # CMake function to imitate Bazel's cc_test rule. |
| 177 | # |
| 178 | # Parameters: |
| 179 | # NAME: name of target (see Usage below) |
| 180 | # SRCS: List of source files for the binary |
| 181 | # DEPS: List of other libraries to be linked in to the binary targets |
| 182 | # COPTS: List of private compile options |
| 183 | # DEFINES: List of public defines |
| 184 | # LINKOPTS: List of link options |
| 185 | # |
| 186 | # Note: |
| 187 | # By default, absl_cc_test will always create a binary named absl_${NAME}. |
| 188 | # This will also add it to ctest list as absl_${NAME}. |
| 189 | # |
| 190 | # Usage: |
| 191 | # absl_cc_library( |
| 192 | # NAME |
| 193 | # awesome |
| 194 | # HDRS |
| 195 | # "a.h" |
| 196 | # SRCS |
| 197 | # "a.cc" |
| 198 | # PUBLIC |
| 199 | # ) |
| 200 | # |
| 201 | # absl_cc_test( |
| 202 | # NAME |
| 203 | # awesome_test |
| 204 | # SRCS |
| 205 | # "awesome_test.cc" |
| 206 | # DEPS |
| 207 | # absl::awesome |
| 208 | # gmock |
| 209 | # gtest_main |
| 210 | # ) |
| 211 | function(absl_cc_test) |
| 212 | if(NOT ABSL_RUN_TESTS) |
| 213 | return() |
| 214 | endif() |
| 215 | |
| 216 | cmake_parse_arguments(ABSL_CC_TEST |
| 217 | "" |
| 218 | "NAME" |
| 219 | "SRCS;COPTS;DEFINES;LINKOPTS;DEPS" |
| 220 | ${ARGN} |
| 221 | ) |
| 222 | |
| 223 | set(_NAME "absl_${ABSL_CC_TEST_NAME}") |
| 224 | add_executable(${_NAME} "") |
| 225 | target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS}) |
| 226 | target_include_directories(${_NAME} |
| 227 | PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} |
| 228 | PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} |
| 229 | ) |
| 230 | target_compile_definitions(${_NAME} |
| 231 | PUBLIC ${ABSL_CC_TEST_DEFINES} |
| 232 | ) |
| 233 | target_compile_options(${_NAME} |
| 234 | PRIVATE ${ABSL_CC_TEST_COPTS} |
| 235 | ) |
| 236 | target_link_libraries(${_NAME} |
| 237 | PUBLIC ${ABSL_CC_TEST_DEPS} |
| 238 | PRIVATE ${ABSL_CC_TEST_LINKOPTS} |
| 239 | ) |
| 240 | # Add all Abseil targets to a a folder in the IDE for organization. |
| 241 | set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) |
| 242 | |
| 243 | set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) |
| 244 | set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) |
| 245 | |
| 246 | add_test(NAME ${_NAME} COMMAND ${_NAME}) |
| 247 | endfunction() |
| 248 | |
| 249 | |
| 250 | function(check_target my_target) |
| 251 | if(NOT TARGET ${my_target}) |
| 252 | message(FATAL_ERROR " ABSL: compiling absl requires a ${my_target} CMake target in your project, |
| 253 | see CMake/README.md for more details") |
| 254 | endif(NOT TARGET ${my_target}) |
| 255 | endfunction() |