cocoapods 1.9.1 → 1.10.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +229 -5
- data/README.md +2 -1
- data/lib/cocoapods.rb +3 -1
- data/lib/cocoapods/command.rb +12 -2
- data/lib/cocoapods/command/lib/lint.rb +12 -3
- data/lib/cocoapods/command/repo/push.rb +1 -1
- data/lib/cocoapods/command/repo/update.rb +11 -0
- data/lib/cocoapods/command/spec/lint.rb +12 -3
- data/lib/cocoapods/config.rb +17 -0
- data/lib/cocoapods/downloader/cache.rb +2 -2
- data/lib/cocoapods/gem_version.rb +1 -1
- data/lib/cocoapods/generator/app_target_helper.rb +10 -2
- data/lib/cocoapods/generator/copy_dsyms_script.rb +56 -0
- data/lib/cocoapods/generator/copy_resources_script.rb +2 -14
- data/lib/cocoapods/generator/copy_xcframework_script.rb +254 -0
- data/lib/cocoapods/generator/embed_frameworks_script.rb +125 -212
- data/lib/cocoapods/generator/script_phase_constants.rb +99 -0
- data/lib/cocoapods/installer.rb +70 -3
- data/lib/cocoapods/installer/analyzer.rb +17 -8
- data/lib/cocoapods/installer/analyzer/target_inspection_result.rb +1 -1
- data/lib/cocoapods/installer/base_install_hooks_context.rb +135 -0
- data/lib/cocoapods/installer/installation_options.rb +5 -0
- data/lib/cocoapods/installer/pod_source_installer.rb +2 -1
- data/lib/cocoapods/installer/post_install_hooks_context.rb +1 -127
- data/lib/cocoapods/installer/post_integrate_hooks_context.rb +9 -0
- data/lib/cocoapods/installer/project_cache/project_metadata_cache.rb +4 -0
- data/lib/cocoapods/installer/sandbox_dir_cleaner.rb +2 -1
- data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +132 -111
- data/lib/cocoapods/installer/xcode/pods_project_generator.rb +45 -6
- data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +13 -27
- data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +2 -1
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_dependency_installer.rb +8 -6
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +175 -58
- data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_integrator.rb +61 -30
- data/lib/cocoapods/installer/xcode/pods_project_generator/project_generator.rb +3 -2
- data/lib/cocoapods/installer/xcode/pods_project_generator/target_installation_result.rb +5 -7
- data/lib/cocoapods/installer/xcode/pods_project_generator_result.rb +19 -0
- data/lib/cocoapods/installer/xcode/target_validator.rb +1 -1
- data/lib/cocoapods/sources_manager.rb +2 -1
- data/lib/cocoapods/target.rb +44 -2
- data/lib/cocoapods/target/aggregate_target.rb +35 -0
- data/lib/cocoapods/target/build_settings.rb +84 -17
- data/lib/cocoapods/target/pod_target.rb +85 -11
- data/lib/cocoapods/user_interface/error_report.rb +1 -1
- data/lib/cocoapods/user_interface/inspector_reporter.rb +3 -10
- data/lib/cocoapods/validator.rb +37 -11
- data/lib/cocoapods/xcode/framework_paths.rb +1 -1
- data/lib/cocoapods/xcode/xcframework.rb +17 -4
- data/lib/cocoapods/xcode/xcframework/xcframework_slice.rb +81 -3
- metadata +32 -54
- data/lib/cocoapods/generator/prepare_artifacts_script.rb +0 -257
data/lib/cocoapods/config.rb
CHANGED
@@ -60,6 +60,11 @@ module Pod
|
|
60
60
|
attr_accessor :silent
|
61
61
|
alias_method :silent?, :silent
|
62
62
|
|
63
|
+
# @return [Bool] Whether CocoaPods is allowed to run as root.
|
64
|
+
#
|
65
|
+
attr_accessor :allow_root
|
66
|
+
alias_method :allow_root?, :allow_root
|
67
|
+
|
63
68
|
# @return [Bool] Whether a message should be printed when a new version of
|
64
69
|
# CocoaPods is available.
|
65
70
|
#
|
@@ -314,6 +319,18 @@ module Pod
|
|
314
319
|
nil
|
315
320
|
end
|
316
321
|
|
322
|
+
# Excludes the given dir from Time Machine backups.
|
323
|
+
#
|
324
|
+
# @param [Pathname] dir
|
325
|
+
# The directory to exclude from Time Machine backups.
|
326
|
+
#
|
327
|
+
# @return [void]
|
328
|
+
#
|
329
|
+
def exclude_from_backup(dir)
|
330
|
+
return if Gem.win_platform?
|
331
|
+
system('tmutil', 'addexclusion', dir.to_s, %i(out err) => File::NULL)
|
332
|
+
end
|
333
|
+
|
317
334
|
public
|
318
335
|
|
319
336
|
#-------------------------------------------------------------------------#
|
@@ -97,7 +97,7 @@ module Pod
|
|
97
97
|
# `request`.
|
98
98
|
#
|
99
99
|
def path_for_pod(request, slug_opts = {})
|
100
|
-
root + request.slug(slug_opts)
|
100
|
+
root + request.slug(**slug_opts)
|
101
101
|
end
|
102
102
|
|
103
103
|
# @param [Request] request
|
@@ -111,7 +111,7 @@ module Pod
|
|
111
111
|
# `request`.
|
112
112
|
#
|
113
113
|
def path_for_spec(request, slug_opts = {})
|
114
|
-
path = root + 'Specs' + request.slug(slug_opts)
|
114
|
+
path = root + 'Specs' + request.slug(**slug_opts)
|
115
115
|
path.sub_ext('.podspec.json')
|
116
116
|
end
|
117
117
|
|
@@ -127,9 +127,17 @@ module Pod
|
|
127
127
|
# @return [void]
|
128
128
|
#
|
129
129
|
def self.add_xctest_search_paths(target)
|
130
|
+
requires_libs = target.platform_name == :ios &&
|
131
|
+
Version.new(target.deployment_target) < Version.new('12.2')
|
132
|
+
|
130
133
|
target.build_configurations.each do |configuration|
|
131
|
-
|
132
|
-
|
134
|
+
framework_search_paths = configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] ||= '$(inherited)'
|
135
|
+
framework_search_paths << ' "$(PLATFORM_DIR)/Developer/Library/Frameworks"'
|
136
|
+
|
137
|
+
if requires_libs
|
138
|
+
library_search_paths = configuration.build_settings['LIBRARY_SEARCH_PATHS'] ||= '$(inherited)'
|
139
|
+
library_search_paths << ' "$(PLATFORM_DIR)/Developer/usr/lib"'
|
140
|
+
end
|
133
141
|
end
|
134
142
|
end
|
135
143
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Pod
|
2
|
+
module Generator
|
3
|
+
class CopydSYMsScript
|
4
|
+
# @return [Array<Pathname>] dsym_paths the dSYM paths to include in the script contents.
|
5
|
+
#
|
6
|
+
attr_reader :dsym_paths
|
7
|
+
|
8
|
+
# @return [Array<Pathname>] bcsymbolmap_paths the bcsymbolmap paths to include in the script contents.
|
9
|
+
#
|
10
|
+
attr_reader :bcsymbolmap_paths
|
11
|
+
|
12
|
+
# Initialize a new instance
|
13
|
+
#
|
14
|
+
# @param [Array<Pathname>] dsym_paths @see dsym_paths
|
15
|
+
# @param [Array<Pathname>] bcsymbolmap_paths @see bcsymbolmap_paths
|
16
|
+
#
|
17
|
+
def initialize(dsym_paths, bcsymbolmap_paths)
|
18
|
+
@dsym_paths = Array(dsym_paths)
|
19
|
+
@bcsymbolmap_paths = Array(bcsymbolmap_paths)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Saves the copy dSYMs script to the given pathname.
|
23
|
+
#
|
24
|
+
# @param [Pathname] pathname
|
25
|
+
# The path where the copy dSYMs script should be saved.
|
26
|
+
#
|
27
|
+
# @return [void]
|
28
|
+
#
|
29
|
+
def save_as(pathname)
|
30
|
+
pathname.open('w') do |file|
|
31
|
+
file.puts(generate)
|
32
|
+
end
|
33
|
+
File.chmod(0755, pathname.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [String] The generated of the copy dSYMs script.
|
37
|
+
#
|
38
|
+
def generate
|
39
|
+
script = <<-SH.strip_heredoc
|
40
|
+
#{Pod::Generator::ScriptPhaseConstants::DEFAULT_SCRIPT_PHASE_HEADER}
|
41
|
+
#{Pod::Generator::ScriptPhaseConstants::STRIP_INVALID_ARCHITECTURES_METHOD}
|
42
|
+
#{Pod::Generator::ScriptPhaseConstants::RSYNC_PROTECT_TMP_FILES}
|
43
|
+
#{Pod::Generator::ScriptPhaseConstants::INSTALL_DSYM_METHOD}
|
44
|
+
#{Pod::Generator::ScriptPhaseConstants::INSTALL_BCSYMBOLMAP_METHOD}
|
45
|
+
SH
|
46
|
+
dsym_paths.each do |dsym_path|
|
47
|
+
script << %(install_dsym "#{dsym_path}"\n)
|
48
|
+
end
|
49
|
+
bcsymbolmap_paths.each do |bcsymbolmap_path|
|
50
|
+
script << %(install_bcsymbolmap "#{bcsymbolmap_path}"\n)
|
51
|
+
end
|
52
|
+
script
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -100,16 +100,7 @@ module Pod
|
|
100
100
|
end
|
101
101
|
|
102
102
|
INSTALL_RESOURCES_FUNCTION = <<EOS
|
103
|
-
|
104
|
-
set -e
|
105
|
-
set -u
|
106
|
-
set -o pipefail
|
107
|
-
|
108
|
-
function on_error {
|
109
|
-
echo "$(realpath -mq "${0}"):$1: error: Unexpected failure"
|
110
|
-
}
|
111
|
-
trap 'on_error $LINENO' ERR
|
112
|
-
|
103
|
+
#{Pod::Generator::ScriptPhaseConstants::DEFAULT_SCRIPT_PHASE_HEADER}
|
113
104
|
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
|
114
105
|
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
|
115
106
|
# resources to, so exit 0 (signalling the script phase was successful).
|
@@ -123,10 +114,7 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
|
123
114
|
|
124
115
|
XCASSET_FILES=()
|
125
116
|
|
126
|
-
#
|
127
|
-
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
128
|
-
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
129
|
-
|
117
|
+
#{Pod::Generator::ScriptPhaseConstants::RSYNC_PROTECT_TMP_FILES}
|
130
118
|
case "${TARGETED_DEVICE_FAMILY:-}" in
|
131
119
|
1,2)
|
132
120
|
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
@@ -0,0 +1,254 @@
|
|
1
|
+
require 'cocoapods/xcode'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
module Generator
|
5
|
+
class CopyXCFrameworksScript
|
6
|
+
# @return [Array<Pod::Xcode::XCFramework>] List of xcframeworks to copy
|
7
|
+
#
|
8
|
+
attr_reader :xcframeworks
|
9
|
+
|
10
|
+
# @return [Pathname] the root directory of the sandbox
|
11
|
+
#
|
12
|
+
attr_reader :sandbox_root
|
13
|
+
|
14
|
+
# @return [Platform] the platform of the target for which this script will run
|
15
|
+
#
|
16
|
+
attr_reader :platform
|
17
|
+
|
18
|
+
# Creates a script for copying XCFramework slcies into an intermediate build directory
|
19
|
+
#
|
20
|
+
# @param [Array<Pod::Xcode::XCFramework>] xcframeworks
|
21
|
+
# the list of xcframeworks to copy
|
22
|
+
#
|
23
|
+
# @param [Pathname] sandbox_root
|
24
|
+
# the root of the Sandbox into which this script will be installed
|
25
|
+
#
|
26
|
+
# @param [Platform] platform
|
27
|
+
# the platform of the target for which this script will be run
|
28
|
+
#
|
29
|
+
def initialize(xcframeworks, sandbox_root, platform)
|
30
|
+
@xcframeworks = xcframeworks
|
31
|
+
@sandbox_root = sandbox_root
|
32
|
+
@platform = platform
|
33
|
+
end
|
34
|
+
|
35
|
+
# Saves the resource script to the given pathname.
|
36
|
+
#
|
37
|
+
# @param [Pathname] pathname
|
38
|
+
# The path where the embed frameworks script should be saved.
|
39
|
+
#
|
40
|
+
# @return [void]
|
41
|
+
#
|
42
|
+
def save_as(pathname)
|
43
|
+
pathname.open('w') do |file|
|
44
|
+
file.puts(script)
|
45
|
+
end
|
46
|
+
File.chmod(0o755, pathname.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [String] The contents of the embed frameworks script.
|
50
|
+
#
|
51
|
+
def generate
|
52
|
+
script
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
# @!group Private Helpers
|
58
|
+
|
59
|
+
# @return [String] The contents of the prepare artifacts script.
|
60
|
+
#
|
61
|
+
def script
|
62
|
+
script = <<-SH.strip_heredoc
|
63
|
+
#{Pod::Generator::ScriptPhaseConstants::DEFAULT_SCRIPT_PHASE_HEADER}
|
64
|
+
|
65
|
+
#{Pod::Generator::ScriptPhaseConstants::RSYNC_PROTECT_TMP_FILES}
|
66
|
+
|
67
|
+
copy_dir()
|
68
|
+
{
|
69
|
+
local source="$1"
|
70
|
+
local destination="$2"
|
71
|
+
|
72
|
+
# Use filter instead of exclude so missing patterns don't throw errors.
|
73
|
+
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" \\"${source}\\" \\"${destination}\\""
|
74
|
+
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}" "${destination}"
|
75
|
+
}
|
76
|
+
|
77
|
+
SELECT_SLICE_RETVAL=""
|
78
|
+
|
79
|
+
select_slice() {
|
80
|
+
local paths=("$@")
|
81
|
+
# Locate the correct slice of the .xcframework for the current architectures
|
82
|
+
local target_path=""
|
83
|
+
|
84
|
+
# Split archs on space so we can find a slice that has all the needed archs
|
85
|
+
local target_archs=$(echo $ARCHS | tr " " "\\n")
|
86
|
+
|
87
|
+
local target_variant=""
|
88
|
+
if [[ "$PLATFORM_NAME" == *"simulator" ]]; then
|
89
|
+
target_variant="simulator"
|
90
|
+
fi
|
91
|
+
if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then
|
92
|
+
target_variant="maccatalyst"
|
93
|
+
fi
|
94
|
+
for i in ${!paths[@]}; do
|
95
|
+
local matched_all_archs="1"
|
96
|
+
for target_arch in $target_archs
|
97
|
+
do
|
98
|
+
if ! [[ "${paths[$i]}" == *"$target_variant"* ]]; then
|
99
|
+
matched_all_archs="0"
|
100
|
+
break
|
101
|
+
fi
|
102
|
+
|
103
|
+
# Verifies that the path contains the variant string (simulator or maccatalyst) if the variant is set.
|
104
|
+
if [[ -z "$target_variant" && ("${paths[$i]}" == *"simulator"* || "${paths[$i]}" == *"maccatalyst"*) ]]; then
|
105
|
+
matched_all_archs="0"
|
106
|
+
break
|
107
|
+
fi
|
108
|
+
|
109
|
+
# This regex matches all possible variants of the arch in the folder name:
|
110
|
+
# Let's say the folder name is: ios-armv7_armv7s_arm64_arm64e/CoconutLib.framework
|
111
|
+
# We match the following: -armv7_, _armv7s_, _arm64_ and _arm64e/.
|
112
|
+
# If we have a specific variant: ios-i386_x86_64-simulator/CoconutLib.framework
|
113
|
+
# We match the following: -i386_ and _x86_64-
|
114
|
+
# When the .xcframework wraps a static library, the folder name does not include
|
115
|
+
# any .framework. In that case, the folder name can be: ios-arm64_armv7
|
116
|
+
# We also match _armv7$ to handle that case.
|
117
|
+
local target_arch_regex="[_\\-]${target_arch}([\\/_\\-]|$)"
|
118
|
+
if ! [[ "${paths[$i]}" =~ $target_arch_regex ]]; then
|
119
|
+
matched_all_archs="0"
|
120
|
+
break
|
121
|
+
fi
|
122
|
+
done
|
123
|
+
|
124
|
+
if [[ "$matched_all_archs" == "1" ]]; then
|
125
|
+
# Found a matching slice
|
126
|
+
echo "Selected xcframework slice ${paths[$i]}"
|
127
|
+
SELECT_SLICE_RETVAL=${paths[$i]}
|
128
|
+
break
|
129
|
+
fi
|
130
|
+
done
|
131
|
+
}
|
132
|
+
|
133
|
+
install_library() {
|
134
|
+
local source="$1"
|
135
|
+
local name="$2"
|
136
|
+
local destination="#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/${name}"
|
137
|
+
|
138
|
+
# Libraries can contain headers, module maps, and a binary, so we'll copy everything in the folder over
|
139
|
+
|
140
|
+
local source="$binary"
|
141
|
+
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" \\"${source}/*\\" \\"${destination}\\""
|
142
|
+
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}/*" "${destination}"
|
143
|
+
}
|
144
|
+
|
145
|
+
# Copies a framework to derived data for use in later build phases
|
146
|
+
install_framework()
|
147
|
+
{
|
148
|
+
local source="$1"
|
149
|
+
local name="$2"
|
150
|
+
local destination="#{Pod::Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/${name}"
|
151
|
+
|
152
|
+
if [ ! -d "$destination" ]; then
|
153
|
+
mkdir -p "$destination"
|
154
|
+
fi
|
155
|
+
|
156
|
+
copy_dir "$source" "$destination"
|
157
|
+
echo "Copied $source to $destination"
|
158
|
+
}
|
159
|
+
|
160
|
+
install_xcframework_library() {
|
161
|
+
local basepath="$1"
|
162
|
+
local name="$2"
|
163
|
+
local paths=("$@")
|
164
|
+
|
165
|
+
# Locate the correct slice of the .xcframework for the current architectures
|
166
|
+
select_slice "${paths[@]}"
|
167
|
+
local target_path="$SELECT_SLICE_RETVAL"
|
168
|
+
if [[ -z "$target_path" ]]; then
|
169
|
+
echo "warning: [CP] Unable to find matching .xcframework slice in '${paths[@]}' for the current build architectures ($ARCHS)."
|
170
|
+
return
|
171
|
+
fi
|
172
|
+
|
173
|
+
install_framework "$basepath/$target_path" "$name"
|
174
|
+
}
|
175
|
+
|
176
|
+
install_xcframework() {
|
177
|
+
local basepath="$1"
|
178
|
+
local name="$2"
|
179
|
+
local package_type="$3"
|
180
|
+
local paths=("$@")
|
181
|
+
|
182
|
+
# Locate the correct slice of the .xcframework for the current architectures
|
183
|
+
select_slice "${paths[@]}"
|
184
|
+
local target_path="$SELECT_SLICE_RETVAL"
|
185
|
+
if [[ -z "$target_path" ]]; then
|
186
|
+
echo "warning: [CP] Unable to find matching .xcframework slice in '${paths[@]}' for the current build architectures ($ARCHS)."
|
187
|
+
return
|
188
|
+
fi
|
189
|
+
local source="$basepath/$target_path"
|
190
|
+
|
191
|
+
local destination="#{Pod::Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/${name}"
|
192
|
+
|
193
|
+
if [ ! -d "$destination" ]; then
|
194
|
+
mkdir -p "$destination"
|
195
|
+
fi
|
196
|
+
|
197
|
+
if [[ "$package_type" == "library" ]]; then
|
198
|
+
# Libraries can contain headers, module maps, and a binary, so we'll copy everything in the folder over
|
199
|
+
copy_dir "$source/" "$destination"
|
200
|
+
elif [[ "$package_type" == "framework" ]]; then
|
201
|
+
copy_dir "$source" "$destination"
|
202
|
+
fi
|
203
|
+
echo "Copied $source to $destination"
|
204
|
+
}
|
205
|
+
|
206
|
+
SH
|
207
|
+
xcframeworks.each do |xcframework|
|
208
|
+
slices = xcframework.slices.select { |f| f.platform.symbolic_name == platform.symbolic_name }
|
209
|
+
next if slices.empty?
|
210
|
+
args = install_xcframework_args(xcframework, slices)
|
211
|
+
script << "install_xcframework #{args}\n"
|
212
|
+
end
|
213
|
+
|
214
|
+
script << "\n" unless xcframeworks.empty?
|
215
|
+
script
|
216
|
+
end
|
217
|
+
|
218
|
+
def shell_escape(value)
|
219
|
+
"\"#{value}\""
|
220
|
+
end
|
221
|
+
|
222
|
+
def install_xcframework_args(xcframework, slices)
|
223
|
+
root = xcframework.path
|
224
|
+
args = [shell_escape("${PODS_ROOT}/#{root.relative_path_from(sandbox_root)}")]
|
225
|
+
args << shell_escape(xcframework.name)
|
226
|
+
is_framework = xcframework.build_type.framework?
|
227
|
+
args << shell_escape(is_framework ? 'framework' : 'library')
|
228
|
+
slices.each do |slice|
|
229
|
+
args << if is_framework
|
230
|
+
shell_escape(slice.path.relative_path_from(root))
|
231
|
+
else
|
232
|
+
# We don't want the path to the library binary, we want the dir that contains it
|
233
|
+
shell_escape(slice.path.dirname.relative_path_from(root))
|
234
|
+
end
|
235
|
+
end
|
236
|
+
args.join(' ')
|
237
|
+
end
|
238
|
+
|
239
|
+
class << self
|
240
|
+
# @param [Pathname] xcframework_path
|
241
|
+
# the base path of the .xcframework bundle
|
242
|
+
#
|
243
|
+
# @return [Array<Pathname>] all found .dSYM paths
|
244
|
+
#
|
245
|
+
def dsym_folder(xcframework_path)
|
246
|
+
basename = File.basename(xcframework_path, '.xcframework')
|
247
|
+
dsym_basename = basename + '.dSYMs'
|
248
|
+
path = xcframework_path.dirname + dsym_basename
|
249
|
+
Pathname.new(path) if File.directory?(path)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -8,11 +8,20 @@ module Pod
|
|
8
8
|
#
|
9
9
|
attr_reader :frameworks_by_config
|
10
10
|
|
11
|
+
# @return [Hash{String => Array<XCFrameworkPaths>}] Multiple lists of frameworks per
|
12
|
+
# configuration.
|
13
|
+
#
|
14
|
+
attr_reader :xcframeworks_by_config
|
15
|
+
|
11
16
|
# @param [Hash{String => Array<FrameworkPaths>] frameworks_by_config
|
12
17
|
# @see #frameworks_by_config
|
13
18
|
#
|
14
|
-
|
19
|
+
# @param [Hash{String => Array<XCFramework>] xcframeworks_by_config
|
20
|
+
# @see #xcframeworks_by_config
|
21
|
+
#
|
22
|
+
def initialize(frameworks_by_config, xcframeworks_by_config)
|
15
23
|
@frameworks_by_config = frameworks_by_config
|
24
|
+
@xcframeworks_by_config = xcframeworks_by_config
|
16
25
|
end
|
17
26
|
|
18
27
|
# Saves the resource script to the given pathname.
|
@@ -43,219 +52,123 @@ module Pod
|
|
43
52
|
#
|
44
53
|
def script
|
45
54
|
script = <<-SH.strip_heredoc
|
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
|
-
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
144
|
-
if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then
|
145
|
-
strip_invalid_archs "$binary" "$warn_missing_arch"
|
146
|
-
fi
|
147
|
-
|
148
|
-
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
|
149
|
-
# Move the stripped file into its final destination.
|
150
|
-
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" --filter \\"- Headers\\" --filter \\"- PrivateHeaders\\" --filter \\"- Modules\\" \\"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\\" \\"${DWARF_DSYM_FOLDER_PATH}\\""
|
151
|
-
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
|
152
|
-
else
|
153
|
-
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
|
154
|
-
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM"
|
155
|
-
fi
|
156
|
-
fi
|
157
|
-
}
|
158
|
-
|
159
|
-
# Copies the bcsymbolmap files of a vendored framework
|
160
|
-
install_bcsymbolmap() {
|
161
|
-
local bcsymbolmap_path="$1"
|
162
|
-
local destination="${BUILT_PRODUCTS_DIR}"
|
163
|
-
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${bcsymbolmap_path}\" \"${destination}\""
|
164
|
-
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"
|
165
|
-
}
|
166
|
-
|
167
|
-
# Signs a framework with the provided identity
|
168
|
-
code_sign_if_enabled() {
|
169
|
-
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
170
|
-
# Use the current code_sign_identity
|
171
|
-
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
172
|
-
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
173
|
-
|
174
|
-
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
175
|
-
code_sign_cmd="$code_sign_cmd &"
|
176
|
-
fi
|
177
|
-
echo "$code_sign_cmd"
|
178
|
-
eval "$code_sign_cmd"
|
179
|
-
fi
|
180
|
-
}
|
181
|
-
|
182
|
-
# Strip invalid architectures
|
183
|
-
strip_invalid_archs() {
|
184
|
-
binary="$1"
|
185
|
-
warn_missing_arch=${2:-true}
|
186
|
-
# Get architectures for current target binary
|
187
|
-
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
|
188
|
-
# Intersect them with the architectures we are building for
|
189
|
-
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\\n' | sort | uniq -d)"
|
190
|
-
# If there are no archs supported by this binary then warn the user
|
191
|
-
if [[ -z "$intersected_archs" ]]; then
|
192
|
-
if [[ "$warn_missing_arch" == "true" ]]; then
|
193
|
-
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
|
194
|
-
fi
|
195
|
-
STRIP_BINARY_RETVAL=0
|
196
|
-
return
|
197
|
-
fi
|
198
|
-
stripped=""
|
199
|
-
for arch in $binary_archs; do
|
200
|
-
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
201
|
-
# Strip non-valid architectures in-place
|
202
|
-
lipo -remove "$arch" -output "$binary" "$binary"
|
203
|
-
stripped="$stripped $arch"
|
204
|
-
fi
|
205
|
-
done
|
206
|
-
if [[ "$stripped" ]]; then
|
207
|
-
echo "Stripped $binary of architectures:$stripped"
|
208
|
-
fi
|
209
|
-
STRIP_BINARY_RETVAL=1
|
210
|
-
}
|
211
|
-
|
212
|
-
install_artifact() {
|
213
|
-
artifact="$1"
|
214
|
-
base="$(basename "$artifact")"
|
215
|
-
case $base in
|
216
|
-
*.framework)
|
217
|
-
install_framework "$artifact"
|
218
|
-
;;
|
219
|
-
*.dSYM)
|
220
|
-
# Suppress arch warnings since XCFrameworks will include many dSYM files
|
221
|
-
install_dsym "$artifact" "false"
|
222
|
-
;;
|
223
|
-
*.bcsymbolmap)
|
224
|
-
install_bcsymbolmap "$artifact"
|
225
|
-
;;
|
226
|
-
*)
|
227
|
-
echo "error: Unrecognized artifact "$artifact""
|
228
|
-
;;
|
229
|
-
esac
|
230
|
-
}
|
231
|
-
|
232
|
-
copy_artifacts() {
|
233
|
-
file_list="$1"
|
234
|
-
while read artifact; do
|
235
|
-
install_artifact "$artifact"
|
236
|
-
done <$file_list
|
237
|
-
}
|
238
|
-
|
239
|
-
ARTIFACT_LIST_FILE="${BUILT_PRODUCTS_DIR}/cocoapods-artifacts-${CONFIGURATION}.txt"
|
240
|
-
if [ -r "${ARTIFACT_LIST_FILE}" ]; then
|
241
|
-
copy_artifacts "${ARTIFACT_LIST_FILE}"
|
242
|
-
fi
|
243
|
-
|
55
|
+
#{Pod::Generator::ScriptPhaseConstants::DEFAULT_SCRIPT_PHASE_HEADER}
|
56
|
+
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
|
57
|
+
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
|
58
|
+
# frameworks to, so exit 0 (signalling the script phase was successful).
|
59
|
+
exit 0
|
60
|
+
fi
|
61
|
+
|
62
|
+
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
63
|
+
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
64
|
+
|
65
|
+
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
|
66
|
+
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
67
|
+
BCSYMBOLMAP_DIR="BCSymbolMaps"
|
68
|
+
|
69
|
+
|
70
|
+
#{Pod::Generator::ScriptPhaseConstants::RSYNC_PROTECT_TMP_FILES}
|
71
|
+
# Copies and strips a vendored framework
|
72
|
+
install_framework()
|
73
|
+
{
|
74
|
+
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
75
|
+
local source="${BUILT_PRODUCTS_DIR}/$1"
|
76
|
+
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
77
|
+
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
78
|
+
elif [ -r "$1" ]; then
|
79
|
+
local source="$1"
|
80
|
+
fi
|
81
|
+
|
82
|
+
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
83
|
+
|
84
|
+
if [ -L "${source}" ]; then
|
85
|
+
echo "Symlinked..."
|
86
|
+
source="$(readlink "${source}")"
|
87
|
+
fi
|
88
|
+
|
89
|
+
if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then
|
90
|
+
# Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied
|
91
|
+
find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do
|
92
|
+
echo "Installing $f"
|
93
|
+
install_bcsymbolmap "$f" "$destination"
|
94
|
+
rm "$f"
|
95
|
+
done
|
96
|
+
rmdir "${source}/${BCSYMBOLMAP_DIR}"
|
97
|
+
fi
|
98
|
+
|
99
|
+
# Use filter instead of exclude so missing patterns don't throw errors.
|
100
|
+
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \\"- CVS/\\" --filter \\"- .svn/\\" --filter \\"- .git/\\" --filter \\"- .hg/\\" --filter \\"- Headers\\" --filter \\"- PrivateHeaders\\" --filter \\"- Modules\\" \\"${source}\\" \\"${destination}\\""
|
101
|
+
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
102
|
+
|
103
|
+
local basename
|
104
|
+
basename="$(basename -s .framework "$1")"
|
105
|
+
binary="${destination}/${basename}.framework/${basename}"
|
106
|
+
|
107
|
+
if ! [ -r "$binary" ]; then
|
108
|
+
binary="${destination}/${basename}"
|
109
|
+
elif [ -L "${binary}" ]; then
|
110
|
+
echo "Destination binary is symlinked..."
|
111
|
+
dirname="$(dirname "${binary}")"
|
112
|
+
binary="${dirname}/$(readlink "${binary}")"
|
113
|
+
fi
|
114
|
+
|
115
|
+
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
116
|
+
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
117
|
+
strip_invalid_archs "$binary"
|
118
|
+
fi
|
119
|
+
|
120
|
+
# Resign the code if required by the build settings to avoid unstable apps
|
121
|
+
code_sign_if_enabled "${destination}/$(basename "$1")"
|
122
|
+
|
123
|
+
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
124
|
+
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
125
|
+
local swift_runtime_libs
|
126
|
+
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\\\/\\(.+dylib\\).*/\\\\1/g | uniq -u)
|
127
|
+
for lib in $swift_runtime_libs; do
|
128
|
+
echo "rsync -auv \\"${SWIFT_STDLIB_PATH}/${lib}\\" \\"${destination}\\""
|
129
|
+
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
130
|
+
code_sign_if_enabled "${destination}/${lib}"
|
131
|
+
done
|
132
|
+
fi
|
133
|
+
}
|
134
|
+
#{Pod::Generator::ScriptPhaseConstants::INSTALL_DSYM_METHOD}
|
135
|
+
#{Pod::Generator::ScriptPhaseConstants::STRIP_INVALID_ARCHITECTURES_METHOD}
|
136
|
+
#{Pod::Generator::ScriptPhaseConstants::INSTALL_BCSYMBOLMAP_METHOD}
|
137
|
+
# Signs a framework with the provided identity
|
138
|
+
code_sign_if_enabled() {
|
139
|
+
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
140
|
+
# Use the current code_sign_identity
|
141
|
+
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
142
|
+
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
143
|
+
|
144
|
+
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
145
|
+
code_sign_cmd="$code_sign_cmd &"
|
146
|
+
fi
|
147
|
+
echo "$code_sign_cmd"
|
148
|
+
eval "$code_sign_cmd"
|
149
|
+
fi
|
150
|
+
}
|
244
151
|
SH
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
# sources will have their dSYM generated and copied by Xcode.
|
252
|
-
script << %( install_dsym "#{framework_with_dsym.dsym_path}"\n) unless framework_with_dsym.dsym_path.nil?
|
253
|
-
unless framework_with_dsym.bcsymbolmap_paths.nil?
|
254
|
-
framework_with_dsym.bcsymbolmap_paths.each do |bcsymbolmap_path|
|
255
|
-
script << %( install_bcsymbolmap "#{bcsymbolmap_path}"\n)
|
256
|
-
end
|
257
|
-
end
|
152
|
+
contents_by_config = Hash.new do |hash, key|
|
153
|
+
hash[key] = ''
|
154
|
+
end
|
155
|
+
frameworks_by_config.each do |config, frameworks|
|
156
|
+
frameworks.each do |framework|
|
157
|
+
contents_by_config[config] << %( install_framework "#{framework.source_path}"\n)
|
258
158
|
end
|
159
|
+
end
|
160
|
+
xcframeworks_by_config.each do |config, xcframeworks|
|
161
|
+
xcframeworks.select { |xcf| xcf.build_type.dynamic_framework? }.each do |xcframework|
|
162
|
+
name = xcframework.name
|
163
|
+
contents_by_config[config] << %( install_framework "#{Target::BuildSettings::XCFRAMEWORKS_BUILD_DIR_VARIABLE}/#{name}/#{name}.framework"\n)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
script << "\n" unless contents_by_config.empty?
|
167
|
+
contents_by_config.keys.sort.each do |config|
|
168
|
+
contents = contents_by_config[config]
|
169
|
+
next if contents.empty?
|
170
|
+
script << %(if [[ "$CONFIGURATION" == "#{config}" ]]; then\n)
|
171
|
+
script << contents
|
259
172
|
script << "fi\n"
|
260
173
|
end
|
261
174
|
script << <<-SH.strip_heredoc
|