File: merge_static_libs.cmake

package info (click to toggle)
libavif 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 20,956 kB
  • sloc: ansic: 29,303; cpp: 13,260; sh: 1,145; xml: 1,040; java: 307; makefile: 51
file content (133 lines) | stat: -rw-r--r-- 4,788 bytes parent folder | download | duplicates (3)
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()