1
+ # https://cristianadam.eu/20190501/bundling-together-static-libraries-with-cmake/
2
+
3
+ function (bundle_static_library tgt_name bundled_tgt_name)
4
+ list (APPEND static_libs ${tgt_name} )
5
+
6
+ function (_recursively_collect_dependencies input_target)
7
+ set (_input_link_libraries LINK_LIBRARIES )
8
+ get_target_property (_input_type ${input_target} TYPE )
9
+ if (${_input_type} STREQUAL "INTERFACE_LIBRARY" )
10
+ set (_input_link_libraries INTERFACE_LINK_LIBRARIES)
11
+ endif ()
12
+ get_target_property (public_dependencies ${input_target} ${_input_link_libraries} )
13
+ foreach (dependency IN LISTS public_dependencies)
14
+ if (TARGET ${dependency} )
15
+ get_target_property (alias ${dependency} ALIASED_TARGET)
16
+ if (TARGET ${alias} )
17
+ set (dependency ${alias} )
18
+ endif ()
19
+ get_target_property (_type ${dependency} TYPE )
20
+ if (${_type} STREQUAL "STATIC_LIBRARY" )
21
+ list (APPEND static_libs ${dependency} )
22
+ endif ()
23
+
24
+ get_property (library_already_added
25
+ GLOBAL PROPERTY _${tgt_name} _static_bundle_${dependency} )
26
+ if (NOT library_already_added)
27
+ set_property (GLOBAL PROPERTY _${tgt_name} _static_bundle_${dependency} ON )
28
+ _recursively_collect_dependencies(${dependency} )
29
+ endif ()
30
+ endif ()
31
+ endforeach ()
32
+ set (static_libs ${static_libs} PARENT_SCOPE)
33
+ endfunction ()
34
+
35
+ _recursively_collect_dependencies(${tgt_name} )
36
+
37
+ list (REMOVE_DUPLICATES static_libs)
38
+
39
+ set (bundled_tgt_full_name
40
+ ${CMAKE_BINARY_DIR} /${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX} )
41
+
42
+ if (CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU)$" )
43
+ file (WRITE ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar.in
44
+ "CREATE ${bundled_tgt_full_name} \n " )
45
+
46
+ foreach (tgt IN LISTS static_libs)
47
+ file (APPEND ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar.in
48
+ "ADDLIB $<TARGET_FILE:${tgt} >\n " )
49
+ endforeach ()
50
+
51
+ file (APPEND ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar.in "SAVE\n " )
52
+ file (APPEND ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar.in "END\n " )
53
+
54
+ file (GENERATE
55
+ OUTPUT ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar
56
+ INPUT ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar.in)
57
+
58
+ set (ar_tool ${CMAKE_AR} )
59
+ if (CMAKE_INTERPROCEDURAL_OPTIMIZATION)
60
+ set (ar_tool ${CMAKE_CXX_COMPILER_AR} )
61
+ endif ()
62
+
63
+ add_custom_command (
64
+ COMMAND ${ar_tool} -M < ${CMAKE_BINARY_DIR} /${bundled_tgt_name} .ar
65
+ OUTPUT ${bundled_tgt_full_name}
66
+ COMMENT "Bundling ${bundled_tgt_name} "
67
+ VERBATIM )
68
+ elseif (MSVC )
69
+ find_program (lib_tool lib)
70
+
71
+ if (NOT lib_tool)
72
+ get_filename_component (CXX_COMPILER_DIRECTORY "${CMAKE_CXX_COMPILER} " PATH )
73
+ set (lib_tool "${CXX_COMPILER_DIRECTORY} /lib.exe" )
74
+ endif ()
75
+
76
+ foreach (tgt IN LISTS static_libs)
77
+ list (APPEND static_libs_full_names $<TARGET_FILE:${tgt} >)
78
+ endforeach ()
79
+
80
+ add_custom_command (
81
+ COMMAND ${lib_tool} /NOLOGO /OUT:${bundled_tgt_full_name} ${static_libs_full_names}
82
+ OUTPUT ${bundled_tgt_full_name}
83
+ COMMENT "Bundling ${bundled_tgt_name} "
84
+ VERBATIM )
85
+ else ()
86
+ message (FATAL_ERROR "Unknown bundle scenario!" )
87
+ endif ()
88
+
89
+ add_custom_target (bundling_target ALL DEPENDS ${bundled_tgt_full_name} )
90
+ add_dependencies (bundling_target ${tgt_name} )
91
+
92
+ add_library (${bundled_tgt_name} STATIC IMPORTED )
93
+ set_target_properties (${bundled_tgt_name}
94
+ PROPERTIES
95
+ IMPORTED_LOCATION ${bundled_tgt_full_name}
96
+ INTERFACE_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:${tgt_name} ,INTERFACE_INCLUDE_DIRECTORIES >)
97
+ add_dependencies (${bundled_tgt_name} bundling_target)
98
+
99
+ endfunction ()
0 commit comments