cocoapods-jxedt 0.0.10 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cocoapods-jxedt/binary/Intergation.rb +18 -13
  3. data/lib/cocoapods-jxedt/binary/config.rb +67 -0
  4. data/lib/cocoapods-jxedt/binary/helper/podfile_post_install_hook.rb +29 -0
  5. data/lib/cocoapods-jxedt/binary/helper/prebuild_sandbox.rb +112 -2
  6. data/lib/cocoapods-jxedt/binary/hooks/CocoapodsJxedtHook.rb +6 -9
  7. data/lib/cocoapods-jxedt/binary/hooks/post_install.rb +2 -2
  8. data/lib/cocoapods-jxedt/binary/hooks/pre_install.rb +33 -9
  9. data/lib/cocoapods-jxedt/binary/main.rb +1 -0
  10. data/lib/cocoapods-jxedt/binary/pod-room/framework.rb +40 -0
  11. data/lib/cocoapods-jxedt/binary/pod-room/xcodebuild_command.rb +79 -1
  12. data/lib/cocoapods-jxedt/binary/pod-room/xcodebuild_raw.rb +1 -1
  13. data/lib/cocoapods-jxedt/binary/prebuild.rb +92 -14
  14. data/lib/cocoapods-jxedt/binary/targets/pod_target.rb +50 -0
  15. data/lib/cocoapods-jxedt/command/binary/binary.rb +36 -0
  16. data/lib/cocoapods-jxedt/command/binary/command/build.rb +84 -0
  17. data/lib/cocoapods-jxedt/command/binary/command/clean.rb +101 -0
  18. data/lib/cocoapods-jxedt/command/binary/command/fetch.rb +36 -0
  19. data/lib/cocoapods-jxedt/command/binary/command/push.rb +41 -0
  20. data/lib/cocoapods-jxedt/command/binary/command/statistics.rb +104 -0
  21. data/lib/cocoapods-jxedt/command/jxedt.rb +1 -1
  22. data/lib/cocoapods-jxedt/command/options/options.rb +85 -2
  23. data/lib/cocoapods-jxedt/gem_version.rb +1 -1
  24. data/lib/cocoapods-jxedt/git_helper/cache_fetcher.rb +34 -0
  25. data/lib/cocoapods-jxedt/git_helper/cache_pucher.rb +42 -0
  26. data/lib/cocoapods-jxedt/git_helper/git_command.rb +48 -0
  27. data/lib/cocoapods-jxedt/git_helper/zip.rb +22 -0
  28. metadata +14 -3
  29. data/lib/cocoapods-jxedt/command/statistics/statistics.rb +0 -98
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 777002b95ef4f80296a0e6289a5a90ad04c2f71e49d2e647fd21e145c872b871
4
- data.tar.gz: 0dc4fee30c433a0e07c89c114c61e9f2355746618fd3cf2055f011e9e767b4b4
3
+ metadata.gz: ce0b5536dca75bc86d6f3abb3769eb01f71c234d0c2297797c58c08c23d0708d
4
+ data.tar.gz: 3d35dbe1026d3e87251d35dab948d1b9f7ec8d2029b72c12a3689021d476fab8
5
5
  SHA512:
6
- metadata.gz: 239b4f5621619a359f42159c0d14bad1402e75b56862af836ae297b6ff88667b0bf8fc6b2bbdc5a1f65d31fade8b04895de910f2d50c99e2ba7f03f19e12ce14
7
- data.tar.gz: 198b0e23d430d4788b3fe14cee2562041b8323ac9ad68ac12b215613a9ea443caa6c427e6d49f51fb539687f81c2e0caab8de2290362227ab268de8e34ea0472
6
+ metadata.gz: 273c9150c1d416861cb7d3e3722a440c5d3a52910cfcafbae3620f824ad7fae09834ff686b1925bfd02baccbbc0405cabd89f51a8484bbcc917771528c994cf5
7
+ data.tar.gz: 5393135f03f3443ee623fd56df1a4411c62d83f5cc2f4d8de5f67f687c9da3cfb6e6ccd45bd9e73fd38045c80fbd9e08fbed10555eafbc4586ad671be2f57be9
@@ -138,7 +138,7 @@ module Pod
138
138
  specs = self.analysis_result.specifications
139
139
  prebuilt_specs = (specs.select do |spec|
140
140
  # rmtree
141
- target_prebuild_files = self.sandbox.root + spec.root.name + "_Prebuild"
141
+ target_prebuild_files = self.sandbox.pod_dir(spec.name) + "_Prebuild"
142
142
  target_prebuild_files.rmtree if target_prebuild_files.exist?
143
143
 
144
144
  self.prebuild_pod_names.include? spec.root.name
@@ -149,18 +149,6 @@ module Pod
149
149
  checked_specs[spec.root.name] = [] if checked_specs[spec.root.name].nil?
150
150
  checked_specs[spec.root.name] << spec
151
151
 
152
- # Use the prebuild framworks as vendered frameworks
153
- # get_corresponding_targets
154
- targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
155
- targets.each do |target|
156
- # the framework_file_path rule is decided when `install_for_prebuild`,
157
- # as to compitable with older version and be less wordy.
158
- check_sandbox.prebuild_vendored_frameworks(spec.root.name).each do |frame_file_path|
159
- framework_file_path = "_Prebuild/" + frame_file_path
160
- framework_file_path = nil if checked_specs[spec.root.name].size > 1 # spec.root.name相同的只添加一次framework文件
161
- add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
162
- end
163
- end
164
152
  # Clean the source files
165
153
  # we just add the prebuilt framework to specific platform and set no source files
166
154
  # for all platform, so it doesn't support the sence that 'a pod perbuild for one
@@ -186,8 +174,25 @@ module Pod
186
174
  spec.attributes_hash["resources"] += prebuild_bundles
187
175
  end
188
176
 
177
+ # Use the prebuild framworks as vendered frameworks
178
+ # get_corresponding_targets
179
+ targets = Pod.fast_get_targets_for_pod_name(spec.root.name, self.pod_targets, cache)
180
+ targets.each do |target|
181
+ # the framework_file_path rule is decided when `install_for_prebuild`,
182
+ # as to compitable with older version and be less wordy.
183
+ check_sandbox.prebuild_vendored_frameworks(spec.root.name).each do |frame_file_path|
184
+ framework_file_path = "_Prebuild/" + frame_file_path
185
+ framework_file_path = nil if checked_specs[spec.root.name].size > 1 # spec.root.name相同的只添加一次framework文件
186
+ add_vendered_framework(spec, target.platform.name.to_s, framework_file_path)
187
+ end
188
+
189
+ # clear resource when target is a dynamic framework
190
+ spec.attributes_hash["resources"] = [] if target.build_as_dynamic_framework?
191
+ end
192
+
189
193
  # to avoid the warning of missing license
190
194
  spec.attributes_hash["license"] = {}
195
+ # keep all file in pods
191
196
  spec.attributes_hash["preserve_paths"] = "**/*"
192
197
 
193
198
  end
@@ -11,6 +11,7 @@ module Jxedt
11
11
  :binary_dir => "framework的保存路径,相对于'Pods/Pods.xcodeproj'的相对路径。默认为'../_Prebuild'",
12
12
  :binary_switch => "二进制开关,关闭则不hook pre_install过程。默认为true",
13
13
  :prebuild_job => "开启编译任务,设置为false则不触发编译。默认为true",
14
+ :keep_source_project => "保留源码的pods工程,默认保留,方便查看源码",
14
15
  :dev_pods_enabled => "Development Pods是否支持binary。默认为false",
15
16
  :excluded_pods => "排除binary的pods",
16
17
  :xcconfig_configuration_alias => "xcconfig文件中configuration的别名,configurations设置为多个值的时候会用到,用于搜索替换。一般不需要设置,有默认值为'cocoapods-jxedt-binary'",
@@ -23,12 +24,22 @@ module Jxedt
23
24
  :device_build_enabled => "编译真机。默认true",
24
25
  :simulator_build_enabled => "编译模拟器。默认false",
25
26
  :disable_dsym => "禁止编译dsym产物。默认true",
27
+ :disable_resource_compilable_pods => "禁止编译有需要编译的resource文件(xib、xcdatamodeld等)的pod",
26
28
  :build_log_path => "编译的log输出路径",
27
29
  :build_args => "编译的配置。了解xcodebuild命令的可以配置编译参数,例如配置 ARCHS='arm64 armv7'",
30
+ :git_cache => 'git缓存配置,A Hash. 详情查看 GIT_CACHE_CONFIG'
28
31
  }.freeze
29
32
 
33
+ GIT_CACHE_CONFIG = {
34
+ :repo => '配置缓存仓库地址,如:{:remote => "https://github.com/user/cocoapods-cache.git", :local => "~/.cocoapods-jxedt/cocoapods-cache"},或者直接写远程仓库地址"https://github.com/user/cocoapods-cache.git"',
35
+ :branch => 'git cache的branch,默认是master分支',
36
+ :auto_fetch => 'pod install过程是否自动拉取远程的二进制,默认true',
37
+ :auto_push => 'pod install过程是否自动同步二进制结果到远程仓库,默认false',
38
+ }.freeze
39
+
30
40
  def initialize()
31
41
  @dsl_config = {}
42
+ @git_config = {}
32
43
  end
33
44
 
34
45
  def self.instance
@@ -59,6 +70,10 @@ module Jxedt
59
70
  @dsl_config[:prebuild_job] || @dsl_config[:prebuild_job].nil?
60
71
  end
61
72
 
73
+ def keep_source_project?
74
+ @dsl_config[:keep_source_project] || false
75
+ end
76
+
62
77
  def dev_pods_enabled?
63
78
  @dsl_config[:dev_pods_enabled] || false
64
79
  end
@@ -103,6 +118,10 @@ module Jxedt
103
118
  @dsl_config[:disable_dsym] || @dsl_config[:disable_dsym].nil?
104
119
  end
105
120
 
121
+ def disable_resource_compilable_pods?
122
+ @dsl_config[:disable_resource_compilable_pods] || false
123
+ end
124
+
106
125
  def device_build_enabled?
107
126
  @dsl_config[:device_build_enabled] || @dsl_config[:device_build_enabled].nil?
108
127
  end
@@ -135,5 +154,53 @@ module Jxedt
135
154
  configurations
136
155
  end
137
156
  end
157
+
158
+ # git配置 ======================================= git配置
159
+ def git_cache_config
160
+ @git_cache ||= @dsl_config[:git_cache] || {}
161
+ end
162
+
163
+ def cache_repo
164
+ @cache_repo ||= begin
165
+ cache_repo = {}
166
+ user_config = git_cache_config[:repo]
167
+ cache_repo[:remote] = user_config if user_config.is_a?(String)
168
+ cache_repo.merge!(user_config) if user_config.is_a?(Hash)
169
+ cache_repo
170
+ end
171
+ end
172
+
173
+ def git_remote_repo
174
+ @remote ||= cache_repo[:remote]
175
+ end
176
+
177
+ def cache_repo_enabled?
178
+ remote = git_remote_repo
179
+ remote && remote.is_a?(String) && remote =~ /.*\.git$/
180
+ end
181
+
182
+ def git_cache_path
183
+ return nil unless cache_repo_enabled?
184
+
185
+ local = cache_repo[:local]
186
+ return File.expand_path(local) if local && local.is_a?(String) && local.split('/').size > 1
187
+
188
+ remote = git_remote_repo
189
+ repo_name = Pathname.new(remote).basename.sub_ext('').to_s
190
+ File.expand_path("~/.cocoapods-jxedt/#{repo_name}")
191
+ end
192
+
193
+ def auto_fetch?
194
+ git_cache_config[:auto_fetch] || git_cache_config[:auto_fetch].nil?
195
+ end
196
+
197
+ def auto_push?
198
+ git_cache_config[:auto_push]
199
+ end
200
+
201
+ def cache_branch
202
+ git_cache_config[:branch] || 'master'
203
+ end
204
+ # git配置 ======================================= git配置
138
205
  end
139
206
  end
@@ -0,0 +1,29 @@
1
+ module Pod
2
+ class Podfile
3
+ if Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
4
+ # Calls the post install callback if defined.
5
+ #
6
+ # @param [Pod::Installer] installer
7
+ # the installer that is performing the installation.
8
+ #
9
+ # @return [Bool] whether a post install callback was specified and it was
10
+ # called.
11
+ #
12
+ # This allows the user to customize, for instance, the generated Xcode project _before_ it’s written to disk.
13
+ alias_method :old_post_install!, :post_install!
14
+ def post_install!(installer)
15
+ executed = old_post_install!(installer)
16
+ handle_pods_project_configurations!(installer) unless executed
17
+ executed
18
+ end
19
+
20
+ def handle_pods_project_configurations!(installer)
21
+ installer.pods_project.targets.each do |target|
22
+ target.build_configurations.each do |config|
23
+ config.build_settings["CODE_SIGN_IDENTITY"] = "" if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,4 +1,46 @@
1
1
  module Pod
2
+ # The sandbox provides support for the directory that CocoaPods uses for an
3
+ # installation. In this directory the Pods projects, the support files and
4
+ # the sources of the Pods are stored.
5
+ #
6
+ # CocoaPods assumes to have control of the sandbox.
7
+ #
8
+ # Once completed the sandbox will have the following file structure:
9
+ #
10
+ # Pods
11
+ # |
12
+ # +-- Headers
13
+ # | +-- Private
14
+ # | | +-- [Pod Name]
15
+ # | +-- Public
16
+ # | +-- [Pod Name]
17
+ # |
18
+ # +-- Local Podspecs
19
+ # | +-- External Sources
20
+ # | +-- Normal Sources
21
+ # |
22
+ # +-- Target Support Files
23
+ # | +-- [Target Name]
24
+ # | +-- Pods-acknowledgements.markdown
25
+ # | +-- Pods-acknowledgements.plist
26
+ # | +-- Pods-dummy.m
27
+ # | +-- Pods-prefix.pch
28
+ # | +-- Pods.xcconfig
29
+ # |
30
+ # +-- [Pod Name]
31
+ # |
32
+ # +-- Manifest.lock
33
+ # |
34
+ # +-- Pods.xcodeproj
35
+ # (if installation option 'generate_multiple_pod_projects' is enabled)
36
+ # |
37
+ # +-- PodTarget1.xcodeproj
38
+ # |
39
+ # ...
40
+ # |
41
+ # +-- PodTargetN.xcodeproj
42
+ #
43
+ #
2
44
  class PrebuildSandbox < Sandbox
3
45
  # [String] standard_sandbox_path
4
46
  def self.from_standard_sandbox_path(path)
@@ -10,9 +52,77 @@ module Pod
10
52
  from_standard_sandbox_path(sandbox.root)
11
53
  end
12
54
 
55
+ def make_source_link(source, target)
56
+ source = Pathname.new(source)
57
+ target = Pathname.new(target)
58
+ target.parent.mkpath unless target.parent.exist?
59
+ target.rmtree if target.exist?
60
+ relative_source = source.relative_path_from(target.parent)
61
+ FileUtils.ln_sf(relative_source, target)
62
+ end
63
+
64
+ def source_path
65
+ '../Pods-Source'
66
+ end
67
+
68
+ def headers_root
69
+ root + source_path + 'Headers'
70
+ end
71
+
13
72
  def project_path
14
- super
15
- # root + 'Pods.xcodeproj'
73
+ root + source_path + 'Pods-Source.xcodeproj'
74
+ end
75
+
76
+ def specifications_root
77
+ # root + source_path + 'Local Podspecs'
78
+ super
79
+ end
80
+
81
+ def target_support_files_root
82
+ root + source_path + 'Target Support Files'
83
+ end
84
+
85
+ def link_source_project!
86
+ root.children.each do |child|
87
+ next if ['Headers', 'Local Podspecs', 'Target Support Files'].include? child.basename.to_s
88
+ next if ['.lock', '.xcodeproj'].include? child.extname.to_s
89
+ make_source_link(child, root + source_path + child.basename)
90
+ end
91
+ end
92
+
93
+ def clean_source_project!
94
+ return if Jxedt.config.keep_source_project?
95
+
96
+ source_project_path = root + source_path
97
+ source_project_path.rmtree if source_project_path.exist?
98
+ end
99
+ end
100
+ end
101
+
102
+ module Pod
103
+ class Installer
104
+ # The {UserProjectIntegrator} integrates the libraries generated by
105
+ # TargetDefinitions of the {Podfile} with their correspondent user
106
+ # projects.
107
+ #
108
+ class UserProjectIntegrator
109
+ alias_method :old_create_workspace, :create_workspace
110
+ def create_workspace
111
+ old_create_workspace unless sandbox.is_a?(Pod::PrebuildSandbox)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ module Pod
118
+ class Installer
119
+ # Cleans up the sandbox directory by removing stale target support files and headers.
120
+ #
121
+ class SandboxDirCleaner
122
+ alias_method :old_clean!, :clean!
123
+ def clean!
124
+ old_clean! unless @sandbox.is_a?(Pod::PrebuildSandbox)
125
+ end
16
126
  end
17
127
  end
18
128
  end
@@ -6,20 +6,17 @@ module CocoapodsJxedtHook
6
6
  Jxedt::PreInstall.new(installer_context).run
7
7
  end
8
8
 
9
- Pod::HooksManager.register('cocoapods-jxedt', :pre_integrate) do |context, _|
10
-
11
- end
9
+ # Pod::HooksManager.register('cocoapods-jxedt', :pre_integrate) do |context, _|
10
+ # end
12
11
 
13
12
  Pod::HooksManager.register('cocoapods-jxedt', :post_install) do |context, _|
14
13
  require_relative 'post_install'
15
14
  Jxedt::PostInstall.new(context).run
16
15
  end
17
16
 
18
- Pod::HooksManager.register('cocoapods-jxedt', :post_integrate) do |context, _|
19
-
20
- end
17
+ # Pod::HooksManager.register('cocoapods-jxedt', :post_integrate) do |context, _|
18
+ # end
21
19
 
22
- Pod::HooksManager.register('cocoapods-jxedt', :source_provider) do |context, _|
23
-
24
- end
20
+ # Pod::HooksManager.register('cocoapods-jxedt', :source_provider) do |context, _|
21
+ # end
25
22
  end
@@ -14,7 +14,7 @@ module Jxedt
14
14
  validate_pod_checksum unless @installer_context.sandbox.is_a?(Pod::PrebuildSandbox)
15
15
  end
16
16
 
17
- def validate_pod_checksum
17
+ def validate_pod_checksum
18
18
  original_installer = ObjectSpace.each_object(Pod::Installer).reject {|installer| installer.sandbox.is_a?(Pod::PrebuildSandbox) }.first
19
19
  return if original_installer.nil?
20
20
 
@@ -28,7 +28,7 @@ module Jxedt
28
28
  value2 = source_lockfile.spec_checksums_hash_key(name)
29
29
  validation_failed << name if value1.nil? || value2.nil? || value1 != value2
30
30
  }
31
- Pod::UI.warn "Lockfile文件校验失败,请检查Pod组件: #{validation_failed}"
31
+ Pod::UI.warn "⚠️ ⚠️ ⚠️ Lockfile文件校验失败,请检查Pod组件: #{validation_failed}"
32
32
  end
33
33
  end
34
34
  end
@@ -16,10 +16,8 @@ module Jxedt
16
16
  # check binary switch
17
17
  return unless Jxedt.config.binary_switch?
18
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?
19
+ unless Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
20
+ raise STDERR.puts "[!] cocoapods-jxedt binary plugin should use cocoapods version greater than '1.10.0'`".red
23
21
  end
24
22
 
25
23
  require_relative '../helper/prebuild_sandbox'
@@ -29,8 +27,8 @@ module Jxedt
29
27
 
30
28
  # 获取原始的installer对象,必须先获取对象
31
29
  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)
30
+ prebuild_sandbox = Pod::PrebuildSandbox.from_standard_sandbox(@installer_context.sandbox)
31
+ source_installer = Pod::Installer.new(prebuild_sandbox, @installer_context.podfile, @installer_context.lockfile)
34
32
  # 设置原始的installer携带的参数
35
33
  source_installer.update = original_installer.update
36
34
  source_installer.repo_update = original_installer.repo_update
@@ -38,14 +36,40 @@ module Jxedt
38
36
  source_installer.install!
39
37
 
40
38
  # 保存首次`pod install`的lockfile结果,用来验证二进制文件和后面做结果校验
41
- @installer_context.sandbox.source_lockfile = sandbox.source_lockfile = source_installer.lockfile
39
+ @installer_context.sandbox.source_lockfile = prebuild_sandbox.source_lockfile = source_installer.lockfile
42
40
 
43
41
  require_relative '../helper/podfile_options'
44
42
  require_relative '../prebuild'
45
43
 
44
+ # fetch cache and sync
45
+ if Jxedt.config.cache_repo_enabled? && Jxedt.config.auto_fetch?
46
+ log_section "🚗 Fetch git cache"
47
+ pods = prebuild_sandbox.source_lockfile.internal_data["SPEC CHECKSUMS"].keys
48
+ binary_hash = pods.reduce({}) do |hash, name|
49
+ checksum = prebuild_sandbox.source_lockfile.spec_checksums_hash_key(name)
50
+ hash.update(name => checksum) unless checksum.nil?
51
+ end
52
+
53
+ require 'cocoapods-jxedt/git_helper/cache_fetcher'
54
+ binary_dir = @installer_context.sandbox.root + Jxedt.config.binary_dir
55
+ Jxedt::CacheFetcher.sync(binary_hash, binary_dir)
56
+ end
57
+
46
58
  # prebuild_job
47
- log_section "🚀 Prebuild frameworks" if Jxedt.config.prebuild_job?
48
- Jxedt::Prebuild.new(source_installer).build if Jxedt.config.prebuild_job?
59
+ prebuild_sandbox.link_source_project!
60
+ if Jxedt.config.prebuild_job?
61
+ log_section "🚀 Prebuild frameworks"
62
+ build_targets = Jxedt::Prebuild.new(source_installer).build
63
+
64
+ # cache push
65
+ if Jxedt.config.cache_repo_enabled? && Jxedt.config.auto_push? && build_targets && build_targets.size > 0
66
+ log_section "🚄 Push git cache"
67
+ require 'cocoapods-jxedt/git_helper/cache_pucher'
68
+ output_dir = prebuild_sandbox.root + Jxedt.config.binary_dir
69
+ Jxedt::CachePucher.push(output_dir, build_targets, false)
70
+ end
71
+ end
72
+ prebuild_sandbox.clean_source_project!
49
73
 
50
74
  log_section "🤖 Resume pod installation"
51
75
  require_relative '../targets/pod_target'
@@ -1,3 +1,4 @@
1
1
  require_relative 'config'
2
2
  require_relative 'podfile_dsl'
3
3
  require_relative 'hooks/CocoapodsJxedtHook'
4
+ require_relative 'helper/podfile_post_install_hook'
@@ -0,0 +1,40 @@
1
+ module StaticFramework
2
+ class Tree
3
+ attr_reader :headers_path
4
+ attr_reader :private_headers_path
5
+ attr_reader :module_map_path
6
+ attr_reader :root_path
7
+ attr_reader :fwk_path
8
+
9
+ def initialize(name, at_path)
10
+ @name = name
11
+ @at_path = at_path
12
+ make
13
+ end
14
+
15
+ def make
16
+ make_root
17
+ make_framework
18
+ end
19
+
20
+ private
21
+ def make_framework
22
+ @fwk_path = @root_path + Pathname.new(@name + '.framework')
23
+ @fwk_path.rmtree if @fwk_path.exist?
24
+ @fwk_path.mkdir
25
+
26
+ @module_map_path = @fwk_path + Pathname.new('Modules')
27
+
28
+ @headers_path = @fwk_path + Pathname.new('Headers')
29
+ @headers_path.mkpath unless @headers_path.exist?
30
+
31
+ @private_headers_path = @fwk_path + Pathname.new('PrivateHeaders')
32
+ end
33
+
34
+ def make_root
35
+ @root_path = Pathname.new(@at_path)
36
+ @root_path.mkpath unless @root_path.exist?
37
+ end
38
+ end
39
+ end
40
+
@@ -19,9 +19,15 @@ module Jxedt
19
19
  end
20
20
 
21
21
  def run
22
- sdks.each { |sdk| build_for_sdk(sdk) }
22
+ sdks.each { |sdk|
23
+ build_for_sdk(sdk)
24
+ @options[:clean_build] = false # 如果需要编译真机和模拟器,那么第二次编译的时候不能clean
25
+ }
23
26
 
24
27
  targets.each do |target|
28
+ # create static framework with library
29
+ create_framework_from_library(target) if target.build_as_library?
30
+
25
31
  if Jxedt.config.xcframework?
26
32
  create_xcframework(target)
27
33
  elsif sdks.count > 1
@@ -83,10 +89,78 @@ module Jxedt
83
89
  sdk: sdk,
84
90
  deployment_target: targets.map { |t| t.platform.deployment_target }.max.to_s,
85
91
  log_path: log_path(sdk),
92
+ clean_build: clean_build?,
86
93
  args: sdk == simulator ? @build_args[:simulator] : @build_args[:device]
87
94
  )
88
95
  end
89
96
 
97
+ def create_framework_from_library(target)
98
+ require_relative 'framework'
99
+
100
+ sdks.each do |sdk|
101
+ procuct_dir = Pathname.new(target_products_dir_of(target, sdk))
102
+ # make static framework
103
+ fwk = StaticFramework::Tree.new(target.product_module_name, procuct_dir.to_s)
104
+
105
+ # copy library
106
+ lib_output = fwk.fwk_path + target.product_module_name
107
+ lib_file = procuct_dir + "lib#{target.name}.a"
108
+ `lipo -create -output #{lib_output} #{lib_file}` if lib_file.exist?
109
+
110
+ # copy public headers
111
+ headers_source = target.sandbox.headers_root + 'Public' + target.product_module_name
112
+ Dir.glob("#{headers_source}/**/*.h").each { |h| `ditto #{h} #{fwk.headers_path}/#{File.basename(h)}` }
113
+
114
+ # target support module
115
+ if target.defines_module?
116
+ # create modulemap path
117
+ fwk.module_map_path.mkpath unless fwk.module_map_path.exist?
118
+
119
+ # check and copy umbrella headers
120
+ umbrella_headers = Dir.glob("#{procuct_dir}/*-umbrella.h")
121
+ umbrella_headers.each { |h| FileUtils.cp_r(h.to_s, fwk.headers_path) }
122
+
123
+ # check and copy swift headers
124
+ swift_headers = Dir.glob("#{procuct_dir}/*/*-Swift.h")
125
+ swift_headers.each { |h| FileUtils.cp_r(h.to_s, fwk.headers_path) }
126
+
127
+ # check and copy swiftmodule files
128
+ swiftmodule_path = procuct_dir + "#{target.product_module_name}.swiftmodule"
129
+ FileUtils.cp_r(swiftmodule_path, fwk.module_map_path) if swiftmodule_path.exist?
130
+
131
+ # umbrella header name
132
+ header_name = "#{target.name}"
133
+ header_name = "#{target.name}-umbrella" if File.exist? "#{fwk.headers_path}/#{target.name}-umbrella.h"
134
+
135
+ # make modulemap
136
+ if File.exist?("#{fwk.headers_path}/#{header_name}.h")
137
+ module_map = <<MODULE_MAP
138
+ framework module #{target.product_module_name} {
139
+ umbrella header "#{header_name}.h"
140
+
141
+ export *
142
+ module * { export * }
143
+ }
144
+ MODULE_MAP
145
+ unless swift_headers.empty?
146
+ module_map << swift_module_map = <<SWIFT_MODULE_MAP
147
+ module #{target.product_module_name}.Swift {
148
+ header "#{target.product_module_name}-Swift.h"
149
+ requires objc
150
+ }
151
+ SWIFT_MODULE_MAP
152
+ end
153
+ File.write("#{fwk.module_map_path}/module.modulemap", module_map) unless module_map.nil?
154
+ end
155
+ end
156
+
157
+ # remove library product
158
+ procuct_dir.children.each do |child|
159
+ FileUtils.rm_rf(child) if ['.h', '.modulemap', '.a', '.swiftmodule'].include?(child.extname) || "#{child.basename}" == 'Swift Compatibility Header'
160
+ end
161
+ end
162
+ end
163
+
90
164
  def create_xcframework(target)
91
165
  non_framework_paths = Dir[target_products_dir_of(target, preferred_sdk) + "/*"] \
92
166
  - [framework_path_of(target, preferred_sdk)] \
@@ -261,5 +335,9 @@ module Jxedt
261
335
  def log_path(sdk)
262
336
  @options[:log_path].nil? ? nil : "#{@options[:log_path]}_#{sdk}"
263
337
  end
338
+
339
+ def clean_build?
340
+ @options[:clean_build]
341
+ end
264
342
  end
265
343
  end
@@ -34,7 +34,7 @@ module Jxedt
34
34
  end
35
35
  end
36
36
  cmd += options[:args] if options[:args]
37
- cmd += "clean" if options[:clean_build]
37
+ cmd << "clean" if options[:clean_build]
38
38
  cmd << "build"
39
39
 
40
40
  if options[:log_path].nil?