cocoapods-jxedt 0.0.9
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 +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/lib/cocoapods-jxedt/binary/Intergation.rb +303 -0
- data/lib/cocoapods-jxedt/binary/config.rb +139 -0
- data/lib/cocoapods-jxedt/binary/helper/names.rb +78 -0
- data/lib/cocoapods-jxedt/binary/helper/podfile_options.rb +116 -0
- data/lib/cocoapods-jxedt/binary/helper/prebuild_sandbox.rb +18 -0
- data/lib/cocoapods-jxedt/binary/helper/target_definition.rb +34 -0
- data/lib/cocoapods-jxedt/binary/hooks/CocoapodsJxedtHook.rb +25 -0
- data/lib/cocoapods-jxedt/binary/hooks/post_install.rb +35 -0
- data/lib/cocoapods-jxedt/binary/hooks/pre_install.rb +61 -0
- data/lib/cocoapods-jxedt/binary/main.rb +3 -0
- data/lib/cocoapods-jxedt/binary/pod-room/xcodebuild_command.rb +265 -0
- data/lib/cocoapods-jxedt/binary/pod-room/xcodebuild_raw.rb +68 -0
- data/lib/cocoapods-jxedt/binary/podfile_dsl.rb +26 -0
- data/lib/cocoapods-jxedt/binary/prebuild.rb +210 -0
- data/lib/cocoapods-jxedt/binary/targets/pod_target.rb +103 -0
- data/lib/cocoapods-jxedt/command/header/header.rb +157 -0
- data/lib/cocoapods-jxedt/command/jxedt.rb +40 -0
- data/lib/cocoapods-jxedt/command/options/options.rb +33 -0
- data/lib/cocoapods-jxedt/command.rb +1 -0
- data/lib/cocoapods-jxedt/gem_version.rb +3 -0
- data/lib/cocoapods-jxedt/tool.rb +12 -0
- data/lib/cocoapods-jxedt.rb +1 -0
- data/lib/cocoapods_plugin.rb +3 -0
- metadata +122 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
require_relative './target_definition'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Podfile
|
5
|
+
class TargetDefinition
|
6
|
+
# Returns the names of pod targets explicitly declared as prebuilt in Podfile using `:binary => true`.
|
7
|
+
def explicit_prebuild_pod_names
|
8
|
+
names = @explicit_prebuild_pod_names || []
|
9
|
+
names += parent.explicit_prebuild_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
10
|
+
names
|
11
|
+
end
|
12
|
+
|
13
|
+
def reject_prebuild_pod_names
|
14
|
+
names = @reject_prebuild_pod_names || []
|
15
|
+
names += parent.reject_prebuild_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
16
|
+
names
|
17
|
+
end
|
18
|
+
|
19
|
+
def explicit_header_search_pod_names
|
20
|
+
names = @explicit_header_search_pod_names || []
|
21
|
+
names += parent.explicit_header_search_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
22
|
+
names
|
23
|
+
end
|
24
|
+
|
25
|
+
def reject_header_search_pod_names
|
26
|
+
names = @reject_header_search_pod_names || []
|
27
|
+
names += parent.reject_header_search_pod_names if !parent.nil? && parent.is_a?(TargetDefinition)
|
28
|
+
names
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Pod
|
35
|
+
class Installer
|
36
|
+
# Returns the names of pod targets detected as prebuilt, including
|
37
|
+
# those declared in Podfile and their dependencies
|
38
|
+
def prebuild_pod_names
|
39
|
+
prebuilt_pod_targets.map(&:name).to_set
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the pod targets detected as prebuilt, including
|
43
|
+
# those declared in Podfile and their dependencies
|
44
|
+
def prebuilt_pod_targets
|
45
|
+
@prebuilt_pod_targets ||= begin
|
46
|
+
explicit_prebuild_pod_names = aggregate_targets.flat_map { |target|
|
47
|
+
target.target_definition.explicit_prebuild_pod_names
|
48
|
+
}.uniq
|
49
|
+
|
50
|
+
reject_prebuild_pod_names = aggregate_targets.flat_map { |target|
|
51
|
+
target.target_definition.reject_prebuild_pod_names
|
52
|
+
}.uniq
|
53
|
+
|
54
|
+
available_pod_names = []
|
55
|
+
check_sandbox = Jxedt::Sandbox.from_sandbox(self.sandbox)
|
56
|
+
available_pod_names = check_sandbox.target_paths.map {|path| path.basename.to_s }
|
57
|
+
if Jxedt.config.all_binary_enabled?
|
58
|
+
explicit_prebuild_pod_names = available_pod_names
|
59
|
+
else
|
60
|
+
explicit_prebuild_pod_names = (explicit_prebuild_pod_names & available_pod_names).uniq
|
61
|
+
end
|
62
|
+
explicit_prebuild_pod_names -= reject_prebuild_pod_names
|
63
|
+
|
64
|
+
targets = pod_targets.select { |target|
|
65
|
+
explicit_prebuild_pod_names.include?(target.pod_name)
|
66
|
+
}
|
67
|
+
targets = targets.reject { |target| sandbox.local?(target.pod_name) } unless Jxedt.config.dev_pods_enabled?
|
68
|
+
targets.reject! { |target| Jxedt.config.excluded_pods.include?(target.pod_name) }
|
69
|
+
targets.map { |target| target.use_binary = true }
|
70
|
+
targets
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module Pod
|
77
|
+
class Target
|
78
|
+
attr_accessor :use_binary
|
79
|
+
|
80
|
+
def frame_header_search_paths_enable?
|
81
|
+
return false if reject_header_search_pod_names.include? self.name
|
82
|
+
return true if explicit_header_search_pod_names.include? self.name
|
83
|
+
self.use_binary && Jxedt.config.framework_header_search_enabled?
|
84
|
+
end
|
85
|
+
|
86
|
+
def explicit_header_search_pod_names
|
87
|
+
@explicit_header_search_pod_names ||= begin
|
88
|
+
target_definitions.flat_map { |target_definition|
|
89
|
+
target_definition.explicit_header_search_pod_names
|
90
|
+
}.uniq
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def reject_header_search_pod_names
|
95
|
+
@reject_header_search_pod_names ||= begin
|
96
|
+
target_definitions.flat_map { |target_definition|
|
97
|
+
target_definition.reject_header_search_pod_names
|
98
|
+
}.uniq
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
module Pod
|
105
|
+
class Lockfile
|
106
|
+
def spec_checksums_hash_key(name)
|
107
|
+
# git分支或commit依赖的组件的checksum值是用podspec文件做的hash,hash可能不变,所以有commitid时校验commitid
|
108
|
+
checkout_options = self.internal_data["CHECKOUT OPTIONS"] || {}
|
109
|
+
checksum = checkout_options[name][:commit] unless checkout_options[name].nil?
|
110
|
+
return checksum unless checksum.nil?
|
111
|
+
|
112
|
+
checksums_hash = self.internal_data["SPEC CHECKSUMS"]
|
113
|
+
return checksums_hash[name] if checksums_hash.include?("#{name}")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Pod
|
2
|
+
class PrebuildSandbox < Sandbox
|
3
|
+
# [String] standard_sandbox_path
|
4
|
+
def self.from_standard_sandbox_path(path)
|
5
|
+
prebuild_sandbox_path = Pathname.new(path).realpath
|
6
|
+
new(prebuild_sandbox_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.from_standard_sandbox(sandbox)
|
10
|
+
from_standard_sandbox_path(sandbox.root)
|
11
|
+
end
|
12
|
+
|
13
|
+
def project_path
|
14
|
+
super
|
15
|
+
# root + 'Pods.xcodeproj'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Pod
|
2
|
+
class Podfile
|
3
|
+
class TargetDefinition
|
4
|
+
def detect_prebuilt_pod(name, requirements)
|
5
|
+
options = requirements.last || {}
|
6
|
+
|
7
|
+
# prebuild
|
8
|
+
@explicit_prebuild_pod_names ||= []
|
9
|
+
@reject_prebuild_pod_names ||= []
|
10
|
+
@explicit_prebuild_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:binary]
|
11
|
+
@reject_prebuild_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options.include?(:binary) && !options[:binary]
|
12
|
+
|
13
|
+
# header search path
|
14
|
+
@explicit_header_search_pod_names ||= []
|
15
|
+
@reject_header_search_pod_names ||= []
|
16
|
+
@explicit_header_search_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options[:framework_header_search]
|
17
|
+
@reject_header_search_pod_names << Specification.root_name(name) if options.is_a?(Hash) && options.include?(:framework_header_search) && !options[:framework_header_search]
|
18
|
+
|
19
|
+
options.delete(:binary) if options.is_a?(Hash)
|
20
|
+
options.delete(:framework_header_search) if options.is_a?(Hash)
|
21
|
+
requirements.pop if options.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
# ---- patch method ----
|
25
|
+
# We want modify `store_pod` method, but it's hard to insert a line in the
|
26
|
+
# implementation. So we patch a method called in `store_pod`.
|
27
|
+
original_parse_inhibit_warnings = instance_method(:parse_inhibit_warnings)
|
28
|
+
define_method(:parse_inhibit_warnings) do |name, requirements|
|
29
|
+
detect_prebuilt_pod(name, requirements)
|
30
|
+
original_parse_inhibit_warnings.bind(self).call(name, requirements)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../helper/target_definition'
|
2
|
+
|
3
|
+
module CocoapodsJxedtHook
|
4
|
+
Pod::HooksManager.register('cocoapods-jxedt', :pre_install) do |installer_context, _|
|
5
|
+
require_relative 'pre_install'
|
6
|
+
Jxedt::PreInstall.new(installer_context).run
|
7
|
+
end
|
8
|
+
|
9
|
+
Pod::HooksManager.register('cocoapods-jxedt', :pre_integrate) do |context, _|
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
Pod::HooksManager.register('cocoapods-jxedt', :post_install) do |context, _|
|
14
|
+
require_relative 'post_install'
|
15
|
+
Jxedt::PostInstall.new(context).run
|
16
|
+
end
|
17
|
+
|
18
|
+
Pod::HooksManager.register('cocoapods-jxedt', :post_integrate) do |context, _|
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
Pod::HooksManager.register('cocoapods-jxedt', :source_provider) do |context, _|
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Jxedt
|
2
|
+
class PostInstall
|
3
|
+
def initialize(installer_context)
|
4
|
+
@installer_context = installer_context
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
# check binary switch
|
9
|
+
return unless Jxedt.config.binary_switch?
|
10
|
+
|
11
|
+
require_relative '../helper/prebuild_sandbox'
|
12
|
+
|
13
|
+
# :post_install过程校验两次`pod install`的值
|
14
|
+
validate_pod_checksum unless @installer_context.sandbox.is_a?(Pod::PrebuildSandbox)
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_pod_checksum
|
18
|
+
original_installer = ObjectSpace.each_object(Pod::Installer).reject {|installer| installer.sandbox.is_a?(Pod::PrebuildSandbox) }.first
|
19
|
+
return if original_installer.nil?
|
20
|
+
|
21
|
+
check_result = original_installer.lockfile == @installer_context.sandbox.source_lockfile
|
22
|
+
unless check_result
|
23
|
+
validation_failed = []
|
24
|
+
lockfile = original_installer.lockfile
|
25
|
+
source_lockfile = @installer_context.sandbox.source_lockfile
|
26
|
+
lockfile.internal_data["SPEC CHECKSUMS"].each_key { |name|
|
27
|
+
value1 = lockfile.spec_checksums_hash_key(name)
|
28
|
+
value2 = source_lockfile.spec_checksums_hash_key(name)
|
29
|
+
validation_failed << name if value1.nil? || value2.nil? || value1 != value2
|
30
|
+
}
|
31
|
+
Pod::UI.warn "Lockfile文件校验失败,请检查Pod组件: #{validation_failed}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Pod
|
2
|
+
class Sandbox
|
3
|
+
attr_accessor :source_lockfile
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
module Jxedt
|
8
|
+
class PreInstall
|
9
|
+
include ObjectSpace
|
10
|
+
|
11
|
+
def initialize(installer_context)
|
12
|
+
@installer_context = installer_context
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
# check binary switch
|
17
|
+
return unless Jxedt.config.binary_switch?
|
18
|
+
|
19
|
+
# [Check Environment]
|
20
|
+
podfile = @installer_context.podfile
|
21
|
+
podfile.target_definition_list.each do |target_definition|
|
22
|
+
raise STDERR.puts "[!] Cocoapods-binary requires `use_frameworks!`".red if not target_definition.uses_frameworks?
|
23
|
+
end
|
24
|
+
|
25
|
+
require_relative '../helper/prebuild_sandbox'
|
26
|
+
|
27
|
+
# 如果是Pod::PrebuildSandbox类则直接返回
|
28
|
+
return if @installer_context.sandbox.is_a?(Pod::PrebuildSandbox)
|
29
|
+
|
30
|
+
# 获取原始的installer对象,必须先获取对象
|
31
|
+
original_installer = ObjectSpace.each_object(Pod::Installer).first
|
32
|
+
sandbox = Pod::PrebuildSandbox.from_standard_sandbox(@installer_context.sandbox)
|
33
|
+
source_installer = Pod::Installer.new(sandbox, @installer_context.podfile, @installer_context.lockfile)
|
34
|
+
# 设置原始的installer携带的参数
|
35
|
+
source_installer.update = original_installer.update
|
36
|
+
source_installer.repo_update = original_installer.repo_update
|
37
|
+
# 执行install
|
38
|
+
source_installer.install!
|
39
|
+
|
40
|
+
# 保存首次`pod install`的lockfile结果,用来验证二进制文件和后面做结果校验
|
41
|
+
@installer_context.sandbox.source_lockfile = sandbox.source_lockfile = source_installer.lockfile
|
42
|
+
|
43
|
+
require_relative '../helper/podfile_options'
|
44
|
+
require_relative '../prebuild'
|
45
|
+
|
46
|
+
# prebuild_job
|
47
|
+
log_section "🚀 Prebuild frameworks" if Jxedt.config.prebuild_job?
|
48
|
+
Jxedt::Prebuild.new(source_installer).build if Jxedt.config.prebuild_job?
|
49
|
+
|
50
|
+
log_section "🤖 Resume pod installation"
|
51
|
+
require_relative '../targets/pod_target'
|
52
|
+
require_relative '../Intergation'
|
53
|
+
end
|
54
|
+
|
55
|
+
def log_section(message)
|
56
|
+
Pod::UI.puts "-----------------------------------------"
|
57
|
+
Pod::UI.puts message
|
58
|
+
Pod::UI.puts "-----------------------------------------"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
require_relative "xcodebuild_raw"
|
2
|
+
|
3
|
+
module Jxedt
|
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
|
20
|
+
|
21
|
+
def run
|
22
|
+
sdks.each { |sdk| build_for_sdk(sdk) }
|
23
|
+
|
24
|
+
targets.each do |target|
|
25
|
+
if Jxedt.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
|
34
|
+
|
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
|
44
|
+
end
|
45
|
+
|
46
|
+
def preferred_sdk
|
47
|
+
@preferred_sdk ||= sdks.include?(device) ? device : sdks[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
def build_types
|
51
|
+
@build_types ||= begin
|
52
|
+
types = []
|
53
|
+
types << :simulator if simulator_build_enabled?
|
54
|
+
types << :device if device_build_enabled?
|
55
|
+
types
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def make_up_build_args(args)
|
60
|
+
# Note: The build arguments explicitly passed from config_cocoapods_binary_cache
|
61
|
+
# should be preceded by the default arguments so that they could take higher priority
|
62
|
+
# when there are argument collisions in the xcodebuild command.
|
63
|
+
# For ex. `xcodebuild AN_ARG=1 AN_ARG=2` should use `AN_ARG=2` instead.
|
64
|
+
args_ = args.clone
|
65
|
+
args_[:default] ||= []
|
66
|
+
args_[:simulator] ||= []
|
67
|
+
args_[:device] ||= []
|
68
|
+
args_[:default].prepend("BITCODE_GENERATION_MODE=bitcode") if bitcode_enabled?
|
69
|
+
args_[:default].prepend("DEBUG_INFORMATION_FORMAT=dwarf") if disable_dsym?
|
70
|
+
# args_[:simulator].prepend("ARCHS=x86_64", "ONLY_ACTIVE_ARCH=NO") if simulator == "iphonesimulator"
|
71
|
+
# args_[:device].prepend("ONLY_ACTIVE_ARCH=NO")
|
72
|
+
args_[:simulator] += args_[:default]
|
73
|
+
args_[:device] += args_[:default]
|
74
|
+
args_
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_for_sdk(sdk)
|
78
|
+
Jxedt::XcodebuildCommand.xcodebuild(
|
79
|
+
sandbox: sandbox,
|
80
|
+
scheme: scheme,
|
81
|
+
targets: targets.map(&:label),
|
82
|
+
configuration: configuration,
|
83
|
+
sdk: sdk,
|
84
|
+
deployment_target: targets.map { |t| t.platform.deployment_target }.max.to_s,
|
85
|
+
log_path: log_path(sdk),
|
86
|
+
args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_xcframework(target)
|
91
|
+
non_framework_paths = Dir[target_products_dir_of(target, preferred_sdk) + "/*"] \
|
92
|
+
- [framework_path_of(target, preferred_sdk)] \
|
93
|
+
- dsym_paths_of(target, preferred_sdk) \
|
94
|
+
- bcsymbolmap_paths_of(target, preferred_sdk)
|
95
|
+
collect_output(target, non_framework_paths)
|
96
|
+
|
97
|
+
output = "#{output_path(target)}/#{target.product_module_name}.xcframework"
|
98
|
+
FileUtils.rm_rf(output)
|
99
|
+
|
100
|
+
cmd = ["xcodebuild", "-create-xcframework", "-allow-internal-distribution"]
|
101
|
+
|
102
|
+
# for each sdk, the order of params must be -framework then -debug-symbols
|
103
|
+
# to prevent duplicated file error when copying dSYMs
|
104
|
+
sdks.each do |sdk|
|
105
|
+
cmd << "-framework" << framework_path_of(target, sdk).shellescape
|
106
|
+
|
107
|
+
unless disable_dsym?
|
108
|
+
dsyms = dsym_paths_of(target, sdk)
|
109
|
+
cmd += dsyms.map { |dsym| "-debug-symbols #{dsym.shellescape}" }
|
110
|
+
end
|
111
|
+
|
112
|
+
if bitcode_enabled?
|
113
|
+
bcsymbolmaps = bcsymbolmap_paths_of(target, sdk)
|
114
|
+
cmd += bcsymbolmaps.map { |bcsymbolmap| "-debug-symbols #{bcsymbolmap.shellescape}" }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
cmd << "-output" << output
|
119
|
+
|
120
|
+
Pod::UI.puts "- Create xcframework: #{target}".magenta unless Jxedt.config.silent_build?
|
121
|
+
Pod::UI.puts_indented "$ #{cmd.join(' ')}" unless Jxedt.config.silent_build?
|
122
|
+
|
123
|
+
`#{cmd.join(" ")}`
|
124
|
+
end
|
125
|
+
|
126
|
+
def create_fat_framework(target)
|
127
|
+
# When merging contents of `simulator` & `device`, prefer contents of `device` over `simulator`
|
128
|
+
# https://github.com/grab/cocoapods-binary-cache/issues/25
|
129
|
+
collect_output(target, Dir[target_products_dir_of(target, device) + "/*"])
|
130
|
+
|
131
|
+
merge_framework_binary(target)
|
132
|
+
merge_framework_dsym(target)
|
133
|
+
merge_swift_headers(target)
|
134
|
+
merge_swift_modules(target)
|
135
|
+
end
|
136
|
+
|
137
|
+
def merge_framework_binary(target)
|
138
|
+
merge_contents(target, "/#{target.product_module_name}", &method(:create_fat_binary))
|
139
|
+
end
|
140
|
+
|
141
|
+
def merge_framework_dsym(target)
|
142
|
+
merge_contents(
|
143
|
+
target,
|
144
|
+
".dSYM/Contents/Resources/DWARF/#{target.product_module_name}",
|
145
|
+
&method(:create_fat_binary)
|
146
|
+
)
|
147
|
+
end
|
148
|
+
|
149
|
+
def merge_swift_headers(target)
|
150
|
+
merge_contents(target, "/Headers/#{target.product_module_name}-Swift.h") do |options|
|
151
|
+
merged_header = <<~HEREDOC
|
152
|
+
#if TARGET_OS_SIMULATOR // merged by cocoapods-binary
|
153
|
+
#{File.read(options[:simulator])}
|
154
|
+
#else // merged by cocoapods-binary
|
155
|
+
#{File.read(options[:device])}
|
156
|
+
#endif // merged by cocoapods-binary
|
157
|
+
HEREDOC
|
158
|
+
File.write(options[:output], merged_header.strip)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def merge_swift_modules(target)
|
163
|
+
merge_contents(target, "/Modules/#{target.product_module_name}.swiftmodule") do |options|
|
164
|
+
# Note: swiftmodules of `device` were copied beforehand,
|
165
|
+
# here, we only need to copy swiftmodules of `simulator`
|
166
|
+
FileUtils.cp_r(options[:simulator] + "/.", options[:output])
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def merge_contents(target, path_suffix, &merger)
|
171
|
+
simulator_, device_, output_ = [
|
172
|
+
framework_path_of(target, simulator),
|
173
|
+
framework_path_of(target, device),
|
174
|
+
"#{output_path(target)}/#{target.product_module_name}.framework"
|
175
|
+
].map { |p| p + path_suffix }
|
176
|
+
return unless File.exist?(simulator_) && File.exist?(device_)
|
177
|
+
|
178
|
+
merger.call(simulator: simulator_, device: device_, output: output_)
|
179
|
+
end
|
180
|
+
|
181
|
+
def create_fat_binary(options)
|
182
|
+
cmd = ["lipo", " -create"]
|
183
|
+
cmd << "-output" << options[:output]
|
184
|
+
cmd << options[:simulator].shellescape << options[:device].shellescape
|
185
|
+
`#{cmd.join(" ")}`
|
186
|
+
end
|
187
|
+
|
188
|
+
def collect_output(target, paths)
|
189
|
+
FileUtils.mkdir_p(output_path(target))
|
190
|
+
paths = [paths] unless paths.is_a?(Array)
|
191
|
+
paths.each do |path|
|
192
|
+
FileUtils.rm_rf(File.join(output_path(target), File.basename(path)))
|
193
|
+
FileUtils.cp_r(path, output_path(target))
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def target_products_dir_of(target, sdk)
|
198
|
+
"#{build_dir}/#{configuration}-#{sdk}/#{target.name}"
|
199
|
+
end
|
200
|
+
|
201
|
+
def framework_path_of(target, sdk)
|
202
|
+
"#{target_products_dir_of(target, sdk)}/#{target.product_module_name}.framework"
|
203
|
+
end
|
204
|
+
|
205
|
+
def dsym_paths_of(target, sdk)
|
206
|
+
Dir["#{target_products_dir_of(target, sdk)}/*.dSYM"]
|
207
|
+
end
|
208
|
+
|
209
|
+
def bcsymbolmap_paths_of(target, sdk)
|
210
|
+
Dir["#{target_products_dir_of(target, sdk)}/*.bcsymbolmap"]
|
211
|
+
end
|
212
|
+
|
213
|
+
def sandbox
|
214
|
+
@options[:sandbox]
|
215
|
+
end
|
216
|
+
|
217
|
+
def build_dir
|
218
|
+
@options[:build_dir]
|
219
|
+
end
|
220
|
+
|
221
|
+
def output_path(target)
|
222
|
+
"#{@options[:output_path]}/#{target.label}"
|
223
|
+
end
|
224
|
+
|
225
|
+
def scheme
|
226
|
+
@options[:scheme]
|
227
|
+
end
|
228
|
+
|
229
|
+
def targets
|
230
|
+
@options[:targets]
|
231
|
+
end
|
232
|
+
|
233
|
+
def configuration
|
234
|
+
@options[:configuration] || "Release"
|
235
|
+
end
|
236
|
+
|
237
|
+
def bitcode_enabled?
|
238
|
+
@options[:bitcode_enabled]
|
239
|
+
end
|
240
|
+
|
241
|
+
def device_build_enabled?
|
242
|
+
@options[:device_build_enabled] || @options[:device_build_enabled].nil?
|
243
|
+
end
|
244
|
+
|
245
|
+
def simulator_build_enabled?
|
246
|
+
@options[:simulator_build_enabled] || false
|
247
|
+
end
|
248
|
+
|
249
|
+
def device
|
250
|
+
@options[:device] || "iphoneos"
|
251
|
+
end
|
252
|
+
|
253
|
+
def simulator
|
254
|
+
@options[:simulator] || "iphonesimulator"
|
255
|
+
end
|
256
|
+
|
257
|
+
def disable_dsym?
|
258
|
+
@options[:disable_dsym]
|
259
|
+
end
|
260
|
+
|
261
|
+
def log_path(sdk)
|
262
|
+
@options[:log_path].nil? ? nil : "#{@options[:log_path]}_#{sdk}"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "fourflusher"
|
2
|
+
|
3
|
+
module Jxedt
|
4
|
+
class XcodebuildCommand
|
5
|
+
PLATFORM_OF_SDK = {
|
6
|
+
"iphonesimulator" => "iOS",
|
7
|
+
"iphoneos" => "iOS",
|
8
|
+
"appletvsimulator" => "tvOS",
|
9
|
+
"appletvos" => "tvOS",
|
10
|
+
"watchsimulator" => "watchOS",
|
11
|
+
"watchos" => "watchOS"
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
DESTINATION_OF_SDK = {
|
15
|
+
"iphoneos" => "\"generic/platform=iOS\"",
|
16
|
+
"iphonesimulator" => "\"generic/platform=iOS Simulator\""
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def self.xcodebuild(options)
|
20
|
+
sdk = options[:sdk] || "iphoneos"
|
21
|
+
targets = options[:targets] || [options[:target]]
|
22
|
+
platform = PLATFORM_OF_SDK[sdk]
|
23
|
+
|
24
|
+
cmd = ["xcodebuild"]
|
25
|
+
cmd << "-project" << options[:sandbox].project_path.realdirpath.shellescape
|
26
|
+
targets.each { |target| cmd << "-target" << target }
|
27
|
+
cmd << "-configuration" << options[:configuration].shellescape
|
28
|
+
cmd << "-sdk" << sdk
|
29
|
+
if DESTINATION_OF_SDK.key?(sdk)
|
30
|
+
cmd << "-destination" << DESTINATION_OF_SDK[sdk]
|
31
|
+
else
|
32
|
+
unless platform.nil?
|
33
|
+
cmd << Fourflusher::SimControl.new.destination(:oldest, platform, options[:deployment_target])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
cmd += options[:args] if options[:args]
|
37
|
+
cmd += "clean" if options[:clean_build]
|
38
|
+
cmd << "build"
|
39
|
+
|
40
|
+
if options[:log_path].nil?
|
41
|
+
cmd << "2>&1"
|
42
|
+
else
|
43
|
+
FileUtils.mkdir_p(File.dirname(options[:log_path]))
|
44
|
+
cmd << "> #{options[:log_path].shellescape}"
|
45
|
+
end
|
46
|
+
cmd = cmd.join(" ")
|
47
|
+
|
48
|
+
Pod::UI.puts_indented "$ #{cmd}" unless Jxedt.config.silent_build?
|
49
|
+
|
50
|
+
log = `#{cmd}`
|
51
|
+
return if $?.exitstatus.zero? # rubocop:disable Style/SpecialGlobalVars
|
52
|
+
|
53
|
+
begin
|
54
|
+
require "xcpretty" # TODO (thuyen): Revise this dependency
|
55
|
+
# use xcpretty to print build log
|
56
|
+
# 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/
|
57
|
+
printer = XCPretty::Printer.new({:formatter => XCPretty::Simple, :colorize => "auto"})
|
58
|
+
log.each_line do |line|
|
59
|
+
printer.pretty_print(line)
|
60
|
+
end
|
61
|
+
rescue
|
62
|
+
Pod::UI.puts log.red
|
63
|
+
ensure
|
64
|
+
raise "Fail to build targets: #{targets}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Pod
|
2
|
+
class Podfile
|
3
|
+
module DSL
|
4
|
+
def all_binary!
|
5
|
+
Jxedt.config.dsl_config.merge!({'all_binary': true})
|
6
|
+
end
|
7
|
+
|
8
|
+
def binary_dir(dir=nil)
|
9
|
+
Jxedt.config.dsl_config.merge!({'binary_dir': dir})
|
10
|
+
end
|
11
|
+
|
12
|
+
def binary_switch(enabled=true)
|
13
|
+
Jxedt.config.dsl_config.merge!({'binary_switch': enabled})
|
14
|
+
end
|
15
|
+
|
16
|
+
def framework_header_search_enabled!
|
17
|
+
Jxedt.config.dsl_config.merge!({'framework_header_search_enabled': true})
|
18
|
+
end
|
19
|
+
|
20
|
+
def cocoapods_jxedt_config(options)
|
21
|
+
Jxedt.config.dsl_config.merge!(options)
|
22
|
+
Jxedt.config.validate_dsl_config
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|