1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
function(avif_collect_deps target out_deps)
get_target_property(current_deps ${target} INTERFACE_LINK_LIBRARIES)
if(NOT current_deps)
set(current_deps "") # if no dependencies, replace "current_deps-NOTFOUND" with empty list
endif()
# Remove entries between ::@(directory-id) and ::@
# Such entries are added by target_link_libraries() calls outside the target's directory
set(filtered_deps "")
set(in_special_block FALSE)
foreach(dep IN LISTS current_deps)
if("${dep}" MATCHES "^::@\\(.*\\)$")
set(in_special_block TRUE) # Latch on
elseif("${dep}" STREQUAL "::@")
set(in_special_block FALSE) # Latch off
elseif(NOT in_special_block)
string(REGEX REPLACE "\\\$<BUILD_INTERFACE:([^>]*)>" "\\1" dep ${dep})
string(REGEX REPLACE "\\\$<LINK_ONLY:([^>]*)>" "\\1" dep ${dep})
if(TARGET ${dep})
get_target_property(_aliased_dep ${dep} ALIASED_TARGET)
if(_aliased_dep)
list(APPEND filtered_deps ${_aliased_dep})
else()
list(APPEND filtered_deps ${dep})
endif()
endif()
endif()
endforeach()
set(all_deps ${filtered_deps})
foreach(dep IN LISTS filtered_deps)
# Avoid infinite recursion if the target has a cyclic dependency
if(NOT "${dep}" IN_LIST ${out_deps})
avif_collect_deps(${dep} dep_child_deps)
list(APPEND all_deps ${dep_child_deps})
endif()
endforeach()
list(REMOVE_DUPLICATES all_deps)
set(${out_deps} "${all_deps}" PARENT_SCOPE)
endfunction()
function(merge_static_libs target in_target)
set(args ${ARGN})
set(dependencies ${in_target})
set(libs $<TARGET_FILE:${in_target}>)
set(source_file ${CMAKE_CURRENT_BINARY_DIR}/${target}_depends.c)
add_library(${target} STATIC ${source_file})
get_target_property(include_dirs ${in_target} INTERFACE_INCLUDE_DIRECTORIES)
if(include_dirs)
target_include_directories(${target} PUBLIC ${include_dirs})
endif()
avif_collect_deps(${in_target} lib_deps)
foreach(lib ${lib_deps})
get_target_property(child_target_type ${lib} TYPE)
if(${child_target_type} STREQUAL "INTERFACE_LIBRARY")
continue()
endif()
get_target_property(link_dirs ${lib} INTERFACE_LINK_DIRECTORIES)
if(link_dirs)
target_link_directories(${target} PUBLIC ${link_dirs})
endif()
get_target_property(is_avif_local ${lib} AVIF_LOCAL)
if(is_avif_local)
list(APPEND libs $<TARGET_FILE:${lib}>)
list(APPEND dependencies "${lib}")
endif()
endforeach()
list(REMOVE_DUPLICATES libs)
add_custom_command(
OUTPUT ${source_file} DEPENDS ${dependencies} COMMAND ${CMAKE_COMMAND} -E echo \"const int dummy = 0\;\" > ${source_file}
)
add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E remove $<TARGET_FILE:${target}>)
if(APPLE)
add_custom_command(
TARGET ${target}
POST_BUILD
COMMENT "Merge static libraries with libtool"
COMMAND xcrun libtool -static -o $<TARGET_FILE:${target}> -no_warning_for_no_symbols ${libs}
)
elseif(CMAKE_C_COMPILER_ID MATCHES "^(Clang|GNU|Intel|IntelLLVM)$")
add_custom_command(
TARGET ${target}
POST_BUILD
COMMENT "Merge static libraries with ar"
COMMAND ${CMAKE_COMMAND} -E echo CREATE $<TARGET_FILE:${target}> >script.ar
)
foreach(lib ${libs})
add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo ADDLIB ${lib} >>script.ar)
endforeach()
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo SAVE >>script.ar
COMMAND ${CMAKE_COMMAND} -E echo END >>script.ar
COMMAND ${CMAKE_AR} -M <script.ar
COMMAND ${CMAKE_COMMAND} -E remove script.ar
)
elseif(MSVC)
if(CMAKE_LIBTOOL)
set(BUNDLE_TOOL ${CMAKE_LIBTOOL})
else()
find_program(BUNDLE_TOOL lib HINTS "${CMAKE_C_COMPILER}/..")
if(NOT BUNDLE_TOOL)
message(FATAL_ERROR "Cannot locate lib.exe to bundle libraries")
endif()
endif()
add_custom_command(
TARGET ${target}
POST_BUILD
COMMENT "Merge static libraries with lib.exe"
COMMAND ${BUNDLE_TOOL} /NOLOGO /OUT:$<TARGET_FILE:${target}> ${libs}
)
else()
message(FATAL_ERROR "Unsupported platform for static link merging")
endif()
endfunction()
|