cocoapods-binary-cache 0.1.8 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|