cocoapods-jxedt 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|