1# Copyright 2019 The libgav1 Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15if(LIBGAV1_CMAKE_GAV1_TARGETS_CMAKE_) 16 return() 17endif() # LIBGAV1_CMAKE_GAV1_TARGETS_CMAKE_ 18set(LIBGAV1_CMAKE_GAV1_TARGETS_CMAKE_ 1) 19 20# Resets list variables used to track libgav1 targets. 21macro(libgav1_reset_target_lists) 22 unset(libgav1_targets) 23 unset(libgav1_exe_targets) 24 unset(libgav1_lib_targets) 25 unset(libgav1_objlib_targets) 26 unset(libgav1_sources) 27 unset(libgav1_test_targets) 28endmacro() 29 30# Creates an executable target. The target name is passed as a parameter to the 31# NAME argument, and the sources passed as a parameter to the SOURCES argument: 32# libgav1_add_test(NAME <name> SOURCES <sources> [optional args]) 33# 34# Optional args: 35# cmake-format: off 36# - OUTPUT_NAME: Override output file basename. Target basename defaults to 37# NAME. 38# - TEST: Flag. Presence means treat executable as a test. 39# - DEFINES: List of preprocessor macro definitions. 40# - INCLUDES: list of include directories for the target. 41# - COMPILE_FLAGS: list of compiler flags for the target. 42# - LINK_FLAGS: List of linker flags for the target. 43# - OBJLIB_DEPS: List of CMake object library target dependencies. 44# - LIB_DEPS: List of CMake library dependencies. 45# cmake-format: on 46# 47# Sources passed to this macro are added to $libgav1_test_sources when TEST is 48# specified. Otherwise sources are added to $libgav1_sources. 49# 50# Targets passed to this macro are always added $libgav1_targets. When TEST is 51# specified targets are also added to list $libgav1_test_targets. Otherwise 52# targets are added to $libgav1_exe_targets. 53macro(libgav1_add_executable) 54 unset(exe_TEST) 55 unset(exe_TEST_DEFINES_MAIN) 56 unset(exe_NAME) 57 unset(exe_OUTPUT_NAME) 58 unset(exe_SOURCES) 59 unset(exe_DEFINES) 60 unset(exe_INCLUDES) 61 unset(exe_COMPILE_FLAGS) 62 unset(exe_LINK_FLAGS) 63 unset(exe_OBJLIB_DEPS) 64 unset(exe_LIB_DEPS) 65 set(optional_args TEST) 66 set(single_value_args NAME OUTPUT_NAME) 67 set(multi_value_args SOURCES DEFINES INCLUDES COMPILE_FLAGS LINK_FLAGS 68 OBJLIB_DEPS LIB_DEPS) 69 70 cmake_parse_arguments(exe "${optional_args}" "${single_value_args}" 71 "${multi_value_args}" ${ARGN}) 72 73 if(LIBGAV1_VERBOSE GREATER 1) 74 message("--------- libgav1_add_executable ---------\n" 75 "exe_TEST=${exe_TEST}\n" 76 "exe_TEST_DEFINES_MAIN=${exe_TEST_DEFINES_MAIN}\n" 77 "exe_NAME=${exe_NAME}\n" 78 "exe_OUTPUT_NAME=${exe_OUTPUT_NAME}\n" 79 "exe_SOURCES=${exe_SOURCES}\n" 80 "exe_DEFINES=${exe_DEFINES}\n" 81 "exe_INCLUDES=${exe_INCLUDES}\n" 82 "exe_COMPILE_FLAGS=${exe_COMPILE_FLAGS}\n" 83 "exe_LINK_FLAGS=${exe_LINK_FLAGS}\n" 84 "exe_OBJLIB_DEPS=${exe_OBJLIB_DEPS}\n" 85 "exe_LIB_DEPS=${exe_LIB_DEPS}\n" 86 "------------------------------------------\n") 87 endif() 88 89 if(NOT (exe_NAME AND exe_SOURCES)) 90 message(FATAL_ERROR "libgav1_add_executable: NAME and SOURCES required.") 91 endif() 92 93 list(APPEND libgav1_targets ${exe_NAME}) 94 if(exe_TEST) 95 list(APPEND libgav1_test_targets ${exe_NAME}) 96 list(APPEND libgav1_test_sources ${exe_SOURCES}) 97 else() 98 list(APPEND libgav1_exe_targets ${exe_NAME}) 99 list(APPEND libgav1_sources ${exe_SOURCES}) 100 endif() 101 102 add_executable(${exe_NAME} ${exe_SOURCES}) 103 104 if(exe_OUTPUT_NAME) 105 set_target_properties(${exe_NAME} PROPERTIES OUTPUT_NAME ${exe_OUTPUT_NAME}) 106 endif() 107 108 libgav1_process_intrinsics_sources(TARGET ${exe_NAME} SOURCES ${exe_SOURCES}) 109 110 if(exe_DEFINES) 111 target_compile_definitions(${exe_NAME} PRIVATE ${exe_DEFINES}) 112 endif() 113 114 if(exe_INCLUDES) 115 target_include_directories(${exe_NAME} PRIVATE ${exe_INCLUDES}) 116 endif() 117 118 if(exe_COMPILE_FLAGS OR LIBGAV1_CXX_FLAGS) 119 target_compile_options(${exe_NAME} 120 PRIVATE ${exe_COMPILE_FLAGS} ${LIBGAV1_CXX_FLAGS}) 121 endif() 122 123 if(exe_LINK_FLAGS OR LIBGAV1_EXE_LINKER_FLAGS) 124 set_target_properties(${exe_NAME} 125 PROPERTIES LINK_FLAGS ${exe_LINK_FLAGS} 126 ${LIBGAV1_EXE_LINKER_FLAGS}) 127 endif() 128 129 if(exe_OBJLIB_DEPS) 130 foreach(objlib_dep ${exe_OBJLIB_DEPS}) 131 target_sources(${exe_NAME} PRIVATE $<TARGET_OBJECTS:${objlib_dep}>) 132 endforeach() 133 endif() 134 135 if(CMAKE_THREAD_LIBS_INIT) 136 list(APPEND exe_LIB_DEPS ${CMAKE_THREAD_LIBS_INIT}) 137 endif() 138 139 if(BUILD_SHARED_LIBS AND (MSVC OR WIN32)) 140 target_compile_definitions(${lib_NAME} PRIVATE "LIBGAV1_BUILDING_DLL=0") 141 endif() 142 143 if(exe_LIB_DEPS) 144 unset(exe_static) 145 if("${CMAKE_EXE_LINKER_FLAGS} ${LIBGAV1_EXE_LINKER_FLAGS}" MATCHES "static") 146 set(exe_static ON) 147 endif() 148 149 if(exe_static AND CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") 150 # Third party dependencies can introduce dependencies on system and test 151 # libraries. Since the target created here is an executable, and CMake 152 # does not provide a method of controlling order of link dependencies, 153 # wrap all of the dependencies of this target in start/end group flags to 154 # ensure that dependencies of third party targets can be resolved when 155 # those dependencies happen to be resolved by dependencies of the current 156 # target. 157 list(INSERT exe_LIB_DEPS 0 -Wl,--start-group) 158 list(APPEND exe_LIB_DEPS -Wl,--end-group) 159 endif() 160 target_link_libraries(${exe_NAME} PRIVATE ${exe_LIB_DEPS}) 161 endif() 162endmacro() 163 164# Creates a library target of the specified type. The target name is passed as a 165# parameter to the NAME argument, the type as a parameter to the TYPE argument, 166# and the sources passed as a parameter to the SOURCES argument: 167# libgav1_add_library(NAME <name> TYPE <type> SOURCES <sources> [optional args]) 168# 169# Optional args: 170# cmake-format: off 171# - OUTPUT_NAME: Override output file basename. Target basename defaults to 172# NAME. OUTPUT_NAME is ignored when BUILD_SHARED_LIBS is enabled and CMake 173# is generating a build for which MSVC or WIN32 are true. This is to avoid 174# output basename collisions with DLL import libraries. 175# - TEST: Flag. Presence means treat library as a test. 176# - DEFINES: List of preprocessor macro definitions. 177# - INCLUDES: list of include directories for the target. 178# - COMPILE_FLAGS: list of compiler flags for the target. 179# - LINK_FLAGS: List of linker flags for the target. 180# - OBJLIB_DEPS: List of CMake object library target dependencies. 181# - LIB_DEPS: List of CMake library dependencies. 182# - PUBLIC_INCLUDES: List of include paths to export to dependents. 183# cmake-format: on 184# 185# Sources passed to the macro are added to the lists tracking libgav1 sources: 186# cmake-format: off 187# - When TEST is specified sources are added to $libgav1_test_sources. 188# - Otherwise sources are added to $libgav1_sources. 189# cmake-format: on 190# 191# Targets passed to this macro are added to the lists tracking libgav1 targets: 192# cmake-format: off 193# - Targets are always added to $libgav1_targets. 194# - When the TEST flag is specified, targets are added to 195# $libgav1_test_targets. 196# - When TEST is not specified: 197# - Libraries of type SHARED are added to $libgav1_dylib_targets. 198# - Libraries of type OBJECT are added to $libgav1_objlib_targets. 199# - Libraries of type STATIC are added to $libgav1_lib_targets. 200# cmake-format: on 201macro(libgav1_add_library) 202 unset(lib_TEST) 203 unset(lib_NAME) 204 unset(lib_OUTPUT_NAME) 205 unset(lib_TYPE) 206 unset(lib_SOURCES) 207 unset(lib_DEFINES) 208 unset(lib_INCLUDES) 209 unset(lib_COMPILE_FLAGS) 210 unset(lib_LINK_FLAGS) 211 unset(lib_OBJLIB_DEPS) 212 unset(lib_LIB_DEPS) 213 unset(lib_PUBLIC_INCLUDES) 214 set(optional_args TEST) 215 set(single_value_args NAME OUTPUT_NAME TYPE) 216 set(multi_value_args SOURCES DEFINES INCLUDES COMPILE_FLAGS LINK_FLAGS 217 OBJLIB_DEPS LIB_DEPS PUBLIC_INCLUDES) 218 219 cmake_parse_arguments(lib "${optional_args}" "${single_value_args}" 220 "${multi_value_args}" ${ARGN}) 221 222 if(LIBGAV1_VERBOSE GREATER 1) 223 message("--------- libgav1_add_library ---------\n" 224 "lib_TEST=${lib_TEST}\n" 225 "lib_NAME=${lib_NAME}\n" 226 "lib_OUTPUT_NAME=${lib_OUTPUT_NAME}\n" 227 "lib_TYPE=${lib_TYPE}\n" 228 "lib_SOURCES=${lib_SOURCES}\n" 229 "lib_DEFINES=${lib_DEFINES}\n" 230 "lib_INCLUDES=${lib_INCLUDES}\n" 231 "lib_COMPILE_FLAGS=${lib_COMPILE_FLAGS}\n" 232 "lib_LINK_FLAGS=${lib_LINK_FLAGS}\n" 233 "lib_OBJLIB_DEPS=${lib_OBJLIB_DEPS}\n" 234 "lib_LIB_DEPS=${lib_LIB_DEPS}\n" 235 "lib_PUBLIC_INCLUDES=${lib_PUBLIC_INCLUDES}\n" 236 "---------------------------------------\n") 237 endif() 238 239 if(NOT (lib_NAME AND lib_TYPE AND lib_SOURCES)) 240 message(FATAL_ERROR "libgav1_add_library: NAME, TYPE and SOURCES required.") 241 endif() 242 243 list(APPEND libgav1_targets ${lib_NAME}) 244 if(lib_TEST) 245 list(APPEND libgav1_test_targets ${lib_NAME}) 246 list(APPEND libgav1_test_sources ${lib_SOURCES}) 247 else() 248 list(APPEND libgav1_sources ${lib_SOURCES}) 249 if(lib_TYPE STREQUAL OBJECT) 250 list(APPEND libgav1_objlib_targets ${lib_NAME}) 251 elseif(lib_TYPE STREQUAL SHARED) 252 list(APPEND libgav1_dylib_targets ${lib_NAME}) 253 elseif(lib_TYPE STREQUAL STATIC) 254 list(APPEND libgav1_lib_targets ${lib_NAME}) 255 else() 256 message(WARNING "libgav1_add_library: Unhandled type: ${lib_TYPE}") 257 endif() 258 endif() 259 260 add_library(${lib_NAME} ${lib_TYPE} ${lib_SOURCES}) 261 libgav1_process_intrinsics_sources(TARGET ${lib_NAME} SOURCES ${lib_SOURCES}) 262 263 if(lib_OUTPUT_NAME) 264 if(NOT (BUILD_SHARED_LIBS AND (MSVC OR WIN32))) 265 set_target_properties(${lib_NAME} 266 PROPERTIES OUTPUT_NAME ${lib_OUTPUT_NAME}) 267 endif() 268 endif() 269 270 if(lib_DEFINES) 271 target_compile_definitions(${lib_NAME} PRIVATE ${lib_DEFINES}) 272 endif() 273 274 if(lib_INCLUDES) 275 target_include_directories(${lib_NAME} PRIVATE ${lib_INCLUDES}) 276 endif() 277 278 if(lib_PUBLIC_INCLUDES) 279 target_include_directories(${lib_NAME} PUBLIC ${lib_PUBLIC_INCLUDES}) 280 endif() 281 282 if(lib_COMPILE_FLAGS OR LIBGAV1_CXX_FLAGS) 283 target_compile_options(${lib_NAME} 284 PRIVATE ${lib_COMPILE_FLAGS} ${LIBGAV1_CXX_FLAGS}) 285 endif() 286 287 if(lib_LINK_FLAGS) 288 set_target_properties(${lib_NAME} PROPERTIES LINK_FLAGS ${lib_LINK_FLAGS}) 289 endif() 290 291 if(lib_OBJLIB_DEPS) 292 foreach(objlib_dep ${lib_OBJLIB_DEPS}) 293 target_sources(${lib_NAME} PRIVATE $<TARGET_OBJECTS:${objlib_dep}>) 294 endforeach() 295 endif() 296 297 if(lib_LIB_DEPS) 298 if(lib_TYPE STREQUAL STATIC) 299 set(link_type PUBLIC) 300 else() 301 set(link_type PRIVATE) 302 if(lib_TYPE STREQUAL SHARED AND CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") 303 # The libgav1 shared object uses the static libgav1 as input to turn it 304 # into a shared object. Include everything from the static library in 305 # the shared object. 306 if(APPLE) 307 list(INSERT lib_LIB_DEPS 0 -Wl,-force_load) 308 else() 309 list(INSERT lib_LIB_DEPS 0 -Wl,--whole-archive) 310 list(APPEND lib_LIB_DEPS -Wl,--no-whole-archive) 311 endif() 312 endif() 313 endif() 314 target_link_libraries(${lib_NAME} ${link_type} ${lib_LIB_DEPS}) 315 endif() 316 317 if(NOT MSVC AND lib_NAME MATCHES "^lib") 318 # Non-MSVC generators prepend lib to static lib target file names. Libgav1 319 # already includes lib in its name. Avoid naming output files liblib*. 320 set_target_properties(${lib_NAME} PROPERTIES PREFIX "") 321 endif() 322 323 if(lib_TYPE STREQUAL SHARED AND NOT MSVC) 324 set_target_properties(${lib_NAME} PROPERTIES SOVERSION ${LIBGAV1_SOVERSION}) 325 endif() 326 327 if(BUILD_SHARED_LIBS AND (MSVC OR WIN32)) 328 if(lib_TYPE STREQUAL SHARED) 329 target_compile_definitions(${lib_NAME} PRIVATE "LIBGAV1_BUILDING_DLL=1") 330 else() 331 target_compile_definitions(${lib_NAME} PRIVATE "LIBGAV1_BUILDING_DLL=0") 332 endif() 333 endif() 334 335 # Determine if $lib_NAME is a header only target. 336 set(sources_list ${lib_SOURCES}) 337 list(FILTER sources_list INCLUDE REGEX cc$) 338 if(NOT sources_list) 339 if(NOT XCODE) 340 # This is a header only target. Tell CMake the link language. 341 set_target_properties(${lib_NAME} PROPERTIES LINKER_LANGUAGE CXX) 342 else() 343 # The Xcode generator ignores LINKER_LANGUAGE. Add a dummy cc file. 344 libgav1_create_dummy_source_file(TARGET ${lib_NAME} BASENAME ${lib_NAME}) 345 endif() 346 endif() 347endmacro() 348