cocoapods-binary-cache 0.1.8 → 0.1.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cocoapods-binary-cache/helper/podspec.rb +0 -1
- data/lib/cocoapods-binary-cache/hooks/post_install.rb +0 -11
- data/lib/cocoapods-binary-cache/hooks/pre_install.rb +12 -2
- data/lib/cocoapods-binary-cache/main.rb +0 -1
- data/lib/cocoapods-binary-cache/pod-binary/helper/build.rb +27 -30
- data/lib/cocoapods-binary-cache/pod-binary/integration/alter_specs.rb +32 -15
- data/lib/cocoapods-binary-cache/pod-binary/integration/patch/embed_framework_script.rb +1 -1
- data/lib/cocoapods-binary-cache/pod-binary/integration/patch/source_installation.rb +23 -9
- data/lib/cocoapods-binary-cache/pod-binary/integration/source_installer.rb +30 -19
- data/lib/cocoapods-binary-cache/pod-binary/prebuild.rb +24 -18
- data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_command.rb +215 -155
- data/lib/cocoapods-binary-cache/pod-rome/xcodebuild_raw.rb +47 -32
- data/lib/command/config.rb +18 -2
- data/lib/command/executor/base.rb +11 -1
- data/lib/command/executor/fetcher.rb +21 -3
- data/lib/command/executor/prebuilder.rb +8 -6
- data/lib/command/executor/pusher.rb +20 -4
- data/lib/command/prebuild.rb +6 -0
- metadata +16 -4
- data/lib/cocoapods-binary-cache/helper/prebuild_order.rb +0 -12
- data/lib/cocoapods-binary-cache/scheme_editor.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 732c3a4179deba8a6f1ffe95e9035c12d80989a1b3edb0581a5d569f1b9ef542
|
4
|
+
data.tar.gz: c72c2d4333f1525d2078896374b2fbe239891dc404ca35dadffc2f22fc4b8aff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ff71c26afc711721ce4360999a94b03a36fcd49f51ead77583c5ef4b07e86c7c841effcfdc023a4968d26d19d33f66ed9ea0891ce046584e9c4bd50e6afa375
|
7
|
+
data.tar.gz: 1c28065aefc4539864e5645d9d01c5b660c03a9df40ca72a05a07be80cba28c28906e11802ff4fcb676057628e4eb4f39a8eee72ec920a04d4acfc336589a9d2
|
@@ -5,7 +5,6 @@ module PodPrebuild
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def run
|
8
|
-
edit_scheme_for_code_coverage if PodPrebuild::Env.prebuild_stage?
|
9
8
|
diagnose if PodPrebuild::Env.integration_stage?
|
10
9
|
end
|
11
10
|
|
@@ -20,15 +19,5 @@ module PodPrebuild
|
|
20
19
|
).run
|
21
20
|
end
|
22
21
|
end
|
23
|
-
|
24
|
-
def edit_scheme_for_code_coverage
|
25
|
-
return unless PodPrebuild.config.dev_pods_enabled?
|
26
|
-
return unless @installer_context.sandbox.instance_of?(Pod::PrebuildSandbox)
|
27
|
-
|
28
|
-
# Modify pods scheme to support code coverage
|
29
|
-
# If we don't prebuild dev pod -> no need to care about this in Pod project
|
30
|
-
# because we setup in the main project (ex. DriverCI scheme)
|
31
|
-
SchemeEditor.edit_to_support_code_coverage(@installer_context.sandbox)
|
32
|
-
end
|
33
22
|
end
|
34
23
|
end
|
@@ -2,13 +2,14 @@ module PodPrebuild
|
|
2
2
|
class PreInstallHook
|
3
3
|
include ObjectSpace
|
4
4
|
|
5
|
-
attr_reader :installer_context, :podfile, :prebuild_sandbox, :cache_validation
|
5
|
+
attr_reader :installer_context, :podfile, :prebuild_sandbox, :standard_sandbox, :cache_validation
|
6
6
|
|
7
7
|
def initialize(installer_context)
|
8
8
|
@installer_context = installer_context
|
9
9
|
@podfile = installer_context.podfile
|
10
10
|
@pod_install_options = {}
|
11
11
|
@prebuild_sandbox = nil
|
12
|
+
@standard_sandbox = installer_context.sandbox
|
12
13
|
@cache_validation = nil
|
13
14
|
end
|
14
15
|
|
@@ -24,6 +25,7 @@ module PodPrebuild
|
|
24
25
|
prebuild! if PodPrebuild.config.prebuild_job?
|
25
26
|
|
26
27
|
PodPrebuild::Env.next_stage!
|
28
|
+
prepare_for_integration
|
27
29
|
log_section "🤖 Resume pod installation"
|
28
30
|
require_relative "../pod-binary/integration"
|
29
31
|
end
|
@@ -51,7 +53,6 @@ module PodPrebuild
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def create_prebuild_sandbox
|
54
|
-
standard_sandbox = installer_context.sandbox
|
55
56
|
@prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sandbox)
|
56
57
|
Pod::UI.message "Create prebuild sandbox at #{@prebuild_sandbox.root}"
|
57
58
|
end
|
@@ -102,6 +103,15 @@ module PodPrebuild
|
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
106
|
+
def prepare_for_integration
|
107
|
+
# Remove local podspec of external sources so that it downloads sources correctly.
|
108
|
+
# Otherwise, with incremental pod installation, CocoaPods downloads the sources
|
109
|
+
# based on the `s.source` declaration in the podspecs which are sometimes incorrect.
|
110
|
+
PodPrebuild.config.prebuilt_pod_names.each do |name|
|
111
|
+
@standard_sandbox.remove_local_podspec(name) if @standard_sandbox.checkout_sources.key?(name)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
105
115
|
def log_section(message)
|
106
116
|
Pod::UI.puts "-----------------------------------------"
|
107
117
|
Pod::UI.puts message
|
@@ -1,40 +1,37 @@
|
|
1
1
|
require_relative "../../pod-rome/xcodebuild_raw"
|
2
2
|
require_relative "../../pod-rome/xcodebuild_command"
|
3
3
|
|
4
|
-
module
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
return if target.nil?
|
4
|
+
module PodPrebuild
|
5
|
+
def self.build(options)
|
6
|
+
targets = options[:targets] || []
|
7
|
+
return if targets.empty?
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
options[:build_dir] = build_dir(options[:sandbox].root)
|
9
|
+
options[:sandbox] = Pod::Sandbox.new(Pathname(options[:sandbox])) unless options[:sandbox].is_a?(Pod::Sandbox)
|
10
|
+
options[:build_dir] = build_dir(options[:sandbox].root)
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
raise "The build directory was not found in the expected location" unless options[:build_dir].directory?
|
12
|
+
case targets[0].platform.name
|
13
|
+
when :ios, :tvos, :watchos
|
14
|
+
PodPrebuild::XcodebuildCommand.new(options).run
|
15
|
+
when :osx
|
16
|
+
xcodebuild(
|
17
|
+
sandbox: options[:sandbox],
|
18
|
+
targets: targets,
|
19
|
+
configuration: options[:configuration],
|
20
|
+
sdk: "macosx",
|
21
|
+
args: options[:args]
|
22
|
+
)
|
23
|
+
else
|
24
|
+
raise "Unsupported platform for '#{targets[0].name}': '#{targets[0].platform.name}'"
|
29
25
|
end
|
26
|
+
raise "The build directory was not found in the expected location" unless options[:build_dir].directory?
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
def self.remove_build_dir(sandbox_root)
|
30
|
+
path = build_dir(sandbox_root)
|
31
|
+
path.rmtree if path.exist?
|
32
|
+
end
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
34
|
+
def self.build_dir(sandbox_root)
|
35
|
+
sandbox_root.parent + "build"
|
39
36
|
end
|
40
37
|
end
|
@@ -4,26 +4,43 @@ module Pod
|
|
4
4
|
cache = []
|
5
5
|
analysis_result.specifications
|
6
6
|
.select { |spec| should_integrate_prebuilt_pod?(spec.root.name) }
|
7
|
-
.
|
7
|
+
.group_by(&:root)
|
8
|
+
.each do |_, specs|
|
9
|
+
first_subspec_or_self = specs.find(&:subspec?) || specs[0]
|
10
|
+
specs.each do |spec|
|
11
|
+
alterations = {
|
12
|
+
:source_files => true,
|
13
|
+
:resources => true,
|
14
|
+
:license => true,
|
15
|
+
:vendored_framework => spec == first_subspec_or_self
|
16
|
+
}
|
17
|
+
alter_spec(spec, alterations, cache)
|
18
|
+
end
|
19
|
+
end
|
8
20
|
end
|
9
21
|
|
10
|
-
|
22
|
+
private
|
23
|
+
|
24
|
+
def alter_spec(spec, alterations, cache)
|
11
25
|
targets = Pod.fast_get_targets_for_pod_name(spec.root.name, pod_targets, cache)
|
12
|
-
targets.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
26
|
+
platforms = targets.map { |target| target.platform.name.to_s }.uniq
|
27
|
+
|
28
|
+
if alterations[:vendored_framework]
|
29
|
+
targets.each do |target|
|
30
|
+
# Use the prebuilt frameworks as vendered frameworks.
|
31
|
+
# The framework_file_path rule is decided in `install_for_prebuild`,
|
32
|
+
# as to compitable with older version and be less wordy.
|
33
|
+
framework_file_path = target.framework_name
|
34
|
+
framework_file_path = target.name + "/" + framework_file_path if targets.count > 1
|
35
|
+
framework_file_path = PodPrebuild.config.prebuilt_path(path: framework_file_path)
|
36
|
+
add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
|
37
|
+
end
|
20
38
|
end
|
21
39
|
|
22
|
-
platforms
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
empty_liscence(spec) # to avoid the warning of missing license
|
40
|
+
empty_source_files(spec, platforms) if alterations[:source_files]
|
41
|
+
tweak_resources_for_xib(spec, platforms) if alterations[:resources]
|
42
|
+
tweak_resources_for_resource_bundles(spec, platforms) if alterations[:resources]
|
43
|
+
empty_liscence(spec) if alterations[:license]
|
27
44
|
end
|
28
45
|
|
29
46
|
def tweak_resources_for_xib(spec, platforms)
|
@@ -17,7 +17,7 @@ module Pod
|
|
17
17
|
# If the path isn't an absolute path, we add a realtive prefix.
|
18
18
|
old_read_link=`which readlink`
|
19
19
|
readlink () {
|
20
|
-
path=`$old_read_link $1`;
|
20
|
+
path=`$old_read_link "$1"`;
|
21
21
|
if [ $(echo "$path" | cut -c 1-1) = '/' ]; then
|
22
22
|
echo $path;
|
23
23
|
else
|
@@ -3,17 +3,31 @@ require_relative "../source_installer"
|
|
3
3
|
module Pod
|
4
4
|
class Installer
|
5
5
|
# Override the download step to skip download and prepare file in target folder
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
if should_integrate_prebuilt_pod?(pod_name)
|
11
|
-
pod_installer.install_for_prebuild!(sandbox)
|
6
|
+
alias original_create_pod_installer create_pod_installer
|
7
|
+
def create_pod_installer(name)
|
8
|
+
if should_integrate_prebuilt_pod?(name)
|
9
|
+
create_prebuilt_source_installer(name)
|
12
10
|
else
|
13
|
-
|
11
|
+
create_normal_source_installer(name)
|
14
12
|
end
|
15
|
-
|
16
|
-
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def create_normal_source_installer(name)
|
18
|
+
original_create_pod_installer(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_prebuilt_source_installer(name)
|
22
|
+
source_installer = PodSourceInstaller.new(sandbox, podfile, specs_for_pod(name))
|
23
|
+
pod_installer = PrebuiltSourceInstaller.new(
|
24
|
+
sandbox,
|
25
|
+
podfile,
|
26
|
+
specs_for_pod(name),
|
27
|
+
source_installer: source_installer
|
28
|
+
)
|
29
|
+
pod_installers << pod_installer
|
30
|
+
pod_installer
|
17
31
|
end
|
18
32
|
|
19
33
|
def should_integrate_prebuilt_pod?(name)
|
@@ -1,21 +1,27 @@
|
|
1
|
-
# NOTE:
|
2
|
-
# This file will only be loaded on normal pod install step
|
3
|
-
# so there's no need to check is_prebuild_stage
|
4
|
-
|
5
|
-
# Provide a special "download" process for prebuilded pods.
|
6
|
-
#
|
7
|
-
# As the frameworks is already exsited in local folder. We
|
8
|
-
# just create a symlink to the original target folder.
|
9
|
-
#
|
10
1
|
module Pod
|
11
2
|
class Installer
|
12
|
-
class PodSourceInstaller
|
13
|
-
def
|
14
|
-
|
3
|
+
class PrebuiltSourceInstaller < PodSourceInstaller
|
4
|
+
def initialize(*args, **kwargs)
|
5
|
+
@source_installer = kwargs.delete(:source_installer)
|
6
|
+
super(*args, **kwargs)
|
7
|
+
end
|
8
|
+
|
9
|
+
def prebuild_sandbox
|
10
|
+
@prebuild_sandbox ||= Pod::PrebuildSandbox.from_standard_sandbox(sandbox)
|
11
|
+
end
|
12
|
+
|
13
|
+
def install!
|
14
|
+
@source_installer.install!
|
15
|
+
install_prebuilt_framework!
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def install_prebuilt_framework!
|
21
|
+
return if !PodPrebuild.config.dev_pods_enabled? && sandbox.local?(name)
|
15
22
|
|
16
23
|
# make a symlink to target folder
|
17
24
|
# TODO (bang): Unify to 1 sandbox to optimize and avoid inconsistency
|
18
|
-
prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(standard_sanbox)
|
19
25
|
# if spec used in multiple platforms, it may return multiple paths
|
20
26
|
target_names = prebuild_sandbox.existed_target_names_for_pod_name(name)
|
21
27
|
target_names.each do |name|
|
@@ -24,7 +30,7 @@ module Pod
|
|
24
30
|
# If have only one platform, just place int the root folder of this pod.
|
25
31
|
# If have multiple paths, we use a sperated folder to store different
|
26
32
|
# platform frameworks. e.g. AFNetworking/AFNetworking-iOS/AFNetworking.framework
|
27
|
-
target_folder =
|
33
|
+
target_folder = sandbox.pod_dir(self.name)
|
28
34
|
target_folder += real_file_folder.basename if target_names.count > 1
|
29
35
|
target_folder += PodPrebuild.config.prebuilt_path
|
30
36
|
target_folder.rmtree if target_folder.exist?
|
@@ -33,8 +39,10 @@ module Pod
|
|
33
39
|
walk(real_file_folder) do |child|
|
34
40
|
source = child
|
35
41
|
# only make symlink to file and `.framework` folder
|
36
|
-
if child.directory? && [".framework", ".dSYM"].include?(child.extname)
|
37
|
-
|
42
|
+
if child.directory? && [".framework", ".xcframework", ".dSYM"].include?(child.extname)
|
43
|
+
if [".framework", ".xcframework"].include?(child.extname)
|
44
|
+
mirror_with_symlink(source, real_file_folder, target_folder)
|
45
|
+
end
|
38
46
|
# Ignore dsym here to avoid cocoapods from adding install_dsym to buildphase-script
|
39
47
|
# That can cause duplicated output files error in Xcode 11 (warning in Xcode 10)
|
40
48
|
# We need more setup to support local debuging with prebuilt dSYM
|
@@ -52,10 +60,15 @@ module Pod
|
|
52
60
|
next unless metadata.static_framework?
|
53
61
|
|
54
62
|
metadata.resources.each do |path|
|
55
|
-
target_file_path = path
|
63
|
+
target_file_path = Pathname(path)
|
56
64
|
.sub("${PODS_ROOT}", sandbox.root.to_path)
|
57
65
|
.sub("${PODS_CONFIGURATION_BUILD_DIR}", sandbox.root.to_path)
|
66
|
+
next if target_file_path.exist?
|
67
|
+
|
58
68
|
real_file_path = real_file_folder + metadata.framework_name + File.basename(path)
|
69
|
+
|
70
|
+
# TODO (thuyen): Fix https://github.com/grab/cocoapods-binary-cache/issues/45
|
71
|
+
|
59
72
|
case File.extname(path)
|
60
73
|
when ".xib"
|
61
74
|
# https://github.com/grab/cocoapods-binary-cache/issues/7
|
@@ -73,8 +86,6 @@ module Pod
|
|
73
86
|
end
|
74
87
|
end
|
75
88
|
|
76
|
-
private
|
77
|
-
|
78
89
|
def walk(path, &action)
|
79
90
|
return unless path.exist?
|
80
91
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require "fileutils"
|
2
2
|
require_relative "../prebuild_output/output"
|
3
3
|
require_relative "../helper/lockfile"
|
4
|
-
require_relative "../helper/prebuild_order"
|
5
4
|
require_relative "helper/target_checker"
|
6
5
|
require_relative "helper/build"
|
7
6
|
|
@@ -15,6 +14,13 @@ module Pod
|
|
15
14
|
@lockfile_wrapper = lockfile && PodPrebuild::Lockfile.new(lockfile)
|
16
15
|
end
|
17
16
|
|
17
|
+
def installation_options
|
18
|
+
# Skip integrating user targets for prebuild Pods project.
|
19
|
+
@installation_options ||= Pod::Installer::InstallationOptions.new(
|
20
|
+
super.to_h.merge(:integrate_targets => false)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
18
24
|
def run_code_gen!(targets)
|
19
25
|
return if PodPrebuild.config.prebuild_code_gen.nil?
|
20
26
|
|
@@ -38,27 +44,27 @@ module Pod
|
|
38
44
|
def prebuild_frameworks!
|
39
45
|
existed_framework_folder = sandbox.generate_framework_path
|
40
46
|
sandbox_path = sandbox.root
|
47
|
+
targets = targets_to_prebuild
|
48
|
+
Pod::UI.puts "Prebuild frameworks (total #{targets.count}): #{targets.map(&:name)}".magenta
|
41
49
|
|
42
|
-
targets = PodPrebuild::BuildOrder.order_targets(targets_to_prebuild)
|
43
|
-
Pod::UI.puts "Prebuild frameworks (total #{targets.count}): #{targets.map(&:name)}"
|
44
|
-
Pod::Prebuild.remove_build_dir(sandbox_path)
|
45
50
|
run_code_gen!(targets)
|
51
|
+
|
52
|
+
PodPrebuild.remove_build_dir(sandbox_path)
|
53
|
+
PodPrebuild.build(
|
54
|
+
sandbox: sandbox_path,
|
55
|
+
targets: targets,
|
56
|
+
configuration: PodPrebuild.config.prebuild_config,
|
57
|
+
output_path: sandbox.generate_framework_path,
|
58
|
+
bitcode_enabled: PodPrebuild.config.bitcode_enabled?,
|
59
|
+
device_build_enabled: PodPrebuild.config.device_build_enabled?,
|
60
|
+
disable_dsym: PodPrebuild.config.disable_dsym?,
|
61
|
+
args: PodPrebuild.config.build_args
|
62
|
+
)
|
63
|
+
PodPrebuild.remove_build_dir(sandbox_path)
|
64
|
+
|
46
65
|
targets.each do |target|
|
47
|
-
|
48
|
-
output_path.mkpath unless output_path.exist?
|
49
|
-
Pod::Prebuild.build(
|
50
|
-
sandbox: sandbox_path,
|
51
|
-
target: target,
|
52
|
-
configuration: PodPrebuild.config.prebuild_config,
|
53
|
-
output_path: output_path,
|
54
|
-
bitcode_enabled: PodPrebuild.config.bitcode_enabled?,
|
55
|
-
device_build_enabled: PodPrebuild.config.device_build_enabled?,
|
56
|
-
disable_dsym: PodPrebuild.config.disable_dsym?,
|
57
|
-
args: PodPrebuild.config.build_args
|
58
|
-
)
|
59
|
-
collect_metadata(target, output_path)
|
66
|
+
collect_metadata(target, sandbox.framework_folder_path_for_target_name(target.name))
|
60
67
|
end
|
61
|
-
Pod::Prebuild.remove_build_dir(sandbox_path)
|
62
68
|
|
63
69
|
# copy vendored libraries and frameworks
|
64
70
|
targets.each do |target|
|
@@ -1,192 +1,252 @@
|
|
1
1
|
require_relative "xcodebuild_raw"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
3
|
+
module PodPrebuild
|
4
|
+
class XcodebuildCommand # rubocop:disable Metrics/ClassLength
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
case options[:targets][0].platform.name
|
8
|
+
when :ios
|
9
|
+
@options[:device] = "iphoneos"
|
10
|
+
@options[:simulator] = "iphonesimulator"
|
11
|
+
when :tvos
|
12
|
+
@options[:device] = "appletvos"
|
13
|
+
@options[:simulator] = "appletvsimulator"
|
14
|
+
when :watchos
|
15
|
+
@options[:device] = "watchos"
|
16
|
+
@options[:simulator] = "watchsimulator"
|
17
|
+
end
|
18
|
+
@build_args = make_up_build_args(options[:args] || {})
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
def run
|
22
|
+
sdks.each { |sdk| build_for_sdk(sdk) }
|
23
|
+
|
24
|
+
targets.each do |target|
|
25
|
+
if PodPrebuild.config.xcframework?
|
26
|
+
create_xcframework(target)
|
27
|
+
elsif sdks.count > 1
|
28
|
+
create_fat_framework(target)
|
29
|
+
else
|
30
|
+
collect_output(target, Dir[target_products_dir_of(target, sdks[0]) + "/*"])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
23
34
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
create_universal_framework
|
35
|
+
private
|
36
|
+
|
37
|
+
def sdks
|
38
|
+
@sdks ||= begin
|
39
|
+
sdks_ = []
|
40
|
+
sdks_ << simulator if build_types.include?(:simulator)
|
41
|
+
sdks_ << device if build_types.include?(:device)
|
42
|
+
sdks_
|
43
|
+
end
|
34
44
|
end
|
35
|
-
end
|
36
45
|
|
37
|
-
|
46
|
+
def build_types
|
47
|
+
@build_types ||= begin
|
48
|
+
# TODO (thuyen): Add DSL options `build_for_types` to specify build types
|
49
|
+
types = [:simulator]
|
50
|
+
types << :device if device_build_enabled?
|
51
|
+
types
|
52
|
+
end
|
53
|
+
end
|
38
54
|
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
55
|
+
def make_up_build_args(args)
|
56
|
+
# Note: The build arguments explicitly passed from config_cocoapods_binary_cache
|
57
|
+
# should be preceded by the default arguments so that they could take higher priority
|
58
|
+
# when there are argument collisions in the xcodebuild command.
|
59
|
+
# For ex. `xcodebuild AN_ARG=1 AN_ARG=2` should use `AN_ARG=2` instead.
|
60
|
+
args_ = args.clone
|
61
|
+
args_[:default] ||= []
|
62
|
+
args_[:simulator] ||= []
|
63
|
+
args_[:device] ||= []
|
64
|
+
args_[:default].prepend("BITCODE_GENERATION_MODE=bitcode") if bitcode_enabled?
|
65
|
+
args_[:default].prepend("DEBUG_INFORMATION_FORMAT=dwarf") if disable_dsym?
|
66
|
+
args_[:simulator].prepend("ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO") if simulator == "iphonesimulator"
|
67
|
+
args_[:simulator] += args_[:default]
|
68
|
+
args_[:device].prepend("ONLY_ACTIVE_ARCH=NO")
|
69
|
+
args_[:device] += args_[:default]
|
70
|
+
args_
|
45
71
|
end
|
46
|
-
end
|
47
72
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
73
|
+
def build_for_sdk(sdk)
|
74
|
+
PodPrebuild::XcodebuildCommand.xcodebuild(
|
75
|
+
sandbox: sandbox,
|
76
|
+
scheme: scheme,
|
77
|
+
targets: targets.map(&:label),
|
78
|
+
configuration: configuration,
|
79
|
+
sdk: sdk,
|
80
|
+
deployment_target: targets.map { |t| t.platform.deployment_target }.max.to_s,
|
81
|
+
args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
|
82
|
+
)
|
83
|
+
end
|
60
84
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
succeeded, = xcodebuild(
|
69
|
-
sandbox: sandbox,
|
70
|
-
target: target.label,
|
71
|
-
configuration: configuration,
|
72
|
-
sdk: sdk,
|
73
|
-
deployment_target: target.platform.deployment_target.to_s,
|
74
|
-
args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
|
75
|
-
)
|
76
|
-
raise "Build framework failed: #{target.label}" unless succeeded
|
77
|
-
end
|
85
|
+
def create_xcframework(target)
|
86
|
+
non_framework_paths = Dir[target_products_dir_of(target, sdks[0]) + "/*"] \
|
87
|
+
- [framework_path_of(target, sdks[0])] \
|
88
|
+
- dsym_paths_of(target, sdks[0]) \
|
89
|
+
- bcsymbolmap_paths_of(target, sdks[0])
|
90
|
+
collect_output(target, non_framework_paths)
|
78
91
|
|
79
|
-
|
80
|
-
|
81
|
-
merge_framework_dsym
|
82
|
-
merge_swift_headers
|
83
|
-
merge_swift_modules
|
84
|
-
end
|
92
|
+
output = "#{output_path(target)}/#{target.product_module_name}.xcframework"
|
93
|
+
FileUtils.rm_rf(output)
|
85
94
|
|
86
|
-
|
87
|
-
merge_contents("/#{module_name}", &method(:create_fat_binary))
|
88
|
-
end
|
95
|
+
cmd = ["xcodebuild", "-create-xcframework", "-allow-internal-distribution"]
|
89
96
|
|
90
|
-
|
91
|
-
|
92
|
-
|
97
|
+
# for each sdk, the order of params must be -framework then -debug-symbols
|
98
|
+
# to prevent duplicated file error when copying dSYMs
|
99
|
+
sdks.each do |sdk|
|
100
|
+
cmd << "-framework" << framework_path_of(target, sdk)
|
101
|
+
|
102
|
+
unless disable_dsym?
|
103
|
+
dsyms = dsym_paths_of(target, sdk)
|
104
|
+
cmd += dsyms.map { |dsym| "-debug-symbols #{dsym}" }
|
105
|
+
end
|
106
|
+
|
107
|
+
if bitcode_enabled?
|
108
|
+
bcsymbolmaps = bcsymbolmap_paths_of(target, sdk)
|
109
|
+
cmd += bcsymbolmaps.map { |bcsymbolmap| "-debug-symbols #{bcsymbolmap}" }
|
110
|
+
end
|
111
|
+
end
|
93
112
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
#{File.read(options[:device])}
|
101
|
-
#endif // merged by cocoapods-binary
|
102
|
-
HEREDOC
|
103
|
-
File.write(options[:output], merged_header.strip)
|
113
|
+
cmd << "-output" << output
|
114
|
+
|
115
|
+
Pod::UI.puts "- Create xcframework: #{target}".magenta
|
116
|
+
Pod::UI.puts_indented "$ #{cmd.join(' ')}" unless PodPrebuild.config.silent_build?
|
117
|
+
|
118
|
+
`#{cmd.join(" ")}`
|
104
119
|
end
|
105
|
-
end
|
106
120
|
|
107
|
-
|
108
|
-
|
109
|
-
#
|
110
|
-
|
111
|
-
|
121
|
+
def create_fat_framework(target)
|
122
|
+
# When merging contents of `simulator` & `device`, prefer contents of `device` over `simulator`
|
123
|
+
# https://github.com/grab/cocoapods-binary-cache/issues/25
|
124
|
+
collect_output(target, Dir[target_products_dir_of(target, device) + "/*"])
|
125
|
+
|
126
|
+
merge_framework_binary(target)
|
127
|
+
merge_framework_dsym(target)
|
128
|
+
merge_swift_headers(target)
|
129
|
+
merge_swift_modules(target)
|
112
130
|
end
|
113
|
-
end
|
114
131
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
framework_path_of(device),
|
119
|
-
"#{output_path}/#{module_name}.framework"
|
120
|
-
].map { |p| p + path_suffix }
|
121
|
-
return unless File.exist?(simulator_) && File.exist?(device_)
|
132
|
+
def merge_framework_binary(target)
|
133
|
+
merge_contents(target, "/#{target.product_module_name}", &method(:create_fat_binary))
|
134
|
+
end
|
122
135
|
|
123
|
-
|
124
|
-
|
136
|
+
def merge_framework_dsym(target)
|
137
|
+
merge_contents(
|
138
|
+
target,
|
139
|
+
".dSYM/Contents/Resources/DWARF/#{target.product_module_name}",
|
140
|
+
&method(:create_fat_binary)
|
141
|
+
)
|
142
|
+
end
|
125
143
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
144
|
+
def merge_swift_headers(target)
|
145
|
+
merge_contents(target, "/Headers/#{target.product_module_name}-Swift.h") do |options|
|
146
|
+
merged_header = <<~HEREDOC
|
147
|
+
#if TARGET_OS_SIMULATOR // merged by cocoapods-binary
|
148
|
+
#{File.read(options[:simulator])}
|
149
|
+
#else // merged by cocoapods-binary
|
150
|
+
#{File.read(options[:device])}
|
151
|
+
#endif // merged by cocoapods-binary
|
152
|
+
HEREDOC
|
153
|
+
File.write(options[:output], merged_header.strip)
|
154
|
+
end
|
155
|
+
end
|
132
156
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
157
|
+
def merge_swift_modules(target)
|
158
|
+
merge_contents(target, "/Modules/#{target.product_module_name}.swiftmodule") do |options|
|
159
|
+
# Note: swiftmodules of `device` were copied beforehand,
|
160
|
+
# here, we only need to copy swiftmodules of `simulator`
|
161
|
+
FileUtils.cp_r(options[:simulator] + "/.", options[:output])
|
162
|
+
end
|
138
163
|
end
|
139
|
-
end
|
140
164
|
|
141
|
-
|
142
|
-
|
143
|
-
|
165
|
+
def merge_contents(target, path_suffix, &merger)
|
166
|
+
simulator_, device_, output_ = [
|
167
|
+
framework_path_of(target, simulator),
|
168
|
+
framework_path_of(target, device),
|
169
|
+
"#{output_path(target)}/#{target.product_module_name}.framework"
|
170
|
+
].map { |p| p + path_suffix }
|
171
|
+
return unless File.exist?(simulator_) && File.exist?(device_)
|
144
172
|
|
145
|
-
|
146
|
-
|
147
|
-
end
|
173
|
+
merger.call(simulator: simulator_, device: device_, output: output_)
|
174
|
+
end
|
148
175
|
|
149
|
-
|
150
|
-
|
151
|
-
|
176
|
+
def create_fat_binary(options)
|
177
|
+
cmd = ["lipo", " -create"]
|
178
|
+
cmd << "-output" << options[:output]
|
179
|
+
cmd << options[:simulator] << options[:device]
|
180
|
+
`#{cmd.join(" ")}`
|
181
|
+
end
|
152
182
|
|
153
|
-
|
154
|
-
|
155
|
-
|
183
|
+
def collect_output(target, paths)
|
184
|
+
FileUtils.mkdir_p(output_path(target))
|
185
|
+
paths = [paths] unless paths.is_a?(Array)
|
186
|
+
paths.each do |path|
|
187
|
+
FileUtils.rm_rf(File.join(output_path(target), File.basename(path)))
|
188
|
+
FileUtils.cp_r(path, output_path(target))
|
189
|
+
end
|
190
|
+
end
|
156
191
|
|
157
|
-
|
158
|
-
|
159
|
-
|
192
|
+
def target_products_dir_of(target, sdk)
|
193
|
+
"#{build_dir}/#{configuration}-#{sdk}/#{target.name}"
|
194
|
+
end
|
160
195
|
|
161
|
-
|
162
|
-
|
163
|
-
|
196
|
+
def framework_path_of(target, sdk)
|
197
|
+
"#{target_products_dir_of(target, sdk)}/#{target.product_module_name}.framework"
|
198
|
+
end
|
164
199
|
|
165
|
-
|
166
|
-
|
167
|
-
|
200
|
+
def dsym_paths_of(target, sdk)
|
201
|
+
Dir["#{target_products_dir_of(target, sdk)}/*.dSYM"]
|
202
|
+
end
|
168
203
|
|
169
|
-
|
170
|
-
|
171
|
-
|
204
|
+
def bcsymbolmap_paths_of(target, sdk)
|
205
|
+
Dir["#{target_products_dir_of(target, sdk)}/*.bcsymbolmap"]
|
206
|
+
end
|
172
207
|
|
173
|
-
|
174
|
-
|
175
|
-
|
208
|
+
def sandbox
|
209
|
+
@options[:sandbox]
|
210
|
+
end
|
176
211
|
|
177
|
-
|
178
|
-
|
179
|
-
|
212
|
+
def build_dir
|
213
|
+
@options[:build_dir]
|
214
|
+
end
|
180
215
|
|
181
|
-
|
182
|
-
|
183
|
-
|
216
|
+
def output_path(target)
|
217
|
+
"#{@options[:output_path]}/#{target.label}"
|
218
|
+
end
|
184
219
|
|
185
|
-
|
186
|
-
|
187
|
-
|
220
|
+
def scheme
|
221
|
+
@options[:scheme]
|
222
|
+
end
|
223
|
+
|
224
|
+
def targets
|
225
|
+
@options[:targets]
|
226
|
+
end
|
227
|
+
|
228
|
+
def configuration
|
229
|
+
@options[:configuration]
|
230
|
+
end
|
231
|
+
|
232
|
+
def bitcode_enabled?
|
233
|
+
@options[:bitcode_enabled]
|
234
|
+
end
|
235
|
+
|
236
|
+
def device_build_enabled?
|
237
|
+
@options[:device_build_enabled]
|
238
|
+
end
|
239
|
+
|
240
|
+
def device
|
241
|
+
@options[:device] || "iphoneos"
|
242
|
+
end
|
243
|
+
|
244
|
+
def simulator
|
245
|
+
@options[:simulator] || "iphonesimulator"
|
246
|
+
end
|
188
247
|
|
189
|
-
|
190
|
-
|
248
|
+
def disable_dsym?
|
249
|
+
@options[:disable_dsym]
|
250
|
+
end
|
191
251
|
end
|
192
252
|
end
|