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