cocoapods-jxedt 0.0.10 → 0.0.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.
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?