cocoapods-bb-xcframework 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f51e31cd2ec034bbc893a17b6335b903273fcd3eb0054cecd270bdf89c4483d3
4
+ data.tar.gz: 9ca7be68bdb56db497bd8c6a99e5870663f98458de65ddf9697c22a993bc5636
5
+ SHA512:
6
+ metadata.gz: 2bc9b6c6c2051a583719ff4e10971387beecbb1a16662ca1c944beebbc9ca70963193e10d2dab59d18abd60d5483dae20c0c99067291441fa80f5b930dd55569
7
+ data.tar.gz: ddd788e2dbee253c008251002bb13c21417cf9b60049316e8b8cfefa1410bd9300b1116546b69347f087ac22059d3777877e8c4fdcfb0cc877358b58b6a166cc
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2021 humin <humin1102@126.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # cocoapods-bb-xcframework
2
+
3
+ - 你是不是发现 `cocoapods-packager` 不能支持 `Swift`?
4
+ - 你是不是发现 `cocoapods-packager` 不能支持 `m1`?
5
+ - 你是不是发现 `cocoapods-packager` 不能支持 `GCC module`?
6
+ - 你是不是发现 `cocoapods-packager` 不能支持 `watch` 和 `tv`?
7
+ - 那你不妨试试我们这个插件~,美滋滋哦~
8
+ 本插件可以帮助开发者快速的创建一个`OC`/`Swift`的`xcframework`。
9
+
10
+ ## feat
11
+ - 支持 `Swift`/`Object-C` 生成 `framework`
12
+ - 支持 `Xcode` 新特性: `xcframework`
13
+ - 支持 `cocoapods` 绝大多数属性
14
+ - 支持 `subspec` 打包
15
+ - 支持二进制库是否生成符号表,默认生成,详见`pod xcframework --help`
16
+
17
+ ## Installation
18
+
19
+ $ gem install cocoapods-bb-xcframework
20
+
21
+ ## Usage
22
+ $ pod xcframework NAME [SOURCE]
23
+ 更多请看
24
+ $pod xcframework --help
25
+
26
+ ```
27
+ % pod xcframework --help
28
+ Usage:
29
+
30
+ $ pod xcframework NAME [SOURCE]
31
+
32
+ Package a podspec into a xcframework.
33
+
34
+ Options:
35
+
36
+ --no-force Overwrite existing
37
+ files.
38
+ --configuration Build the
39
+ specified
40
+ configuration
41
+ (e.g. Debug).
42
+ Defaults to
43
+ Release
44
+ --spec-sources=private,https://github.com/CocoaPods/Specs.git The sources to
45
+ pull dependent
46
+ pods from
47
+ (defaults to
48
+ https://github.com/CocoaPods/Specs.git)
49
+ --subspecs Only include the
50
+ given subspecs
51
+ --use-modular-headers pakcage uses
52
+ modular headers
53
+ during packaging
54
+ --no-static-library package not use
55
+ static library
56
+ --enable-bitcode package enable
57
+ bitcode
58
+ --no-symbols package not use
59
+ symbols
60
+ --allow-root Allows CocoaPods
61
+ to run as root
62
+ --silent Show nothing
63
+ --verbose Show more
64
+ debugging
65
+ information
66
+ --no-ansi Show output
67
+ without ANSI codes
68
+ --help Show help banner
69
+ of specified
70
+ command
71
+ ```
72
+
73
+ ## Q&A
74
+ ### 而且本插件支持`apple`的全平台的`framework`创建,如下图
75
+
76
+ ![all](img/allplatform.png)
@@ -0,0 +1,65 @@
1
+ module Pod
2
+ class Command
3
+ # This is an example of a cocoapods plugin adding a top-level subcommand
4
+ # to the 'pod' command.
5
+ #
6
+ # You can also create subcommands of existing or new commands. Say you
7
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
8
+ # (e.g. `pod list deprecated`), there are a few things that would need
9
+ # to change.
10
+ #
11
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
12
+ # the class to exist in the the Pod::Command::List namespace
13
+ # - change this class to extend from `List` instead of `Command`. This
14
+ # tells the plugin system that it is a subcommand of `list`.
15
+ # - edit `lib/cocoapods_plugins.rb` to require this file
16
+ #
17
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
18
+ # in the `plugins.json` file, once your plugin is released.
19
+ #
20
+ class MutiXCFramework < Command
21
+ self.summary = 'Package some podspec into a xcframework.'
22
+ self.arguments = [
23
+ CLAide::Argument.new('NAME', true),
24
+ CLAide::Argument.new('SOURCE', false)
25
+ ]
26
+ include Config::Mixin
27
+
28
+ def self.options
29
+ [
30
+ ['--no-force', 'Overwrite existing files.'],
31
+ ['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
32
+ ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependent pods from (defaults to https://github.com/CocoaPods/Specs.git)'],
33
+ ['--use-modular-headers', 'pakcage uses modular headers during packaging'],
34
+ ['--no-static-library', 'package not use static library'],
35
+ ['--enable-bitcode', 'package enable bitcode'],
36
+ ['--no-symbols', 'package not use symbols']
37
+ ].concat super
38
+ end
39
+
40
+ def initialize(argv)
41
+ @name = argv.shift_argument
42
+ @source = argv.shift_argument
43
+ @spec_sources = argv.option('spec-sources', 'https://github.com/CocoaPods/Specs.git').split(',')
44
+ @configuration = argv.option('configuration', 'Release')
45
+ @use_modular_headers = argv.option('use-modular-headers', true)
46
+ @force = argv.flag?('force', true)
47
+ @use_static_library = argv.flag?('static-library', true)
48
+ @enable_bitcode = argv.flag?('enable-bitcode',false)
49
+ @symbols = argv.flag?('symbols',true)
50
+ config.static_library_enable = @use_static_library
51
+ super
52
+ end
53
+
54
+ def validate!
55
+ super
56
+ help! 'A file written some pods need package is needed' unless @name
57
+ end
58
+
59
+ def run
60
+ frameworker = MutiFrameworker.new(@name, @source, @spec_sources, @configuration, @force, @use_modular_headers, @enable_bitcode, @symbols)
61
+ frameworker.run
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,68 @@
1
+ module Pod
2
+ class Command
3
+ # This is an example of a cocoapods plugin adding a top-level subcommand
4
+ # to the 'pod' command.
5
+ #
6
+ # You can also create subcommands of existing or new commands. Say you
7
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
8
+ # (e.g. `pod list deprecated`), there are a few things that would need
9
+ # to change.
10
+ #
11
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
12
+ # the class to exist in the the Pod::Command::List namespace
13
+ # - change this class to extend from `List` instead of `Command`. This
14
+ # tells the plugin system that it is a subcommand of `list`.
15
+ # - edit `lib/cocoapods_plugins.rb` to require this file
16
+ #
17
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
18
+ # in the `plugins.json` file, once your plugin is released.
19
+ #
20
+ class XCFramework < Command
21
+ self.summary = 'Package a podspec into a xcframework.'
22
+ self.arguments = [
23
+ CLAide::Argument.new('NAME', true),
24
+ CLAide::Argument.new('SOURCE', false)
25
+ ]
26
+ include Config::Mixin
27
+
28
+ def self.options
29
+ [
30
+ ['--no-force', 'Overwrite existing files.'],
31
+ ['--configuration', 'Build the specified configuration (e.g. Debug). Defaults to Release'],
32
+ ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependent pods from (defaults to https://github.com/CocoaPods/Specs.git)'],
33
+ ['--subspecs', 'Only include the given subspecs'],
34
+ ['--use-modular-headers', 'pakcage uses modular headers during packaging'],
35
+ ['--no-static-library', 'package not use static library'],
36
+ ['--enable-bitcode', 'package enable bitcode'],
37
+ ['--no-symbols', 'package not use symbols'] # 符号表
38
+ ].concat super
39
+ end
40
+
41
+ def initialize(argv)
42
+ @name = argv.shift_argument
43
+ @source = argv.shift_argument
44
+ @spec_sources = argv.option('spec-sources', 'https://github.com/CocoaPods/Specs.git').split(',')
45
+ subspecs = argv.option('subspecs')
46
+ @subspecs = subspecs.split(',') unless subspecs.nil?
47
+ @configuration = argv.option('configuration', 'Release')
48
+ @use_modular_headers = argv.option('use-modular-headers', true)
49
+ @force = argv.flag?('force', true)
50
+ @use_static_library = argv.flag?('static-library',true)
51
+ @enable_bitcode = argv.flag?('enable-bitcode',false)
52
+ @symbols = argv.flag?('symbols',true)
53
+ config.static_library_enable = @use_static_library
54
+ super
55
+ end
56
+
57
+ def validate!
58
+ super
59
+ help! 'A Pod name is required.' unless @name
60
+ end
61
+
62
+ def run
63
+ frameworker = Frameworker.new(@name, @source, @spec_sources, @subspecs, @configuration, @force, @use_modular_headers, @enable_bitcode, @symbols)
64
+ frameworker.run
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,2 @@
1
+ require 'cocoapods-xcframework/command/xcframework'
2
+ require 'cocoapods-xcframework/command/muti_xcframework'
@@ -0,0 +1,8 @@
1
+ module Pod
2
+ class Config
3
+ attr_accessor :xcframework_enable
4
+ alias_method :xcframework_enable?, :xcframework_enable
5
+ attr_accessor :static_library_enable
6
+ alias_method :static_library_enable?, :static_library_enable
7
+ end
8
+ end
@@ -0,0 +1,70 @@
1
+ module Pod
2
+ class Frameworker
3
+ include PodUtil
4
+ include DirUtil
5
+ include Config::Mixin
6
+ def initialize(name, source, spec_sources, subspecs, configuration, force, use_modular_headers=true, enable_bitcode=false, symbols=true)
7
+ @name = name
8
+ @source = source
9
+ @spec_sources = spec_sources
10
+ @subspecs = subspecs
11
+ @configuration = configuration
12
+ @force = force
13
+ @use_modular_headers = use_modular_headers
14
+ @enable_bitcode = enable_bitcode
15
+ @symbols = symbols
16
+ end
17
+
18
+ def run
19
+ spec = spec_with_path @name
20
+ @is_spec_from_path = true if spec
21
+ spec ||= spec_with_name @name
22
+
23
+ target_dir, work_dir = create_working_directory_by_spec spec, @force
24
+ build_framework spec, work_dir, target_dir
25
+ end
26
+
27
+ def build_framework spec, work_dir, target_dir
28
+ build_in_sandbox(work_dir, spec, target_dir)
29
+ end
30
+
31
+ def build_in_sandbox work_dir, spec, target_dir
32
+ config.installation_root = Pathname.new work_dir
33
+ config.sandbox_root = "#{work_dir}/Pods"
34
+ sandbox = build_static_sandbox
35
+
36
+ sandbox_installer = installation_root(
37
+ sandbox,
38
+ spec,
39
+ @subspecs,
40
+ @spec_sources,
41
+ true,
42
+ @use_modular_headers,
43
+ @enable_bitcode
44
+ )
45
+
46
+ perform_build(
47
+ sandbox,
48
+ sandbox_installer,
49
+ spec,
50
+ target_dir
51
+ )
52
+ end
53
+
54
+ # def perform_build platform, sandbox, installer, spec
55
+ def perform_build sandbox, installer, spec, target_dir
56
+ sandbox_root = config.sandbox_root.to_s
57
+ builder = Pod::XBuilder.new(
58
+ installer,
59
+ Dir.pwd,
60
+ sandbox_root,
61
+ spec,
62
+ @configuration,
63
+ @symbols
64
+ )
65
+ builder.build
66
+ builder.outputs target_dir
67
+ target_dir
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module CocoapodsXCFramework
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,57 @@
1
+ module Pod
2
+ class MutiFrameworker
3
+ include Pod::PodUtil
4
+ include Pod::GitUtil
5
+ include Pod::DirUtil
6
+ include Config::Mixin
7
+ def initialize(name, source, spec_sources, configuration, force, use_modular_headers)
8
+ @name = name
9
+ @source = source
10
+ @spec_sources = spec_sources
11
+ @configuration = configuration
12
+ @force = force
13
+ @use_modular_headers = use_modular_headers
14
+ end
15
+
16
+ def run
17
+ configs = muti_config_with_file @name
18
+ target_dir, work_dir = create_working_directory_by_spec "xcframeworks", @force
19
+ prepare_git_with_configs configs, work_dir
20
+ build_frameworks configs, work_dir, target_dir
21
+ end
22
+
23
+ def build_frameworks configs, work_dir, target_dir
24
+ config.installation_root = Pathname.new work_dir
25
+ config.sandbox_root = "#{work_dir}/Pods"
26
+ sandbox = build_static_sandbox
27
+
28
+ sandbox_installer = installation_root_muti(
29
+ sandbox,
30
+ configs,
31
+ @spec_sources,
32
+ @use_modular_headers
33
+ )
34
+ perform_build(
35
+ sandbox,
36
+ sandbox_installer,
37
+ configs,
38
+ target_dir
39
+ )
40
+ end
41
+
42
+ def perform_build sandbox, installer, configs, target_dir
43
+ sandbox_root = config.sandbox_root.to_s
44
+ builder = Pod::XBuilder.new(
45
+ installer,
46
+ Dir.pwd,
47
+ sandbox_root,
48
+ configs,
49
+ @configuration
50
+ )
51
+ builder.build
52
+ builder.outputs_muti target_dir
53
+ end
54
+
55
+
56
+ end
57
+ end
@@ -0,0 +1,24 @@
1
+ module Pod
2
+ class Cmmd
3
+ class << self
4
+ def sh! command
5
+ UI.puts command
6
+ output = `#{command}`.lines.to_a
7
+ if $?.exitstatus != 0
8
+ Pod::ErrorUtil.error_report command,output
9
+ Process.exit -1
10
+ end
11
+ output
12
+ end
13
+
14
+ def sh? command
15
+ UI.puts command
16
+ output = `#{command}`.lines.to_a
17
+ if $?.exitstatus != 0
18
+ Pod::ErrorUtil.error_report command,output
19
+ end
20
+ output
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ module Pod
2
+ module DirUtil
3
+ def create_target_directory_path_by_spec spec,force
4
+ target_dir = "#{Dir.pwd}/#{spec.name}-#{spec.version}"
5
+
6
+ if File.exist? target_dir
7
+ if @force
8
+ Pathname.new(target_dir).rmtree
9
+ else
10
+ UI.warn "Target directory '#{target_dir}' already exists."
11
+ end
12
+ end
13
+ target_dir
14
+ end
15
+
16
+ def create_working_directory_by_spec spec,force
17
+ if spec.is_a? String
18
+ return create_working_directory_by_name spec,force
19
+ end
20
+ target_dir = create_target_directory_path_by_spec spec,force
21
+ # Pathname.new(target_dir).mkdir
22
+ work_dir = Dir.tmpdir + '/frameworks-' + Array.new(8) { rand(36).to_s(36) }.join
23
+
24
+ Pathname.new(work_dir).mkdir
25
+ [target_dir, work_dir]
26
+ end
27
+
28
+ def create_target_directory_path_by_name name, force
29
+ target_dir = "#{Dir.pwd}/#{name}-muti"
30
+
31
+ if File.exist? target_dir
32
+ if @force
33
+ Pathname.new(target_dir).rmtree
34
+ else
35
+ UI.warn "Target directory '#{target_dir}' already exists."
36
+ end
37
+ end
38
+ target_dir
39
+ end
40
+
41
+ def create_working_directory_by_name name, force
42
+ target_dir = create_target_directory_path_by_name name,force
43
+ # Pathname.new(target_dir).mkdir
44
+ work_dir = Dir.tmpdir + '/frameworks-' + Array.new(8) { rand(36).to_s(36) }.join
45
+
46
+ Pathname.new(work_dir).mkdir
47
+ [target_dir, work_dir]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,13 @@
1
+ module Pod
2
+ module ErrorUtil
3
+ class << self
4
+ def error_report(command, output)
5
+ UI.puts "<<-EOF
6
+ Build command failed: #{command}
7
+ Output:
8
+ #{output.map { |line| " #{line}" }.join}
9
+ EOF"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Pod
2
+ module GitUtil
3
+ def prepare_git_with_configs configs, work_dir
4
+ index = 0
5
+ configs.each do |config|
6
+ name = config["name"]
7
+ git_url = config["git_url"]
8
+ git_branch = config["git_branch"]
9
+ command = "git clone #{git_url} -b #{git_branch} #{work_dir}/#{name}"
10
+ Cmmd.sh! command
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,256 @@
1
+ module Pod
2
+ module PodUtil
3
+ include Config::Mixin
4
+
5
+ def to_native_platform name
6
+ case name
7
+ when 'iphoneos' then 'ios'
8
+ when 'macOS' then 'osx'
9
+ when 'appletvos' then 'tvos'
10
+ when 'watchos' then 'watchos'
11
+ when 'ios' then 'ios'
12
+ when 'macos' then 'osx'
13
+ when 'tvos' then 'tvos'
14
+ else
15
+ name
16
+ end
17
+ end
18
+
19
+ def muti_config_with_file(path)
20
+ return nil if path.nil?
21
+ path = Pathname.new(path)
22
+ path = Pathname.new(Dir.pwd).join(path) unless path.absolute?
23
+ @path = path.expand_path
24
+ content = File.open(path, 'rb').read
25
+ result = JSON.parse content
26
+ if not result.is_a? Array
27
+ UI.error "#{path} format not support"
28
+ exit -1
29
+ end
30
+ result
31
+ end
32
+
33
+ def spec_with_path(path)
34
+ return if path.nil?
35
+ path = Pathname.new(path)
36
+ path = Pathname.new(Dir.pwd).join(path) unless path.absolute?
37
+ return unless path.exist?
38
+ @path = path.expand_path
39
+
40
+ if @path.directory?
41
+ raise @path + ': is a directory.'
42
+ return
43
+ end
44
+
45
+ unless ['.podspec', '.json'].include? @path.extname
46
+ raise @path + ': is not a podspec.'
47
+ return
48
+ end
49
+
50
+ Specification.from_file(@path)
51
+ end
52
+
53
+ def spec_with_name(name)
54
+ return if name.nil?
55
+
56
+ set = Pod::Config.instance.sources_manager.search(Dependency.new(name))
57
+ return nil if set.nil?
58
+
59
+ set.specification.root
60
+ end
61
+
62
+ def build_static_sandbox
63
+ Sandbox.new(config.sandbox_root)
64
+ end
65
+
66
+ def installation_root sandbox, spec, subspecs, sources,use_frameworks = true,use_modular_headers = true, enable_bitcode = false
67
+ podfile = podfile_from_spec(
68
+ @path,
69
+ spec,
70
+ subspecs,
71
+ sources,
72
+ use_frameworks,
73
+ use_modular_headers
74
+ )
75
+
76
+ installer = Installer.new(sandbox, podfile)
77
+ installer.repo_update = true
78
+ installer.install!
79
+
80
+ unless installer.nil?
81
+ installer.pods_project.targets.each do |target|
82
+ target.build_configurations.each do |configuration|
83
+ if enable_bitcode && configuration.name == "Release"
84
+ configuration.build_settings['ENABLE_BITCODE'] = 'YES'
85
+ configuration.build_settings['BITCODE_GENERATION_MODE'] = 'bitcode'
86
+ end
87
+ end
88
+ if target.name == spec.name
89
+ target.build_configurations.each do |configuration|
90
+ configuration.build_settings['CLANG_MODULES_AUTOLINK'] = 'NO'
91
+ end
92
+ end
93
+ end
94
+ installer.pods_project.save
95
+ end
96
+ installer
97
+ end
98
+
99
+ def installation_root_muti sandbox, configs, sources, use_frameworks = true, use_modular_headers = true, enable_bitcode = false
100
+ podfile = podfile_from_muti_configs(
101
+ configs,
102
+ sources,
103
+ use_frameworks,
104
+ use_modular_headers
105
+ )
106
+ installer = Installer.new(sandbox, podfile)
107
+ installer.repo_update = true
108
+ installer.install!
109
+
110
+ specs = configs.map do |cfg|
111
+ cfg["name"]
112
+ end
113
+ unless installer.nil?
114
+ installer.pods_project.targets.each do |target|
115
+ target.build_configurations.each do |configuration|
116
+ if enable_bitcode && configuration.name == "Release"
117
+ configuration.build_settings['ENABLE_BITCODE'] = 'YES'
118
+ configuration.build_settings['BITCODE_GENERATION_MODE'] = 'bitcode'
119
+ end
120
+ end
121
+ if specs.include? target.name
122
+ target.build_configurations.each do |configuration|
123
+ configuration.build_settings['CLANG_MODULES_AUTOLINK'] = 'NO'
124
+ end
125
+ end
126
+ end
127
+ installer.pods_project.save
128
+ end
129
+ installer
130
+ end
131
+
132
+ def podfile_from_spec path, spec, subspecs, sources, use_frameworks = true, use_modular_headers=true
133
+ options = Hash.new
134
+ options[:podspec] = path.to_s
135
+ options[:subspecs] = spec.subspecs.map do |sub|
136
+ sub.base_name
137
+ end
138
+ options[:subspecs] = subspecs if subspecs
139
+ # 非常奇怪,如果传一个空的数组过去就会出问题!!
140
+ if options[:subspecs].length == 0
141
+ options[:subspecs] = nil
142
+ end
143
+ static_library_enable = config.static_library_enable?
144
+ Pod::Podfile.new do
145
+ sources.each {|s| source s}
146
+ spec.available_platforms.each do |plt|
147
+ target "#{spec.name}-#{plt.name}" do
148
+ platform(plt.name, spec.deployment_target(plt.name))
149
+ pod(spec.name, options)
150
+ end
151
+ end
152
+
153
+ install!('cocoapods',:integrate_targets => false,:deterministic_uuids => false)
154
+ if static_library_enable
155
+ use_frameworks! :linkage => :static if use_frameworks
156
+ else
157
+ use_frameworks! if use_frameworks
158
+ end
159
+ use_modular_headers! if use_modular_headers
160
+ end
161
+ end
162
+
163
+ def podfile_from_muti_configs configs, sources, use_frameworks = true, use_modular_headers = true
164
+ installation_root = config.installation_root.to_s
165
+ static_library_enable = config.static_library_enable?
166
+ Pod::Podfile.new do
167
+ sources.each {|s| source s}
168
+ configs.each do |cfg|
169
+ pod_spec_path = installation_root + "/#{cfg["name"]}/#{cfg["name"]}.podspec"
170
+ pod_spec_json_path = pod_spec_path + ".json"
171
+ (Pathname.glob(pod_spec_path) + Pathname.glob(pod_spec_json_path)).each do |real_path|
172
+ spec = Pod::Specification.from_file real_path.to_s
173
+ options = Hash.new
174
+ options[:podspec] = real_path.to_s
175
+ if cfg["subspecs"]
176
+ options[:subspecs] = cfg["subspecs"]
177
+ else
178
+ options[:subspecs] = spec.subspecs.map do |sub|
179
+ sub.base_name
180
+ end
181
+ end
182
+ # 非常奇怪,如果传一个空的数组过去就会出问题!!
183
+ if options[:subspecs].length == 0
184
+ options[:subspecs] = nil
185
+ end
186
+ spec.available_platforms.each do |plt|
187
+ target "#{spec.name}-#{plt.name}" do
188
+ puts "#{plt.name} #{spec.name} #{options}"
189
+ platform(plt.name, spec.deployment_target(plt.name))
190
+ pod(spec.name, options)
191
+ end
192
+ end
193
+ end
194
+ end
195
+ install!('cocoapods',
196
+ :integrate_targets => false,
197
+ :deterministic_uuids => false)
198
+
199
+ if static_library_enable
200
+ use_frameworks! :linkage => :static if use_frameworks
201
+ else
202
+ use_frameworks! if use_frameworks
203
+ end
204
+ use_modular_headers! if use_modular_headers
205
+ end
206
+ end
207
+
208
+ def generic_new_podspec_hash spec
209
+ spec_hash = spec.to_hash
210
+ [
211
+ "source_files",
212
+ "resources",
213
+ "resource_bundles",
214
+ "prefix_header_contents",
215
+ "prefix_header_file",
216
+ "header_dir",
217
+ "header_mappings_dir",
218
+ "script_phase",
219
+ "public_header_files",
220
+ "private_header_files",
221
+ "vendored_frameworks",
222
+ "vendored_libraries",
223
+ "exclude_files",
224
+ "preserve_paths",
225
+ "module_map",
226
+ "subspec"
227
+ ].each do |key|
228
+ spec_hash.delete "#{key}"
229
+ end
230
+ spec_hash
231
+ end
232
+
233
+ def fix_header_file spec_hash, xcframework_path
234
+ puts "Dir.glob(#{xcframework_path}/*/) : #{Dir.glob("#{xcframework_path}/*/")}"
235
+ Dir.glob("#{xcframework_path}/*/").each do |file|
236
+ ['ios','macos','tvos', 'watchos'].each do |prefix|
237
+ last_path = file.split("/").last
238
+ if last_path =~ /#{prefix}/ and not last_path =~ /simulator/
239
+ platform = to_native_platform prefix
240
+ if spec_hash[platform]
241
+ spec_hash[platform]["public_header_files"] = "#{spec_hash[:vendored_frameworks]}/#{last_path}/*/Headers/*.h"
242
+ spec_hash[platform]["source_files"] = "#{spec_hash[:vendored_frameworks]}/#{last_path}/*/Headers/*.h"
243
+ else
244
+ spec_hash[platform] = {
245
+ "public_header_files" => "#{spec_hash[:vendored_frameworks]}/#{last_path}/*/Headers/*.h",
246
+ "source_files" => "#{spec_hash[:vendored_frameworks]}/#{last_path}/*/Headers/*.h"
247
+ }
248
+ end
249
+ end
250
+ end
251
+ end
252
+ puts spec_hash.to_json
253
+ spec_hash
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,5 @@
1
+ require 'cocoapods-xcframework/util/error_util'
2
+ require 'cocoapods-xcframework/util/cmd'
3
+ require 'cocoapods-xcframework/util/git_util'
4
+ require 'cocoapods-xcframework/util/pod_util'
5
+ require 'cocoapods-xcframework/util/dir_util'
@@ -0,0 +1,21 @@
1
+ module Pod
2
+ class XBuilder
3
+ module XcodeXBuilder
4
+ def xcode_xbuild(defines, configuration, work_dir, build_dir = 'export')
5
+ if defined?(Pod::DONT_CODESIGN)
6
+ defines = "#{defines} CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO"
7
+ end
8
+ pwd = Pathname.pwd
9
+ Dir.chdir work_dir
10
+ command = "xcodebuild #{defines} BUILD_DIR=#{build_dir} BUILD_LIBRARY_FOR_DISTRIBUTION=YES clean build -configuration #{configuration} -alltargets 2>&1"
11
+ UI.puts("XBuilder command:#{command}")
12
+ output = `#{command}`.lines.to_a
13
+ Dir.chdir pwd
14
+ if $?.exitstatus != 0
15
+ Pod::ErrorUtil.error_report command,output
16
+ Process.exit -1
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,46 @@
1
+ require 'xcodeproj'
2
+ module Pod
3
+ class XBuilder
4
+ module XcodeProjHelper
5
+ include PodUtil
6
+ def modify_xcode_project_sdk_to_simullator path
7
+ sdks = xcode_sdks
8
+ project = Xcodeproj::Project.open path
9
+
10
+ project.targets.each do |target|
11
+ simulator_sdk = to_native_simulator_platform target.sdk
12
+ if not simulator_sdk.nil?
13
+ canonicalName = sdks[simulator_sdk]["canonicalName"]
14
+ target.build_configurations.each do |configuration|
15
+ configuration.build_settings["SDKROOT"] = canonicalName
16
+ end
17
+ end
18
+ end
19
+ project.save
20
+ end
21
+
22
+ private
23
+ def xcode_sdks
24
+ return @x_sdks if @x_sdks
25
+ outputs = `xcodebuild -showsdks -json`
26
+ sdks = JSON.parse outputs
27
+ @x_sdks = {}
28
+ sdks.each do |sdk|
29
+ @x_sdks[sdk["platform"]] = sdk
30
+ end
31
+ @x_sdks
32
+ end
33
+
34
+ def to_native_simulator_platform name
35
+ case name
36
+ when 'iphoneos' then 'iphonesimulator'
37
+ when 'macOS' then nil
38
+ when 'appletvos' then 'appletvsimulator'
39
+ when 'watchos' then 'watchsimulator'
40
+ else
41
+ name
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,273 @@
1
+ require 'cocoapods-xcframework/xbuilder/xcode_xbuild'
2
+ require 'cocoapods-xcframework/xbuilder/xcodeproj_helper'
3
+ module Pod
4
+ class XBuilder
5
+ include XcodeXBuilder
6
+ include XcodeProjHelper
7
+ include PodUtil
8
+ include Config::Mixin
9
+ def initialize(installer, source_dir, sandbox_root, spec, configuration, symbols=true)
10
+ # def initialize(platform, installer, source_dir, sandbox_root, spec, config)
11
+ # @platform = platform
12
+ @installer = installer
13
+ @source_dir = source_dir
14
+ @sandbox_root = sandbox_root
15
+ @spec = spec
16
+ @muti = @spec.is_a? Array
17
+ @configs = @spec if @muti
18
+ @spec = "muti" if @muti
19
+
20
+ @configuration = configuration
21
+ @outputs = Hash.new
22
+ @symbols = symbols
23
+ end
24
+
25
+ def build
26
+ UI.puts("Building framework #{@spec} with configuration #{@configuration}")
27
+ UI.puts "Work dir is :#{@sandbox_root}"
28
+ # defines = "GCC_PREPROCESSOR_DEFINITIONS='$(inherited) PodsDummy_Pods_#{@spec.name}=PodsDummy_PodPackage_#{@spec.name}'"
29
+ defines = ""
30
+ if @configuration == 'Debug'
31
+ defines << 'GCC_GENERATE_DEBUGGING_SYMBOLS=YES ONLY_ACTIVE_ARCH=NO'
32
+ else
33
+ if @symbols
34
+ defines << "GCC_GENERATE_DEBUGGING_SYMBOLS=YES" # Release模式需要符号表应于问题排查(二进制切源码操作) by hm 21/10/13
35
+ else
36
+ defines << "GCC_GENERATE_DEBUGGING_SYMBOLS=NO" # 去除符号表
37
+ end
38
+ end
39
+
40
+ build_all_device defines
41
+
42
+ collect_xc_frameworks
43
+
44
+ collect_bundles
45
+ end
46
+
47
+ def collect_xc_frameworks
48
+ if @muti
49
+ collect_muti_xcframworks
50
+ else
51
+ collect_single_xcframeworks
52
+ end
53
+ end
54
+
55
+ def collect_muti_xcframworks
56
+ @outputs[:xcframework] = Hash.new
57
+ @configs.each do |cfg|
58
+ export_dir = "#{@sandbox_root}/export/**/#{cfg["name"]}.framework"
59
+ frameworks = Pathname.glob(export_dir)
60
+ @outputs[:xcframework][cfg["name"]] = create_xc_framework_by_frameworks frameworks, cfg["name"]
61
+ end
62
+ end
63
+
64
+ def collect_single_xcframeworks
65
+ export_dir = "#{@sandbox_root}/export/**/#{@spec.name}.framework"
66
+ frameworks = Pathname.glob(export_dir)
67
+ @outputs[:xcframework] = create_xc_framework_by_frameworks frameworks, @spec.name
68
+ end
69
+
70
+ def collect_bundles
71
+ if @muti
72
+ colelct_muti_bundles
73
+ else
74
+ collect_single_bundles
75
+ end
76
+ end
77
+
78
+ def colelct_muti_bundles
79
+ @outputs[:bundle] = Hash.new
80
+ @configs.each do |cfg|
81
+ # "" 这个是用来代表mac os的 macos 没有后缀奇怪吧
82
+ ["iphoneos","","appletvos","watchos"].each do |plat|
83
+ export_dir = "#{@sandbox_root}/export/*-#{plat}/**/#{cfg["name"]}.bundle/**"
84
+ Pathname.glob(export_dir).each do |bundle|
85
+ if bundle.to_s.include? "#{@spec.name}.bundle/Info.plist"
86
+ return
87
+ end
88
+ target_path = "#{@sandbox_root}/bundle/#{cfg["name"]}"
89
+ @outputs[:bundle][cfg["name"]] = target_path
90
+ native_platform = to_native_platform plat
91
+ path = Pathname.new "#{target_path}/#{native_platform}"
92
+ if not path.exist?
93
+ path.mkpath
94
+ end
95
+ FileUtils.cp_r(Dir["#{bundle}"],"#{path}")
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ def collect_single_bundles
102
+ # "" 这个是用来代表mac os的 macos 没有后缀奇怪吧
103
+ ["iphoneos","","appletvos","watchos"].each do |plat|
104
+ export_dir = "#{@sandbox_root}/export/*-#{plat}/**/#{@spec.name}.bundle/**"
105
+ Pathname.glob(export_dir).each do |bundle|
106
+ if bundle.to_s.include? "#{@spec.name}.bundle/Info.plist"
107
+ return
108
+ end
109
+ @outputs[:bundle] = "#{@sandbox_root}/bundle"
110
+ native_platform = to_native_platform plat
111
+ path = Pathname.new "#{@sandbox_root}/bundle/#{native_platform}"
112
+ if not path.exist?
113
+ path.mkpath
114
+ end
115
+ FileUtils.cp_r(Dir["#{bundle}"],"#{path}")
116
+ end
117
+ end
118
+ end
119
+
120
+ def create_xc_framework_by_frameworks frameworks, spec_name
121
+ command = 'xcodebuild -create-xcframework '
122
+ frameworks.each do |framework|
123
+ command << "-framework #{framework} "
124
+ end
125
+ command << "-output #{@sandbox_root}/#{spec_name}.xcframework 2>&1"
126
+ output = `#{command}`.lines.to_a
127
+ UI.puts("make xcframework command:#{command}")
128
+ UI.puts("make xcframework output:#{output}")
129
+ if $?.exitstatus != 0
130
+ Pod::ErrorUtil.error_report command,output
131
+ Process.exit -1
132
+ end
133
+ "#{@sandbox_root}/#{spec_name}.xcframework"
134
+ end
135
+
136
+ def build_all_device defines
137
+ # build general first because simulator will exchange SDKROOT to simulat sdk
138
+ build_general_device defines
139
+ build_simulator_device defines
140
+ end
141
+
142
+ def build_general_device defines
143
+ UI.puts("--- Building framework #{@spec} with general device")
144
+ xcode_xbuild(
145
+ defines,
146
+ @configuration,
147
+ @sandbox_root
148
+ )
149
+ end
150
+
151
+ def build_simulator_device defines
152
+ UI.puts("--- Building framework #{@spec} with simulator device")
153
+ modify_xcode_project_sdk_to_simullator "#{@sandbox_root}/Pods.xcodeproj"
154
+ xcode_xbuild(
155
+ defines,
156
+ @configuration,
157
+ @sandbox_root
158
+ )
159
+ end
160
+
161
+ def outputs target_dir
162
+ if not File.exist? target_dir
163
+ Pathname.new(target_dir).mkdir
164
+ end
165
+ outputs_xcframework target_dir
166
+ outputs_bundle target_dir
167
+ new_spec_hash = generic_new_podspec_hash @spec
168
+ new_spec_hash[:vendored_frameworks] = "#{@spec.name}.xcframework"
169
+ new_spec_hash = fix_header_file new_spec_hash, "#{target_dir}/#{@spec.name}.xcframework"
170
+ find_bundles(target_dir).each do |plat, value|
171
+ if new_spec_hash[plat]
172
+ new_spec_hash[plat]["resource_bundles"] = value
173
+ else
174
+ new_spec_hash[plat] = {
175
+ "resource_bundles" => value
176
+ }
177
+ end
178
+ end
179
+ require 'json'
180
+ spec_json = JSON.pretty_generate(new_spec_hash) << "\n"
181
+ File.open("#{target_dir}/#{@spec.name}.podspec.json",'wb+') do |f|
182
+ f.write(spec_json)
183
+ end
184
+ UI.puts "result export at :#{target_dir}"
185
+ target_dir
186
+ end
187
+
188
+ def find_bundles target_dir
189
+ bundle_root = "#{target_dir}/bundle/"
190
+ pattern = "#{bundle_root}*"
191
+ result = {}
192
+ Pathname.glob(pattern).each do |bundle|
193
+ bundle_relative_path = bundle.to_s.gsub(bundle_root, "")
194
+ plat = bundle_relative_path
195
+ result[plat] = {
196
+ "#{@spec.name}" => "bundle/" + bundle_relative_path + "/*"
197
+ }
198
+ end
199
+ result
200
+ end
201
+
202
+ def outputs_xcframework target_dir
203
+ command = "cp -rp #{@outputs[:xcframework]} #{target_dir} 2>&1"
204
+ output = `#{command}`.lines.to_a
205
+ if $?.exitstatus != 0
206
+ Pod::ErrorUtil.error_report command,output
207
+ Process.exit -1
208
+ end
209
+ end
210
+
211
+ def outputs_bundle target_dir
212
+ if @outputs[:bundle]
213
+ FileUtils.cp_r(Dir[@outputs[:bundle]],target_dir)
214
+ end
215
+ end
216
+
217
+ def outputs_muti target_dir
218
+ if not File.exist? target_dir
219
+ Pathname.new(target_dir).mkdir
220
+ end
221
+ outputs_xcframework_muti target_dir
222
+ outputs_bundle_muti target_dir
223
+ generic_new_podspec_hash_muti target_dir
224
+ end
225
+
226
+ def generic_new_podspec_hash_muti target_dir
227
+ work_dir = config.installation_root
228
+ @configs.map do |cfg|
229
+ podspec_path = "#{work_dir}/#{cfg["name"]}/#{cfg["name"]}.podspec"
230
+ if not File.exist? podspec_path
231
+ podspec_path = "#{podspec_path}.json"
232
+ end
233
+ podspec = Pod::Specification.from_file podspec_path
234
+ new_spec_hash = generic_new_podspec_hash podspec
235
+ new_spec_hash[:vendored_frameworks] = "#{podspec.name}.xcframework"
236
+ new_spec_hash = fix_header_file new_spec_hash, "#{target_dir}/#{@spec.name}.xcframework"
237
+ find_bundles("#{target_dir}/#{podspec.name}").each do |plat, value|
238
+ if new_spec_hash[plat]
239
+ new_spec_hash[plat]["resource_bundles"] = value
240
+ else
241
+ new_spec_hash[plat] = {
242
+ "resource_bundles" => value
243
+ }
244
+ end
245
+ end
246
+ require 'json'
247
+ spec_json = JSON.pretty_generate(new_spec_hash) << "\n"
248
+ File.open("#{target_dir}/#{podspec.name}/#{podspec.name}.podspec.json",'wb+') do |f|
249
+ f.write(spec_json)
250
+ end
251
+ UI.puts "result export at :#{target_dir}/#{podspec.name}"
252
+ "#{target_dir}/#{podspec.name}"
253
+ end
254
+ end
255
+
256
+ def outputs_xcframework_muti target_dir
257
+ @outputs[:xcframework].each do |name, path|
258
+ target_dir_path = "#{target_dir}/#{name}/"
259
+ Pathname.new(target_dir_path).mkpath
260
+ FileUtils.cp_r(path, target_dir_path)
261
+ end
262
+ end
263
+
264
+ def outputs_bundle_muti target_dir
265
+ @outputs[:bundle].each do |name, path|
266
+ target_dir_path = "#{target_dir}/#{name}/bundle/"
267
+ Pathname.new(target_dir_path).mkpath
268
+ FileUtils.cp_r(path, target_dir_path)
269
+ end
270
+ end
271
+
272
+ end
273
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-xcframework/gem_version'
@@ -0,0 +1,11 @@
1
+ require 'cocoapods'
2
+ require 'cocoapods-xcframework/gem_version.rb'
3
+ require 'cocoapods-xcframework/config'
4
+ require 'cocoapods-xcframework/util'
5
+ require 'cocoapods-xcframework/xbuilder'
6
+ require 'cocoapods-xcframework/frameworker'
7
+ require 'cocoapods-xcframework/muti_frameworker'
8
+
9
+
10
+ #这个放在最后一个
11
+ require 'cocoapods-xcframework/command'
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe Command::XCFramework do
5
+ describe 'CLAide' do
6
+ it 'registers it self' do
7
+ Command.parse(%w{ xcframework }).should.be.instance_of Command::XCFramework
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
3
+ $:.unshift((ROOT + 'lib').to_s)
4
+ $:.unshift((ROOT + 'spec').to_s)
5
+
6
+ require 'bundler/setup'
7
+ require 'bacon'
8
+ require 'mocha-on-bacon'
9
+ require 'pretty_bacon'
10
+ require 'pathname'
11
+ require 'cocoapods'
12
+
13
+ Mocha::Configuration.prevent(:stubbing_non_existent_method)
14
+
15
+ require 'cocoapods_plugin'
16
+
17
+ #-----------------------------------------------------------------------------#
18
+
19
+ module Pod
20
+
21
+ # Disable the wrapping so the output is deterministic in the tests.
22
+ #
23
+ UI.disable_wrap = true
24
+
25
+ # Redirects the messages to an internal store.
26
+ #
27
+ module UI
28
+ @output = ''
29
+ @warnings = ''
30
+
31
+ class << self
32
+ attr_accessor :output
33
+ attr_accessor :warnings
34
+
35
+ def puts(message = '')
36
+ @output << "#{message}\n"
37
+ end
38
+
39
+ def warn(message = '', actions = [])
40
+ @warnings << "#{message}\n"
41
+ end
42
+
43
+ def print(message)
44
+ @output << message
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ #-----------------------------------------------------------------------------#
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-bb-xcframework
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - humin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-10-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cocoapods
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.10.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.10.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.3'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ description: 把podspec打包成xcframework的小工具。packager pod to a xcframework
62
+ email:
63
+ - humin1102@126.com
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - LICENSE.txt
69
+ - README.md
70
+ - lib/cocoapods-xcframework.rb
71
+ - lib/cocoapods-xcframework/command.rb
72
+ - lib/cocoapods-xcframework/command/muti_xcframework.rb
73
+ - lib/cocoapods-xcframework/command/xcframework.rb
74
+ - lib/cocoapods-xcframework/config.rb
75
+ - lib/cocoapods-xcframework/frameworker.rb
76
+ - lib/cocoapods-xcframework/gem_version.rb
77
+ - lib/cocoapods-xcframework/muti_frameworker.rb
78
+ - lib/cocoapods-xcframework/util.rb
79
+ - lib/cocoapods-xcframework/util/cmd.rb
80
+ - lib/cocoapods-xcframework/util/dir_util.rb
81
+ - lib/cocoapods-xcframework/util/error_util.rb
82
+ - lib/cocoapods-xcframework/util/git_util.rb
83
+ - lib/cocoapods-xcframework/util/pod_util.rb
84
+ - lib/cocoapods-xcframework/xbuilder.rb
85
+ - lib/cocoapods-xcframework/xbuilder/xcode_xbuild.rb
86
+ - lib/cocoapods-xcframework/xbuilder/xcodeproj_helper.rb
87
+ - lib/cocoapods_plugin.rb
88
+ - spec/command/framework_spec.rb
89
+ - spec/spec_helper.rb
90
+ homepage: https://github.com/humin1102/cocoapods-bb-xcframework
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubygems_version: 3.1.4
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: 把podspec打包成xcframework的小工具。packager pod to a xcframework
113
+ test_files:
114
+ - spec/command/framework_spec.rb
115
+ - spec/spec_helper.rb