-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArchiveUtility.cmake
181 lines (156 loc) · 5.92 KB
/
ArchiveUtility.cmake
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#
# Copyright (C) 2021 Swift Navigation Inc.
# Contact: Swift Navigation <dev@swift-nav.com>
#
# This source is subject to the license found in the file 'LICENSE' which must
# be be distributed together with this source. All other rights reserved.
#
# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
#
#
# ArchiveUtility
#
# Archive library utility module offers the following commands to users:
#
# * add_static_library_bundle
#
# Read through the functions documentation for mode details on what they do.
#
#
# Usage:
# extract_static_library_bundle (<variable> <target>)
#
# Required:
# variable: list variable where the static library dependencies will be inserted into
# target: cmake static library target for which to extract dependencies from
#
# Given a static library target, the function will prepend onto the variable all
# the cmake static library targets that it will need to be bundled up into order
# to produce a single static library which contains everything needed for a
# person to link directly to the library without any further dependencies.
#
function (extract_static_library_bundle list_ target_)
if (NOT TARGET ${target_})
return ()
endif ()
get_target_property (target_type_ ${target_} TYPE)
if (NOT target_type_ STREQUAL "STATIC_LIBRARY")
return ()
endif ()
list (INSERT ${list_} 0 ${target_})
set (${list_} "${${list_}}" PARENT_SCOPE)
get_target_property (link_libraries_ ${target_} LINK_LIBRARIES)
if (NOT link_libraries_)
return ()
endif ()
foreach (link_library_ IN LISTS link_libraries_)
extract_static_library_bundle (${list_} ${link_library_})
endforeach ()
list (REMOVE_DUPLICATES ${list_})
set (${list_} "${${list_}}" PARENT_SCOPE)
endfunction ()
#
# Usage:
# add_static_library_bundle (<target> <libraries ...> [OUTPUT_NAME name] [OUTPUT_DIRECTORY])
#
# Required
# target: name of the cmake target to create
# libraries: list of cmake static library which will be bundled up
#
# Optional:
# OUTPUT_NAME: static library name to generate (defaults to ${target})
# OUTPUT_DIRECTORY: directory where the static library bundle will be generated (defaults to ${CMAKE_CURRENT_BINARY_DIR})
#
# NOTE: this function currently is only supported on UNIX platforms
#
# Creates a cmake target which when invoked will create a static library that is
# an aggregation of the provided cmake static libraries and all its static
# library dependencies into a single static library (aka bundle).
#
# The output target resides within the OUTPUT_DIRECTORY with the file name
# "${CMAKE_STATIC_LIBRARY_PREFIX}${OUTPUT_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}"
#
function (add_static_library_bundle target)
if (NOT UNIX)
message (FATAL_ERROR "function currently is only supported on UNIX platforms")
endif ()
set (argOption "")
set (argSingle "OUTPUT_NAME" "OUTPUT_DIRECTORY")
set (argMulti "")
cmake_parse_arguments (x "${argOption}" "${argSingle}" "${argMulti}" ${ARGN})
set (output_name ${target})
set (output_directory ${CMAKE_CURRENT_BINARY_DIR})
set (libraries ${x_UNPARSED_ARGUMENTS})
if (x_OUTPUT_NAME)
set (output_name ${x_OUTPUT_NAME})
endif ()
if (x_OUTPUT_DIRECTORY)
set (output_directory ${x_OUTPUT_DIRECTORY})
endif ()
set (bundle_libraries)
foreach (library IN LISTS libraries)
extract_static_library_bundle (bundle_libraries ${library})
endforeach ()
set (output_library ${CMAKE_STATIC_LIBRARY_PREFIX}${output_name}${CMAKE_STATIC_LIBRARY_SUFFIX})
set (mri_script_dir ${CMAKE_CURRENT_BINARY_DIR}/${target}-mri)
execute_process (COMMAND ${CMAKE_COMMAND} -E make_directory ${mri_script_dir})
set (mri_script)
string (APPEND mri_script "counter=1\n")
string (APPEND mri_script "echo create ${output_library}\n\n")
foreach (bundle_library IN LISTS bundle_libraries)
string (APPEND mri_script "if [[ \"\$<TARGET_FILE:${bundle_library}>\" =~ [+] ]] ; then\n")
string (APPEND mri_script " cp \"\$<TARGET_FILE:${bundle_library}>\" \"${mri_script_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}mri_\${counter}${CMAKE_STATIC_LIBRARY_SUFFIX}\"\n")
string (APPEND mri_script " echo addlib ${mri_script_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}mri_\${counter}${CMAKE_STATIC_LIBRARY_SUFFIX}\n")
string (APPEND mri_script " counter=$((counter + 1))\n")
string (APPEND mri_script "else\n")
string (APPEND mri_script " echo addlib \$<TARGET_FILE:${bundle_library}>\n")
string (APPEND mri_script "fi\n\n")
endforeach()
string (APPEND mri_script "echo save\n")
string (APPEND mri_script "echo end\n")
if (ARCHIVE_IAR)
set (iar_script)
string (APPEND iar_script "--create")
foreach (bundle_library IN LISTS bundle_libraries)
string (APPEND iar_script " \$<TARGET_FILE:${bundle_library}>")
endforeach()
string (APPEND iar_script " -o ${output_directory}/${output_library}\n")
set (iar_script_file ${mri_script_dir}/script.iar.sh)
set (iar_cp_file ${mri_script_dir}/script.iar_cp.sh)
file (GENERATE
OUTPUT ${iar_script_file}
CONTENT "${iar_script}"
CONDITION 1
)
add_custom_command (
OUTPUT ${output_directory}/${output_library}
COMMAND ${CMAKE_AR} -f ${iar_script_file}
COMMAND_EXPAND_LISTS
WORKING_DIRECTORY
${output_directory}
DEPENDS
${bundle_libraries}
)
else ()
set (mri_script_file ${mri_script_dir}/script.mri.sh)
file (GENERATE
OUTPUT ${mri_script_file}
CONTENT "${mri_script}"
CONDITION 1
)
add_custom_command (
OUTPUT ${output_directory}/${output_library}
COMMAND bash ${mri_script_file} | ${CMAKE_AR} -M
COMMAND_EXPAND_LISTS
WORKING_DIRECTORY
${output_directory}
DEPENDS
${bundle_libraries}
)
endif()
add_custom_target (${target} ALL
DEPENDS ${output_directory}/${output_library}
)
endfunction ()