cocoapods-headermap 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +13 -0
- data/Rakefile +13 -0
- data/cocoapods-headermap.gemspec +23 -0
- data/lib/cocoapods-headermap/build_settings.rb +63 -0
- data/lib/cocoapods-headermap/command/headermap.rb +44 -0
- data/lib/cocoapods-headermap/command.rb +1 -0
- data/lib/cocoapods-headermap/configuration.rb +36 -0
- data/lib/cocoapods-headermap/file_references_installer.rb +47 -0
- data/lib/cocoapods-headermap/gem_version.rb +3 -0
- data/lib/cocoapods-headermap/header_maps_generator.rb +168 -0
- data/lib/cocoapods-headermap/headers_store.rb +128 -0
- data/lib/cocoapods-headermap/installer.rb +31 -0
- data/lib/cocoapods-headermap/multi_pods_project_generator.rb +46 -0
- data/lib/cocoapods-headermap/pod_target.rb +24 -0
- data/lib/cocoapods-headermap/sandbox.rb +12 -0
- data/lib/cocoapods-headermap/single_pods_project_generator.rb +29 -0
- data/lib/cocoapods-headermap.rb +1 -0
- data/lib/cocoapods_plugin.rb +24 -0
- data/spec/command/headermap_spec.rb +12 -0
- data/spec/spec_helper.rb +50 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 03773ea3588ccfd9fc4f5be042da14a89b41134922afa52c7eec230370014a06
|
4
|
+
data.tar.gz: b13fe6e18cf5571eefdc4314bccd88106d39442fcbaded7906a1e7c2690b5a03
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9ade511448e2ab9b3d380604a1114ab9eb36120847ad2f37867102297cdf06589580e148f528b1df177c9f5700053372735f005c7adc52fa09e416e73d9670bc
|
7
|
+
data.tar.gz: eee532c7e86bfb62dcb4fc0839e077c23e3546d9d100c9f5174277ec495c25d498750d4661cd9190539bee5509943bc86a09d4fafbd3bac5fd07b32b5013f435
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2021 menttofly <1028365614@qq.com>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# cocoapods-headermap
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/cocoapods-headermap.svg)](https://badge.fury.io/rb/cocoapods-headermap)
|
4
|
+
|
5
|
+
A description of cocoapods-headermap.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
$ gem install cocoapods-headermap
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
$ pod spec headermap POD_NAME
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cocoapods-headermap/gem_version.rb'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'cocoapods-headermap'
|
8
|
+
spec.version = CocoapodsHeadermap::VERSION
|
9
|
+
spec.authors = ['menttofly']
|
10
|
+
spec.email = ['1028365614@qq.com']
|
11
|
+
spec.description = %q{Improve Xcode compilation speed based on Header Maps.}
|
12
|
+
spec.summary = %q{Generate header maps file instead of creating soft link during pod installation. Therefore, file IO can be reduced during the build process and the search speed of header files can be improved.}
|
13
|
+
spec.homepage = 'https://github.com/'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'cocoapods-headermap/headers_store'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Target
|
5
|
+
class BuildSettings
|
6
|
+
class PodTargetSettings < BuildSettings
|
7
|
+
|
8
|
+
# Call `define_build_settings_method` with a given block in order to disable sorting.
|
9
|
+
define_build_settings_method :header_search_paths, :build_setting => true, :memoized => true, :sorted => false do
|
10
|
+
paths = target.header_search_paths(:include_dependent_targets_for_test_spec => test_xcconfig? && non_library_spec, :include_dependent_targets_for_app_spec => app_xcconfig? && non_library_spec, :configuration => @configuration)
|
11
|
+
|
12
|
+
dependent_vendored_xcframeworks = []
|
13
|
+
dependent_vendored_xcframeworks.concat vendored_xcframeworks
|
14
|
+
dependent_vendored_xcframeworks.concat dependent_targets.flat_map { |pt| pt.build_settings[@configuration].vendored_xcframeworks }
|
15
|
+
paths.concat dependent_vendored_xcframeworks.
|
16
|
+
select { |xcf| xcf.build_type.static_library? }.
|
17
|
+
map { |xcf| "#{BuildSettings.xcframework_intermediate_dir(xcf)}/Headers" }.
|
18
|
+
compact
|
19
|
+
paths
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Array<String>] The path of `hmap` file for this project
|
23
|
+
define_build_settings_method :user_header_search_paths, :build_setting => true, :memoized => true, :sorted => false do
|
24
|
+
paths = ["${PODS_ROOT}/#{target.sandbox.headers_root.basename}/#{Sandbox::POD_PROJECT_HEADERS}.hmap"]
|
25
|
+
paths
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class AggregateTargetSettings < BuildSettings
|
30
|
+
# # Call `define_build_settings_method` with a given block in order to disable sorting paths.
|
31
|
+
define_build_settings_method :header_search_paths, :build_setting => true, :memoized => true, :sorted => false, :uniqued => true do
|
32
|
+
paths = []
|
33
|
+
|
34
|
+
if !target.build_as_framework? || !pod_targets.all?(&:should_build?)
|
35
|
+
paths.concat target.sandbox.public_headers.search_paths(target.platform)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Make frameworks headers discoverable with any syntax (quotes,
|
39
|
+
# brackets, @import, etc.)
|
40
|
+
paths.concat pod_targets.
|
41
|
+
select { |pt| pt.build_as_framework? && pt.should_build? }.
|
42
|
+
map { |pt| pt.build_settings[@configuration].framework_header_search_path }
|
43
|
+
|
44
|
+
xcframework_library_headers = pod_targets.flat_map { |pt| pt.build_settings[@configuration].vendored_xcframeworks }.
|
45
|
+
select { |xcf| xcf.build_type.static_library? }.
|
46
|
+
map { |xcf| "#{BuildSettings.xcframework_intermediate_dir(xcf)}/Headers" }.
|
47
|
+
compact
|
48
|
+
|
49
|
+
paths.concat xcframework_library_headers
|
50
|
+
paths.concat target.search_paths_aggregate_targets.flat_map { |at| at.build_settings(configuration_name).header_search_paths }
|
51
|
+
paths
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Array<String>] The path of `hmap` file for this project
|
55
|
+
define_build_settings_method :user_header_search_paths, :build_setting => true, :memoized => true, :sorted => false do
|
56
|
+
paths = ["${PODS_ROOT}/#{target.sandbox.headers_root.basename}/#{Sandbox::POD_PROJECT_HEADERS}.hmap"]
|
57
|
+
paths
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,44 @@
|
|
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 Headermap < Command
|
21
|
+
self.summary = 'Short description of cocoapods-headermap.'
|
22
|
+
|
23
|
+
self.description = <<-DESC
|
24
|
+
Longer description of cocoapods-headermap.
|
25
|
+
DESC
|
26
|
+
|
27
|
+
self.arguments = 'NAME'
|
28
|
+
|
29
|
+
def initialize(argv)
|
30
|
+
@name = argv.shift_argument
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate!
|
35
|
+
super
|
36
|
+
help! 'A Pod name is required.' unless @name
|
37
|
+
end
|
38
|
+
|
39
|
+
def run
|
40
|
+
UI.puts "Add your implementation for the cocoapods-headermap plugin in #{__FILE__}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cocoapods-headermap/command/headermap'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Pod
|
2
|
+
class Configuration
|
3
|
+
# 保存 `$PODS_ROOT/Headers` 目录下所有 Header Search Paths
|
4
|
+
# 始终保留头文件 symlink!!!
|
5
|
+
# 默认为 false
|
6
|
+
@keep_symlink_headers = false
|
7
|
+
|
8
|
+
# 始终保留 symlink & Header Search Paths 的组件
|
9
|
+
# 在 keep_symlink_headers 为 false 时有效
|
10
|
+
@always_keep_symlink_headers = []
|
11
|
+
|
12
|
+
# Multi Pods Project 是否生成 Single Pods Target 不带命名空间的 headers 全集
|
13
|
+
# 默认为 false(暂时无效)
|
14
|
+
@use_legacy_project_headers = false
|
15
|
+
|
16
|
+
class << self
|
17
|
+
attr_reader :keep_symlink_headers
|
18
|
+
def keep_symlink_headers=(keep_symlink_headers)
|
19
|
+
raise Informative, "[cocoapods-headermap]: Expecting Boolean type for `:keep_symlink_headers`!" unless [true, false].include?(keep_symlink_headers)
|
20
|
+
@keep_symlink_headers = keep_symlink_headers
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :always_keep_symlink_headers
|
24
|
+
def always_keep_symlink_headers=(always_keep_symlink_headers)
|
25
|
+
raise Informative, "[cocoapods-headermap]: Expecting array type for `:always_keep_symlink_headers`!" unless always_keep_symlink_headers.is_a?(Array)
|
26
|
+
@always_keep_symlink_headers.concat always_keep_symlink_headers
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :use_legacy_project_headers
|
30
|
+
def use_legacy_project_headers=(use_legacy_project_headers)
|
31
|
+
raise Informative, "[cocoapods-headermap]: Expecting Boolean type for `:use_legacy_project_headers`!" unless [true, false].include?(use_legacy_project_headers)
|
32
|
+
@use_legacy_project_headers = use_legacy_project_headers
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'cocoapods-headermap/header_maps_generator'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Installer
|
6
|
+
class Xcode
|
7
|
+
class PodsProjectGenerator
|
8
|
+
class FileReferencesInstaller
|
9
|
+
|
10
|
+
def link_headers
|
11
|
+
UI.message '- Linking headers' do
|
12
|
+
pod_targets.each do |pod_target|
|
13
|
+
next if pod_target.build_as_framework? && pod_target.should_build?
|
14
|
+
sync_target_info(pod_target)
|
15
|
+
create_symlink_reference(pod_target)
|
16
|
+
HeaderMapsGenerator.merge_target_headers(pod_target)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def sync_target_info(pod_target)
|
22
|
+
# pod_target.build_headers.user_clang_module = true if pod_target.file_accessors.first.module_map
|
23
|
+
pod_target.build_headers.target_name = pod_target.pod_name
|
24
|
+
sandbox.public_headers.target_name = pod_target.pod_name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates the link to the headers of the Pod in the sandbox.
|
28
|
+
def create_symlink_reference(pod_target)
|
29
|
+
pod_target_header_mappings = pod_target.header_mappings_by_file_accessor.values
|
30
|
+
pod_target_header_mappings.each do |header_mappings|
|
31
|
+
header_mappings.each do |namespaced_path, files|
|
32
|
+
pod_target.build_headers.add_files(namespaced_path, files)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
public_header_mappings = pod_target.public_header_mappings_by_file_accessor.values
|
37
|
+
public_header_mappings.each do |header_mappings|
|
38
|
+
header_mappings.each do |namespaced_path, files|
|
39
|
+
sandbox.public_headers.add_files(namespaced_path, files)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
module Pod
|
2
|
+
class HeaderMapsGenerator
|
3
|
+
|
4
|
+
# 所有 target 共享的头文件信息,不带命名空间或路径
|
5
|
+
@all_project_headers = {}
|
6
|
+
|
7
|
+
# 所有 target 公共 header 信息,带命名空间或路径
|
8
|
+
@all_targets_headers = {}
|
9
|
+
|
10
|
+
# Maintains the headers cache for project.
|
11
|
+
@headers_cache = nil
|
12
|
+
|
13
|
+
# Record headers orgnized by target on order to adapt the situation of file change in some targets.
|
14
|
+
@project_headers_by_target = {}
|
15
|
+
@targets_headers_by_target = {}
|
16
|
+
|
17
|
+
# A set of pod target names that were deleted.
|
18
|
+
# Only use for `incremental_installation` enabled.
|
19
|
+
@deleted_pod_targets = Set.new
|
20
|
+
|
21
|
+
class << self
|
22
|
+
attr_accessor :all_project_headers, :all_targets_headers
|
23
|
+
attr_accessor :project_headers_by_target, :targets_headers_by_target
|
24
|
+
attr_accessor :headers_cache
|
25
|
+
attr_reader :deleted_pod_targets
|
26
|
+
|
27
|
+
def deleted_pod_targets=(deleted_pod_target)
|
28
|
+
return if deleted_pod_target.nil?
|
29
|
+
deleted_pod_targets << deleted_pod_target
|
30
|
+
end
|
31
|
+
|
32
|
+
# Generate header map files for all project and targets.
|
33
|
+
def generate!(sandbox, is_legacy_target)
|
34
|
+
UI.puts "[cocoapods-headermap]: Generating header maps.."
|
35
|
+
# 跨组件引用的 public header
|
36
|
+
generate_header_files(sandbox.headers_root, all_targets_headers, Sandbox::POD_TARGETS_HEADERS)
|
37
|
+
# 组件内部使用的 private header
|
38
|
+
project_headers_by_target.each do |target_name, project_headers|
|
39
|
+
generate_header_files(sandbox.headers_root + "Private/#{target_name}", project_headers, target_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# return if !is_legacy_target || !Configuration.use_legacy_project_headers
|
43
|
+
generate_header_files(sandbox.headers_root, all_project_headers, Sandbox::POD_PROJECT_HEADERS)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Store headers cache to sandbox.
|
47
|
+
def store_cache_to(path)
|
48
|
+
return unless headers_cache
|
49
|
+
headers_cache.update_headers!(project_headers_by_target, targets_headers_by_target)
|
50
|
+
headers_cache.save_as(path)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Fetch headers cache from sandbox if `incremental_installation` enabled.
|
54
|
+
def analyze_cache_from(path, regenerate_pod_targets)
|
55
|
+
UI.message 'Analyzing Headers Cache' do
|
56
|
+
self.headers_cache = HeaderMapsCache.from_file(path)
|
57
|
+
# Regenerate pod target must remove cache first.
|
58
|
+
unless regenerate_pod_targets.nil? || regenerate_pod_targets.empty?
|
59
|
+
regenerate_pod_targets.each do |pod_target|
|
60
|
+
headers_cache.project_headers_cache.delete(pod_target.pod_name)
|
61
|
+
headers_cache.targets_headers_cache.delete(pod_target.pod_name)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Pods that were deleted need to be removed from cache.
|
66
|
+
unless deleted_pod_targets.empty?
|
67
|
+
deleted_pod_targets.each do |pod_name|
|
68
|
+
headers_cache.project_headers_cache.delete(pod_name)
|
69
|
+
headers_cache.targets_headers_cache.delete(pod_name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
self.project_headers_by_target = headers_cache.project_headers_cache
|
74
|
+
self.targets_headers_by_target = headers_cache.targets_headers_cache
|
75
|
+
|
76
|
+
# 将恢复的缓存和当前重新生成的 target 合并
|
77
|
+
project_headers_by_target.each do |pod_target, project_headers|
|
78
|
+
all_project_headers.merge!(project_headers) { |key, pre, new| pre } unless project_headers.empty?
|
79
|
+
end
|
80
|
+
targets_headers_by_target.each do |pod_target, targets_headers|
|
81
|
+
all_targets_headers.merge!(targets_headers) unless targets_headers.empty?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Merge the headers for every target and the whole project.
|
87
|
+
# If there is a header file with the same name between different pods, it will keep the previous one.
|
88
|
+
def merge_target_headers(pod_target)
|
89
|
+
pod_project_headers = pod_target.build_headers.pod_project_headers
|
90
|
+
all_project_headers.merge!(pod_project_headers) { |key, pre, new| pre } unless pod_project_headers.empty?
|
91
|
+
|
92
|
+
pod_target_headers = pod_target.build_headers.pod_target_headers
|
93
|
+
all_targets_headers.merge!(pod_target_headers) unless pod_target_headers.empty?
|
94
|
+
|
95
|
+
# Store original data structure of header ordered by target.
|
96
|
+
project_headers_by_target[pod_target.pod_name] = pod_project_headers unless pod_project_headers.empty?
|
97
|
+
targets_headers_by_target[pod_target.pod_name] = pod_target_headers unless pod_target_headers.empty?
|
98
|
+
end
|
99
|
+
|
100
|
+
# Generate `hmap` files for the project of `Pods`.
|
101
|
+
# Pods-all-target-headers.hmap 作为组件 public hmap
|
102
|
+
# Pods-project-headers.hmap 作为不规范 import 组件的兼容 hmap
|
103
|
+
# target_name.hmap 作为组件 private hmap
|
104
|
+
def generate_header_files(dirname, headers, file_name)
|
105
|
+
return if headers.nil? || headers.empty?
|
106
|
+
|
107
|
+
header_json_path = dirname + "#{file_name}.json"
|
108
|
+
File.open(header_json_path, "w") do |f|
|
109
|
+
f.write(JSON.pretty_generate(headers))
|
110
|
+
end
|
111
|
+
json_to_hmap(header_json_path)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Convert json file to headermap file.
|
115
|
+
def json_to_hmap(json_path)
|
116
|
+
install_brew_package(1) if `which hmap`.empty?
|
117
|
+
|
118
|
+
hmap_path = json_path.sub_ext(".hmap")
|
119
|
+
`hmap convert #{json_path} #{hmap_path}`
|
120
|
+
|
121
|
+
File.delete(json_path) if File.exist?(json_path)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Install swift headermap tool less than three times if neccessary.
|
125
|
+
def install_brew_package(retry_count)
|
126
|
+
raise Informative, "[cocoapods-headermap]: Excuting `brew install milend/taps/hmap` error!" if retry_count > 3
|
127
|
+
if_install_success = system "brew install milend/taps/hmap"
|
128
|
+
install_brew_package(retry_count + 1) unless if_install_success
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Cache header maps content for `incremental_installation` option
|
134
|
+
class HeaderMapsCache
|
135
|
+
attr_reader :project_headers_cache, :targets_headers_cache
|
136
|
+
|
137
|
+
def initialize(project_headers_cache = {}, targets_headers_cache = {})
|
138
|
+
@project_headers_cache = project_headers_cache
|
139
|
+
@targets_headers_cache = targets_headers_cache
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.from_file(path)
|
143
|
+
return HeaderMapsCache.new unless File.exist?(path)
|
144
|
+
|
145
|
+
yaml_content = YAMLHelper.load_file(path)
|
146
|
+
project_headers_cache = yaml_content.fetch("PROJECT_HEADERS", {})
|
147
|
+
targets_headers_cache = yaml_content.fetch("TARGETS_HEADERS", {})
|
148
|
+
new(project_headers_cache, targets_headers_cache)
|
149
|
+
end
|
150
|
+
|
151
|
+
def update_headers!(project_headers_by_target, targets_headers_by_target)
|
152
|
+
@project_headers_cache = project_headers_by_target
|
153
|
+
@targets_headers_cache = targets_headers_by_target
|
154
|
+
end
|
155
|
+
|
156
|
+
def to_hash
|
157
|
+
yaml_content = {}
|
158
|
+
yaml_content["PROJECT_HEADERS"] = project_headers_cache if project_headers_cache
|
159
|
+
yaml_content["TARGETS_HEADERS"] = targets_headers_cache if targets_headers_cache
|
160
|
+
yaml_content
|
161
|
+
end
|
162
|
+
|
163
|
+
def save_as(path)
|
164
|
+
Pathname(path).dirname.mkpath
|
165
|
+
Sandbox.update_changed_file(path, YAMLHelper.convert(to_hash))
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'cocoapods-headermap/configuration'
|
3
|
+
|
4
|
+
module Pod
|
5
|
+
class Sandbox
|
6
|
+
POD_TARGETS_HEADERS = "Pods-all-target-headers"
|
7
|
+
POD_PROJECT_HEADERS = "Legacy-project-headers"
|
8
|
+
|
9
|
+
class HeadersStore
|
10
|
+
# Implememt the effect of tuples.
|
11
|
+
SYMLINK_REFERENCE = Struct.new(:namespace, :relative_header_path)
|
12
|
+
|
13
|
+
alias_method :new_add_files, :add_files
|
14
|
+
alias_method :new_search_paths, :search_paths
|
15
|
+
|
16
|
+
# 保存当前 target name
|
17
|
+
attr_reader :target_name
|
18
|
+
def target_name=(target_name)
|
19
|
+
@target_name = target_name
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Hash{Pathname => Hash{String, String}}] public headers 映射
|
23
|
+
def pod_target_headers
|
24
|
+
@pod_target_headers ||= {}
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Hash{Pathname => Hash{String, String}}] private headers 映射
|
28
|
+
def pod_project_headers
|
29
|
+
@pod_project_headers ||= {}
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Array<Pathname>] Generate every part of namespace recusively.
|
33
|
+
# Passing ["WCDB", "include", "source"] return the following content:
|
34
|
+
#
|
35
|
+
# ["WCDB/include/source", "include/source", "source"]
|
36
|
+
def purge_shared_keys(parts, index)
|
37
|
+
return [] if index == parts.length
|
38
|
+
res = [parts.slice(index, parts.length - index).reduce(Pathname.new(""), :+)]
|
39
|
+
res.concat(purge_shared_keys(parts, index + 1))
|
40
|
+
res
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_files(namespace, relative_header_paths)
|
44
|
+
root.join(namespace).mkpath unless relative_header_paths.empty?
|
45
|
+
|
46
|
+
new_add_files(namespace, relative_header_paths)
|
47
|
+
return if @visibility_scope == :public
|
48
|
+
|
49
|
+
list = namespace.each_filename.to_a
|
50
|
+
parts = purge_shared_keys(list, 0)
|
51
|
+
relative_header_paths.map do |relative_header_path|
|
52
|
+
add_targets_headers(parts, namespace, relative_header_path)
|
53
|
+
add_project_headers(relative_header_path)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# 保存带命名空间的 headers 与其 symlink 路径的映射
|
58
|
+
# 结构如下:
|
59
|
+
# {"AFNetworking/AFNetworking.h" => "$PODS_ROOT/Headers/Public/AFNetworking/AFNetworking.h"}
|
60
|
+
#
|
61
|
+
# 用于生成 public hmap,并写入 `HEADER_SEARCH_PATH`,可使用 <Pod/header.h>、"Pod/head.h" 引用
|
62
|
+
# 如果 `namespace/header` 字典序更大,将覆盖之前的 path 值
|
63
|
+
def add_targets_headers(parts, namespace, relative_header_path)
|
64
|
+
|
65
|
+
# public header,使用头文件 symlink 路径
|
66
|
+
header_source = root + namespace + relative_header_path.basename
|
67
|
+
header_section = {
|
68
|
+
"prefix" => "#{header_source.dirname.to_s}/",
|
69
|
+
"suffix" => header_source.basename.to_s
|
70
|
+
}
|
71
|
+
|
72
|
+
parts.each do |part|
|
73
|
+
key = "#{part}/#{header_source.basename}"
|
74
|
+
next if pod_target_headers.key?(key) && (pod_target_headers[key]["prefix"] <=> "#{header_source.dirname.to_s}/") == 1
|
75
|
+
pod_target_headers[key] = header_section
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# 保存不带命名空间的 header 与其原始路径的映射
|
80
|
+
# 结构如下:
|
81
|
+
#
|
82
|
+
# {"AFNetworking" => "$PODS_ROOT/AFNetworking/AFNetworking.h"}
|
83
|
+
#
|
84
|
+
# 用于生成 private hmap,并写入 `HEADER_SEARCH_PATH`,在组件内部 *.{m,c,cpp} 使用 <header.h>、"head.h" 引用
|
85
|
+
# 可选生成跨组件的 shared hmap,写入 `USER_HEADER_SEARCH_PATH`,规避不规范 un-namespaced 引用
|
86
|
+
def add_project_headers(relative_header_path)
|
87
|
+
|
88
|
+
# private header,使用头文件原始路径
|
89
|
+
header_source = sandbox.root + relative_header_path
|
90
|
+
|
91
|
+
source_file_name = header_source.basename.to_s
|
92
|
+
header_section = {
|
93
|
+
"prefix" => "#{header_source.dirname.to_s}/",
|
94
|
+
"suffix" => source_file_name.to_s
|
95
|
+
}
|
96
|
+
|
97
|
+
return if pod_project_headers.key?(source_file_name) && (pod_project_headers[source_file_name]["prefix"] <=> "#{header_source.dirname.to_s}/") == 1
|
98
|
+
pod_project_headers[source_file_name] = header_section
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Array<String>] Public hmap + Private hmap
|
102
|
+
def search_paths(platform, target_name = nil, use_modular_headers = false)
|
103
|
+
visibility_dir = root.relative_path_from(sandbox.root)
|
104
|
+
headers_dir = visibility_dir.dirname
|
105
|
+
|
106
|
+
paths = []
|
107
|
+
paths << "${PODS_ROOT}/#{visibility_dir}/#{@target_name}/#{@target_name}.hmap" if @visibility_scope == :private
|
108
|
+
paths << "${PODS_ROOT}/#{headers_dir}/#{Sandbox::POD_TARGETS_HEADERS}.hmap"
|
109
|
+
|
110
|
+
# 保留 CocoaPods 自动写入的 symlink 路径
|
111
|
+
if Configuration.keep_symlink_headers
|
112
|
+
paths.concat(new_search_paths(platform, target_name, use_modular_headers))
|
113
|
+
else
|
114
|
+
if Configuration.always_keep_symlink_headers.include?(target_name)
|
115
|
+
paths.concat(new_search_paths(platform, target_name, use_modular_headers))
|
116
|
+
end
|
117
|
+
end
|
118
|
+
paths
|
119
|
+
end
|
120
|
+
|
121
|
+
# Clean `$PODS_ROOT/Headers` directory.
|
122
|
+
def rm_headers_root!
|
123
|
+
return if @visibility_scope == :private
|
124
|
+
FileUtils.rm_rf(Dir.glob(sandbox.headers_root + "**" + "*.hmap"))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'cocoapods-headermap/configuration'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Installer
|
5
|
+
alias_method :new_run_podfile_post_install_hooks, :run_podfile_post_install_hooks
|
6
|
+
alias_method :new_clean_sandbox, :clean_sandbox
|
7
|
+
|
8
|
+
def run_podfile_post_install_hooks
|
9
|
+
# 开启 Multi Pods Project 选项
|
10
|
+
if podfile.installation_options.generate_multiple_pod_projects
|
11
|
+
@pod_target_subprojects.flat_map { |project| project.targets }.each do |target|
|
12
|
+
target.build_configurations.each do |config|
|
13
|
+
config.build_settings['USE_HEADERMAP'] = 'NO'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
else
|
17
|
+
@pods_project.targets.each do |target|
|
18
|
+
target.build_configurations.each do |config|
|
19
|
+
config.build_settings['USE_HEADERMAP'] = 'NO'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
new_run_podfile_post_install_hooks
|
24
|
+
end
|
25
|
+
|
26
|
+
def clean_sandbox(pod_targets)
|
27
|
+
new_clean_sandbox(pod_targets)
|
28
|
+
sandbox.public_headers.rm_headers_root!
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'cocoapods-headermap/header_maps_generator'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Installer
|
5
|
+
class Xcode
|
6
|
+
class MultiPodsProjectGenerator < PodsProjectGenerator
|
7
|
+
def generate!
|
8
|
+
# Generate container Pods.xcodeproj.
|
9
|
+
container_project = create_container_project(aggregate_targets, sandbox.project_path)
|
10
|
+
|
11
|
+
project_paths_by_pod_targets = pod_targets.group_by do |pod_target|
|
12
|
+
sandbox.pod_target_project_path(pod_target.project_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
# If `incremental_installation` enabled, read cache from sanbox.
|
16
|
+
if installation_options.incremental_installation
|
17
|
+
HeaderMapsGenerator.analyze_cache_from(project_headers_cache_path, pod_targets)
|
18
|
+
end
|
19
|
+
|
20
|
+
projects_by_pod_targets = Hash[project_paths_by_pod_targets.map do |project_path, pod_targets|
|
21
|
+
project = create_pods_project(pod_targets, project_path, container_project)
|
22
|
+
[project, pod_targets]
|
23
|
+
end]
|
24
|
+
|
25
|
+
# Generate header map files and cache if neccessary.
|
26
|
+
HeaderMapsGenerator.generate!(sandbox, false)
|
27
|
+
HeaderMapsGenerator.store_cache_to(project_headers_cache_path)
|
28
|
+
|
29
|
+
# Note: We must call `install_file_references` on all pod targets before installing them.
|
30
|
+
pod_target_installation_results = install_all_pod_targets(projects_by_pod_targets)
|
31
|
+
aggregate_target_installation_results = install_aggregate_targets_into_project(container_project, aggregate_targets)
|
32
|
+
target_installation_results = InstallationResults.new(pod_target_installation_results, aggregate_target_installation_results)
|
33
|
+
|
34
|
+
integrate_targets(target_installation_results.pod_target_installation_results)
|
35
|
+
wire_target_dependencies(target_installation_results)
|
36
|
+
PodsProjectGeneratorResult.new(container_project, projects_by_pod_targets, target_installation_results)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Project headers cache path.
|
40
|
+
def project_headers_cache_path
|
41
|
+
sandbox.root.join('.project_cache', 'project_headers_cache.yaml')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Pod
|
2
|
+
class PodTarget < Target
|
3
|
+
alias_method :new_header_search_paths, :header_search_paths
|
4
|
+
|
5
|
+
# Move the mapping files to the top of the array by sorting.
|
6
|
+
#
|
7
|
+
# Before sort:
|
8
|
+
# ["${PODS_ROOT}/Headers/Private/AFNetworking.hmap",
|
9
|
+
# "${PODS_ROOT}/Headers/Private/AFNetworking",
|
10
|
+
# "${PODS_ROOT}/Headers/Public/Public-Header-Maps.hmap",
|
11
|
+
# "${PODS_ROOT}/Headers/Public/AFNetworking"]
|
12
|
+
#
|
13
|
+
# After sort:
|
14
|
+
# ["${PODS_ROOT}/Headers/Private/AFNetworking.hmap",
|
15
|
+
# "${PODS_ROOT}/Headers/Public/Public-Header-Maps.hmap",
|
16
|
+
# "${PODS_ROOT}/Headers/Private/AFNetworking",
|
17
|
+
# "${PODS_ROOT}/Headers/Public/AFNetworking"]
|
18
|
+
def header_search_paths(include_dependent_targets_for_test_spec: nil, include_dependent_targets_for_app_spec: nil, include_private_headers: true, configuration: nil)
|
19
|
+
paths = new_header_search_paths(:include_dependent_targets_for_test_spec => include_dependent_targets_for_test_spec, :include_dependent_targets_for_app_spec => include_dependent_targets_for_app_spec, :include_private_headers => include_private_headers, :configuration => configuration)
|
20
|
+
paths.sort_by { |i| i.split(".").last == "hmap" ? 0 : 1 }
|
21
|
+
paths
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'cocoapods-headermap/header_maps_generator'
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
class Installer
|
5
|
+
class Xcode
|
6
|
+
class SinglePodsProjectGenerator < PodsProjectGenerator
|
7
|
+
def generate!
|
8
|
+
project_path = sandbox.project_path
|
9
|
+
platforms = aggregate_targets.map(&:platform)
|
10
|
+
project_generator = ProjectGenerator.new(sandbox, project_path, pod_targets, build_configurations,
|
11
|
+
platforms, project_object_version, config.podfile_path)
|
12
|
+
project = project_generator.generate!
|
13
|
+
install_file_references(project, pod_targets)
|
14
|
+
|
15
|
+
# Generate header map files.
|
16
|
+
HeaderMapsGenerator.generate!(sandbox, true)
|
17
|
+
|
18
|
+
pod_target_installation_results = install_all_pod_targets(project, pod_targets)
|
19
|
+
aggregate_target_installation_results = install_aggregate_targets(project, aggregate_targets)
|
20
|
+
target_installation_results = InstallationResults.new(pod_target_installation_results, aggregate_target_installation_results)
|
21
|
+
|
22
|
+
integrate_targets(target_installation_results.pod_target_installation_results)
|
23
|
+
wire_target_dependencies(target_installation_results)
|
24
|
+
PodsProjectGeneratorResult.new(project, {}, target_installation_results)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cocoapods-headermap/gem_version'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# require 'cocoapods-headermap/command'
|
2
|
+
|
3
|
+
module CocoapodsHmapGod
|
4
|
+
Pod::HooksManager.register("cocoapods-headermap", :pre_install) do |context, options|
|
5
|
+
|
6
|
+
require 'cocoapods-headermap/build_settings'
|
7
|
+
require 'cocoapods-headermap/configuration'
|
8
|
+
require 'cocoapods-headermap/file_references_installer'
|
9
|
+
require 'cocoapods-headermap/headers_store'
|
10
|
+
require 'cocoapods-headermap/installer'
|
11
|
+
require 'cocoapods-headermap/multi_pods_project_generator'
|
12
|
+
require 'cocoapods-headermap/pod_target'
|
13
|
+
require 'cocoapods-headermap/sandbox'
|
14
|
+
require 'cocoapods-headermap/single_pods_project_generator'
|
15
|
+
|
16
|
+
Pod::Configuration.keep_symlink_headers = options[:keep_symlink_headers] if options.key?(:keep_symlink_headers)
|
17
|
+
Pod::Configuration.always_keep_symlink_headers = options[:always_keep_symlink_headers] if options.key?(:always_keep_symlink_headers)
|
18
|
+
end
|
19
|
+
|
20
|
+
Pod::HooksManager.register("cocoapods-hmap-god", :post_install) do |context|
|
21
|
+
# Hook `run_podfile_post_install_hooks` to change build settings rather than `:post_install`.
|
22
|
+
# The time to perform `:post_install` is right after the pod project is generated.
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
module Pod
|
4
|
+
describe Command::Headermap do
|
5
|
+
describe 'CLAide' do
|
6
|
+
it 'registers it self' do
|
7
|
+
Command.parse(%w{ headermap }).should.be.instance_of Command::Headermap
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -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,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cocoapods-headermap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- menttofly
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Improve Xcode compilation speed based on Header Maps.
|
42
|
+
email:
|
43
|
+
- 1028365614@qq.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- cocoapods-headermap.gemspec
|
54
|
+
- lib/cocoapods-headermap.rb
|
55
|
+
- lib/cocoapods-headermap/build_settings.rb
|
56
|
+
- lib/cocoapods-headermap/command.rb
|
57
|
+
- lib/cocoapods-headermap/command/headermap.rb
|
58
|
+
- lib/cocoapods-headermap/configuration.rb
|
59
|
+
- lib/cocoapods-headermap/file_references_installer.rb
|
60
|
+
- lib/cocoapods-headermap/gem_version.rb
|
61
|
+
- lib/cocoapods-headermap/header_maps_generator.rb
|
62
|
+
- lib/cocoapods-headermap/headers_store.rb
|
63
|
+
- lib/cocoapods-headermap/installer.rb
|
64
|
+
- lib/cocoapods-headermap/multi_pods_project_generator.rb
|
65
|
+
- lib/cocoapods-headermap/pod_target.rb
|
66
|
+
- lib/cocoapods-headermap/sandbox.rb
|
67
|
+
- lib/cocoapods-headermap/single_pods_project_generator.rb
|
68
|
+
- lib/cocoapods_plugin.rb
|
69
|
+
- spec/command/headermap_spec.rb
|
70
|
+
- spec/spec_helper.rb
|
71
|
+
homepage: https://github.com/
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubygems_version: 3.0.3
|
91
|
+
signing_key:
|
92
|
+
specification_version: 4
|
93
|
+
summary: Generate header maps file instead of creating soft link during pod installation.
|
94
|
+
Therefore, file IO can be reduced during the build process and the search speed
|
95
|
+
of header files can be improved.
|
96
|
+
test_files:
|
97
|
+
- spec/command/headermap_spec.rb
|
98
|
+
- spec/spec_helper.rb
|