cocoapods-mapfile 0.2.5 → 0.2.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -16
- data/lib/hmap/command/hmap_gen.rb +6 -3
- data/lib/hmap/command/hmap_reader.rb +10 -8
- data/lib/hmap/command/hmap_writer.rb +20 -12
- data/lib/hmap/constants.rb +32 -21
- data/lib/hmap/gem_version.rb +5 -0
- data/lib/hmap/helper/utils.rb +13 -4
- data/lib/hmap/hmap/hmap_bucketstr.rb +8 -0
- data/lib/hmap/hmap/hmap_reader.rb +2 -2
- data/lib/hmap/hmap/hmap_saver.rb +14 -40
- data/lib/hmap/hmap/hmap_struct.rb +13 -48
- data/lib/hmap/hmap/hmap_writer.rb +7 -4
- data/lib/hmap/hmap/mapfile.rb +6 -15
- data/lib/hmap/xc/header_entry.rb +15 -12
- data/lib/hmap/xc/pbx_helper.rb +11 -5
- data/lib/hmap/xc/resolver.rb +2 -2
- data/lib/hmap/xc/target/build_setting.rb +2 -7
- data/lib/hmap/xc/target/target.rb +9 -20
- data/lib/hmap/xc/target/target_context.rb +5 -4
- data/lib/hmap/xc/target/target_helper.rb +21 -8
- data/lib/hmap/xc/target/target_vfs.rb +0 -1
- data/lib/hmap/xc/target/xcconfig.rb +290 -0
- data/lib/hmap/xc/target/xcconfig_helper.rb +7 -10
- data/lib/hmap/xc/workspace/project.rb +9 -6
- data/lib/hmap/xc/workspace/project_helper.rb +14 -14
- data/lib/hmap/xc/workspace/workspace.rb +10 -7
- data/lib/hmap.rb +1 -1
- metadata +19 -4
- data/lib/hmap/version.rb +0 -5
data/lib/hmap/xc/header_entry.rb
CHANGED
@@ -11,45 +11,48 @@ module HMap
|
|
11
11
|
def project_buckets
|
12
12
|
h_name = File.basename(path)
|
13
13
|
h_dir = File.dirname(path)
|
14
|
-
|
14
|
+
{ h_name => ["#{h_dir}/", h_name] }
|
15
15
|
end
|
16
16
|
|
17
17
|
def module_buckets(moudle_name)
|
18
18
|
h_name = File.basename(path)
|
19
19
|
module_p = "#{moudle_name}/"
|
20
|
-
|
20
|
+
{ h_name => [module_p, h_name] }
|
21
21
|
end
|
22
22
|
|
23
23
|
def full_module_buckets(moudle_name)
|
24
24
|
h_name = File.basename(path)
|
25
25
|
h_dir = File.dirname(path)
|
26
26
|
module_k = "#{moudle_name}/#{h_name}"
|
27
|
-
|
27
|
+
{ module_k => ["#{h_dir}/", h_name] }
|
28
28
|
end
|
29
29
|
|
30
30
|
def project_buckets_extra
|
31
31
|
h_name = File.basename(path)
|
32
32
|
h_dir = File.dirname(path)
|
33
|
-
buckets =
|
34
|
-
buckets
|
35
|
-
|
33
|
+
buckets = {}
|
34
|
+
buckets[h_name] = ["#{h_dir}/", h_name] unless extra_keys.include?(h_name)
|
35
|
+
extra_keys.each { |key| buckets[key] = ["#{h_dir}/", h_name] }
|
36
|
+
buckets
|
36
37
|
end
|
37
38
|
|
38
39
|
def module_buckets_extra(moudle_name)
|
39
40
|
h_name = File.basename(path)
|
40
41
|
module_p = "#{moudle_name}/"
|
41
|
-
buckets =
|
42
|
-
buckets
|
43
|
-
|
42
|
+
buckets = {}
|
43
|
+
buckets[h_name] = [module_p, h_name] unless extra_keys.include?(h_name)
|
44
|
+
extra_keys.each { |key| buckets[key] = [module_p, h_name] }
|
45
|
+
buckets
|
44
46
|
end
|
45
47
|
|
46
48
|
def full_module_buckets_extra(moudle_name)
|
47
49
|
h_name = File.basename(path)
|
48
50
|
h_dir = File.dirname(path)
|
49
51
|
module_k = "#{moudle_name}/#{h_name}"
|
50
|
-
buckets =
|
51
|
-
buckets
|
52
|
-
|
52
|
+
buckets = {}
|
53
|
+
buckets[module_k] = ["#{h_dir}/", h_name] unless extra_keys.include?(module_k)
|
54
|
+
extra_keys.each { |key| buckets[key] = ["#{h_dir}/", h_name] }
|
55
|
+
buckets
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
data/lib/hmap/xc/pbx_helper.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
1
|
module HMap
|
2
2
|
module PBXHelper
|
3
|
+
PBX_GROUP = '<group>'.freeze
|
4
|
+
PBX_SOURCE_ROOT = 'SOURCE_ROOT'.freeze
|
5
|
+
private_constant :PBX_GROUP, :PBX_SOURCE_ROOT
|
3
6
|
def self.get_groups(xct)
|
4
7
|
groups = xct.referrers.select { |e| e.is_a?(Constants::PBXGroup) } || []
|
5
8
|
groups += groups.flat_map { |g| get_groups(g) }
|
6
|
-
groups.compact
|
9
|
+
groups.compact
|
7
10
|
end
|
8
11
|
|
9
12
|
def self.group_paths(xct)
|
10
|
-
|
13
|
+
gs = get_groups(xct).reverse
|
14
|
+
ps = gs.map do |g|
|
11
15
|
s_hash = g.instance_variable_get('@simple_attributes_hash')
|
12
|
-
s_hash['path'] unless s_hash.nil?
|
16
|
+
s_hash['path'] unless s_hash.nil? && s_hash['sourceTree'] == PBX_GROUP
|
13
17
|
end.compact
|
14
18
|
File.join(*ps)
|
15
19
|
end
|
@@ -46,8 +50,10 @@ module HMap
|
|
46
50
|
p_path = File.dirname(project.path)
|
47
51
|
project.root_object.project_references.map do |sp|
|
48
52
|
ff = sp[:project_ref]
|
49
|
-
|
50
|
-
|
53
|
+
f_hash = ff.instance_variable_get('@simple_attributes_hash')
|
54
|
+
g_path = PBXHelper.group_paths(ff) if f_hash['sourceTree'] == PBX_GROUP
|
55
|
+
path = f_hash['path'] || ''
|
56
|
+
full_path = File.join(p_path, g_path || '', path)
|
51
57
|
Xcodeproj::Project.open(full_path)
|
52
58
|
end << project
|
53
59
|
end
|
data/lib/hmap/xc/resolver.rb
CHANGED
@@ -39,7 +39,7 @@ module HMap
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def project_build_settings(project_path)
|
42
|
-
targets =
|
42
|
+
targets = xcodebuild_project(project_path) || []
|
43
43
|
targets.first['buildSettings']
|
44
44
|
end
|
45
45
|
|
@@ -121,7 +121,7 @@ module HMap
|
|
121
121
|
command += %w[-json -showBuildSettings]
|
122
122
|
results = Executable.execute_command('xcodebuild', command, false)
|
123
123
|
index = results.index(/"action"/m)
|
124
|
-
reg = results[index
|
124
|
+
reg = results[index..]
|
125
125
|
reg = "[\n{\n#{reg}"
|
126
126
|
JSON.parse(reg) unless results.nil?
|
127
127
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'hmap/xc/target/target_vfs'
|
3
4
|
|
4
5
|
module HMap
|
@@ -63,13 +64,7 @@ module HMap
|
|
63
64
|
end
|
64
65
|
|
65
66
|
def symlink_to(path, need_platform)
|
66
|
-
|
67
|
-
|
68
|
-
filepath = Pathname.new(hmap_filepath(need_platform))
|
69
|
-
filepath.dirname.mkpath unless filepath.exist?
|
70
|
-
return if File.identical?(filepath, path)
|
71
|
-
|
72
|
-
filepath.make_symlink(path)
|
67
|
+
Utils.file_symlink_to(path, Pathname.new(hmap_filepath(need_platform)))
|
73
68
|
end
|
74
69
|
|
75
70
|
def write(data, need_platform)
|
@@ -28,7 +28,7 @@ module HMap
|
|
28
28
|
|
29
29
|
def save_hmap_settings!
|
30
30
|
xcconfig_paths.each do |path|
|
31
|
-
settings = Constants.instance.hmap_build_settings
|
31
|
+
settings = Constants.instance.hmap_build_settings(build_as_framework?)
|
32
32
|
XcodeprojHelper.new(path).add_build_settings_and_save(settings, use_origin: Resolver.instance.use_origin)
|
33
33
|
end
|
34
34
|
end
|
@@ -45,6 +45,14 @@ module HMap
|
|
45
45
|
@xcconfig_paths = target.build_configuration_list.build_configurations.flat_map do |configuration|
|
46
46
|
if configuration.is_a?(Constants::XCBuildConfiguration)
|
47
47
|
bcr = configuration.base_configuration_reference
|
48
|
+
# if bcr.nil?
|
49
|
+
# ab_path = Pathname(project.project_dir + "hmap-#{target_name}.#{configuration.name}.xcconfig")
|
50
|
+
# File.new(ab_path, 'w') unless ab_path.exist?
|
51
|
+
# xc_ref = target.project.new_file(ab_path)
|
52
|
+
# configuration.base_configuration_reference = xc_ref
|
53
|
+
# target.project.save
|
54
|
+
# ab_path
|
55
|
+
# else
|
48
56
|
unless bcr.nil?
|
49
57
|
s_path = PBXHelper.group_paths(bcr)
|
50
58
|
x = bcr.instance_variable_get('@simple_attributes_hash')['path'] || ''
|
@@ -52,25 +60,6 @@ module HMap
|
|
52
60
|
end
|
53
61
|
end
|
54
62
|
end.compact
|
55
|
-
# @xcconfig_paths = TargetConfiguration.new_from_xc(target, project.project_dir).map do |c|
|
56
|
-
# c.xcconfig_path unless c.xcconfig_path.nil?
|
57
|
-
# end.compact
|
58
|
-
# @xcconfig_paths = bc.map(&:xcconfig_path).compact
|
59
|
-
# xc_type = 'XCConfigurationList'
|
60
|
-
# xcs = target.build_configuration_list.build_configurations
|
61
|
-
# @xcconfig_paths = xcs.map do |xc|
|
62
|
-
# if xc.isa == xc_type
|
63
|
-
# xc_path = xc.instance_variable_get('@simple_attributes_hash')['path'] || ''
|
64
|
-
# { xc => File.join(project.project_dir, xc_path) }
|
65
|
-
# else
|
66
|
-
# # ab_path = Pathname(project.project_dir + "hmap-#{name}.#{xc.name}.xcconfig")
|
67
|
-
# # File.new(ab_path, 'w') unless ab_path.exist?
|
68
|
-
# # xc_ref = target.project.new_file(ab_path)
|
69
|
-
# # xc.base_configuration_reference = xc_ref
|
70
|
-
# # target.project.save
|
71
|
-
# # ab_path
|
72
|
-
# end
|
73
|
-
# end
|
74
63
|
end
|
75
64
|
end
|
76
65
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module HMap
|
4
|
-
class Target
|
4
|
+
class Target
|
5
5
|
class TargetContext < Context
|
6
6
|
attr_reader :product_name
|
7
|
+
|
7
8
|
def initialize(build_root, temp_dir, hmap_root, temp_name, build_dir, product_name, full_product_name, defines_modules, build_as_framework_swift)
|
8
9
|
super(build_root, temp_dir, hmap_root, temp_name, build_dir)
|
9
10
|
@full_product_name = full_product_name
|
@@ -11,15 +12,15 @@ module HMap
|
|
11
12
|
@defines_modules = defines_modules
|
12
13
|
@build_as_framework_swift = build_as_framework_swift
|
13
14
|
end
|
14
|
-
|
15
|
+
|
15
16
|
def build_as_framework_swift?
|
16
17
|
@build_as_framework_swift
|
17
18
|
end
|
18
|
-
|
19
|
+
|
19
20
|
def defines_modules?
|
20
21
|
@defines_modules
|
21
22
|
end
|
22
|
-
|
23
|
+
|
23
24
|
def build_path(platform)
|
24
25
|
path = super(platform)
|
25
26
|
File.join(path, @full_product_name)
|
@@ -17,28 +17,41 @@ module HMap
|
|
17
17
|
return if build_as_framework?
|
18
18
|
|
19
19
|
p_h = public_entrys + private_entrys
|
20
|
-
p_h.
|
20
|
+
p_h.inject({}) do |sum, entry|
|
21
|
+
sum.merge!(entry.full_module_buckets(product_name)) { |_, v1, _| v1 }
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
25
|
# all_targets include header full module path
|
24
26
|
define_method(:all_target_headers) do
|
25
27
|
p_h = public_entrys + private_entrys
|
26
|
-
p_h.
|
27
|
-
|
28
|
+
p_h.inject({}) do |sum, entry|
|
29
|
+
sum.merge!(entry.module_buckets(product_name)) { |_, v1, _| v1 }
|
30
|
+
sum.merge!(entry.full_module_buckets(product_name)) { |_, v1, _| v1 }
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
34
|
define_method(:project_headers) do
|
32
|
-
|
35
|
+
p_h = public_entrys + private_entrys
|
36
|
+
hs = p_h.inject({}) do |sum, entry|
|
37
|
+
sum.merge!(entry.module_buckets(product_name)) { |_, v1, _| v1 }
|
38
|
+
end
|
39
|
+
project_entrys.inject(hs) do |sum, entry|
|
40
|
+
sum.merge!(entry.project_buckets_extra) { |_, v1, _| v1 }
|
41
|
+
end
|
33
42
|
end
|
34
43
|
|
35
44
|
define_method(:own_target_headers) do
|
36
45
|
headers = public_entrys + private_entrys
|
37
|
-
|
38
|
-
|
39
|
-
|
46
|
+
hs = headers.inject({}) do |sum, entry|
|
47
|
+
sum.merge!(entry.module_buckets(product_name)) { |_, v1, _| v1 }
|
48
|
+
end
|
49
|
+
project_entrys.inject(hs) do |sum, entry|
|
50
|
+
sum.merge!(entry.project_buckets) { |_, v1, _| v1 }
|
51
|
+
sum.merge!(entry.full_module_buckets(product_name)) { |_, v1, _| v1 }
|
40
52
|
end
|
41
53
|
end
|
54
|
+
|
42
55
|
def build_root
|
43
56
|
project.build_root
|
44
57
|
end
|
@@ -71,7 +84,7 @@ module HMap
|
|
71
84
|
return @build_dir if defined?(@build_dir)
|
72
85
|
|
73
86
|
b_d = xcconfig_paths.any? do |path|
|
74
|
-
xc =
|
87
|
+
xc = XCConfig.new(path)
|
75
88
|
!xc.attributes[Constants::CONFIGURATION_BUILD_DIR].nil?
|
76
89
|
end
|
77
90
|
@build_dir = target_name if b_d
|
@@ -0,0 +1,290 @@
|
|
1
|
+
module HMap
|
2
|
+
# This class holds the data for a Xcode build settings file (xcconfig) and
|
3
|
+
# provides support for serialization.
|
4
|
+
#
|
5
|
+
class XCConfig
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
KEY_VALUE_PATTERN = /
|
9
|
+
(
|
10
|
+
[^=\[]+ # Any char, but not an assignment operator
|
11
|
+
# or subscript (non-greedy)
|
12
|
+
(?: # One or multiple conditional subscripts
|
13
|
+
\[
|
14
|
+
[^\]]* # The subscript key
|
15
|
+
(?:
|
16
|
+
= # The subscript comparison operator
|
17
|
+
[^\]]* # The subscript value
|
18
|
+
)?
|
19
|
+
\]
|
20
|
+
)*
|
21
|
+
)
|
22
|
+
\s* # Whitespaces after the key (needed because subscripts
|
23
|
+
# always end with ']')
|
24
|
+
= # The assignment operator
|
25
|
+
(.*) # The value
|
26
|
+
/x
|
27
|
+
private_constant :KEY_VALUE_PATTERN
|
28
|
+
|
29
|
+
INHERITED = %w($(inherited) ${inherited}).freeze
|
30
|
+
private_constant :INHERITED
|
31
|
+
|
32
|
+
INHERITED_REGEXP = Regexp.union(INHERITED)
|
33
|
+
private_constant :INHERITED_REGEXP
|
34
|
+
|
35
|
+
# @return [Hash{String => String}] The attributes of the settings file
|
36
|
+
# excluding frameworks, weak_framework and libraries.
|
37
|
+
#
|
38
|
+
attr_accessor :attributes
|
39
|
+
|
40
|
+
# @return [Hash{Symbol => Set<String>}] The other linker flags by key.
|
41
|
+
# Xcodeproj handles them in a dedicated way to prevent duplication
|
42
|
+
# of the libraries and of the frameworks.
|
43
|
+
#
|
44
|
+
def initialize(xcconfig_hash_or_file = {})
|
45
|
+
@attributes = {}
|
46
|
+
@includes = []
|
47
|
+
merge!(extract_hash(xcconfig_hash_or_file))
|
48
|
+
end
|
49
|
+
|
50
|
+
def inspect
|
51
|
+
to_hash.inspect
|
52
|
+
end
|
53
|
+
|
54
|
+
def ==(other)
|
55
|
+
other.attributes == attributes
|
56
|
+
end
|
57
|
+
|
58
|
+
# @!group Serialization
|
59
|
+
#-------------------------------------------------------------------------#
|
60
|
+
|
61
|
+
# Sorts the internal data by setting name and serializes it in the xcconfig
|
62
|
+
# format.
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
#
|
66
|
+
# config = Config.new('PODS_ROOT' => '"$(SRCROOT)/Pods"', 'OTHER_LDFLAGS' => '-lxml2')
|
67
|
+
# config.to_s # => "OTHER_LDFLAGS = -lxml2\nPODS_ROOT = \"$(SRCROOT)/Pods\""
|
68
|
+
#
|
69
|
+
# @return [String] The serialized internal data.
|
70
|
+
#
|
71
|
+
def to_s(prefix = nil)
|
72
|
+
include_lines = @includes.map { |path| "#include \"#{normalized_xcconfig_path(path)}\"" }
|
73
|
+
settings = to_hash(prefix).sort_by(&:first).map { |k, v| "#{k} = #{v}".strip }
|
74
|
+
(include_lines + settings).join("\n") << "\n"
|
75
|
+
end
|
76
|
+
|
77
|
+
# Writes the serialized representation of the internal data to the given
|
78
|
+
# path.
|
79
|
+
#
|
80
|
+
# @param [Pathname] pathname
|
81
|
+
# The file where the data should be written to.
|
82
|
+
#
|
83
|
+
# @return [void]
|
84
|
+
#
|
85
|
+
def save_as(pathname, prefix = nil)
|
86
|
+
return if File.exist?(pathname) && (XCConfig.new(pathname) == self)
|
87
|
+
|
88
|
+
pathname.open('w') { |file| file << to_s(prefix) }
|
89
|
+
end
|
90
|
+
|
91
|
+
# The hash representation of the xcconfig. The hash includes the
|
92
|
+
# frameworks, the weak frameworks, the libraries and the simple other
|
93
|
+
# linker flags in the `Other Linker Flags` (`OTHER_LDFLAGS`).
|
94
|
+
#
|
95
|
+
# @note All the values are sorted to have a consistent output in Ruby
|
96
|
+
# 1.8.7.
|
97
|
+
#
|
98
|
+
# @return [Hash] The hash representation
|
99
|
+
#
|
100
|
+
def to_hash(prefix = nil)
|
101
|
+
list = []
|
102
|
+
|
103
|
+
result = attributes.dup
|
104
|
+
result.reject! { |_, v| INHERITED.any? { |i| i == v.to_s.strip } }
|
105
|
+
if prefix
|
106
|
+
Hash[result.map { |k, v| [prefix + k, v] }]
|
107
|
+
else
|
108
|
+
result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
alias to_h to_hash
|
113
|
+
|
114
|
+
# @!group Merging
|
115
|
+
#-------------------------------------------------------------------------#
|
116
|
+
|
117
|
+
# Merges the given xcconfig representation in the receiver.
|
118
|
+
# @note If a key in the given hash already exists in the internal data
|
119
|
+
# then its value is appended.
|
120
|
+
#
|
121
|
+
# @param [Hash, Config] config
|
122
|
+
# The xcconfig representation to merge.
|
123
|
+
#
|
124
|
+
# @todo The logic to normalize an hash should be extracted and the
|
125
|
+
# initializer should not call this method.
|
126
|
+
#
|
127
|
+
# @return [void]
|
128
|
+
#
|
129
|
+
def merge!(xcconfig)
|
130
|
+
if xcconfig.is_a? XCConfig
|
131
|
+
merge_attributes!(xcconfig.attributes)
|
132
|
+
else
|
133
|
+
merge_attributes!(xcconfig.to_hash)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
alias << merge!
|
137
|
+
|
138
|
+
# Creates a new #{Config} with the data of the receiver merged with the
|
139
|
+
# given xcconfig representation.
|
140
|
+
#
|
141
|
+
# @param [Hash, Config] config
|
142
|
+
# The xcconfig representation to merge.
|
143
|
+
#
|
144
|
+
# @return [Config] the new xcconfig.
|
145
|
+
#
|
146
|
+
def merge(config)
|
147
|
+
dup.tap { |x| x.merge!(config) }
|
148
|
+
end
|
149
|
+
|
150
|
+
# @return [Config] A copy of the receiver.
|
151
|
+
#
|
152
|
+
def dup
|
153
|
+
HMap::XCConfig.new(to_hash.dup)
|
154
|
+
end
|
155
|
+
|
156
|
+
#-------------------------------------------------------------------------#
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
# @!group Private Helpers
|
161
|
+
|
162
|
+
# Returns a hash from the given argument reading it from disk if necessary.
|
163
|
+
#
|
164
|
+
# @param [String, Pathname, Hash] argument
|
165
|
+
# The source from where the hash should be extracted.
|
166
|
+
#
|
167
|
+
# @return [Hash]
|
168
|
+
#
|
169
|
+
def extract_hash(argument)
|
170
|
+
return argument if argument.is_a?(Hash)
|
171
|
+
|
172
|
+
if argument.respond_to? :read
|
173
|
+
@filepath = Pathname.new(argument.to_path)
|
174
|
+
hash_from_file_content(argument.read)
|
175
|
+
elsif File.readable?(argument.to_s)
|
176
|
+
@filepath = Pathname.new(argument.to_s)
|
177
|
+
hash_from_file_content(File.read(argument))
|
178
|
+
else
|
179
|
+
argument
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# Returns a hash from the string representation of an Xcconfig file.
|
184
|
+
#
|
185
|
+
# @param [String] string
|
186
|
+
# The string representation of an xcconfig file.
|
187
|
+
#
|
188
|
+
# @return [Hash] the hash containing the xcconfig data.
|
189
|
+
#
|
190
|
+
def hash_from_file_content(string)
|
191
|
+
hash = {}
|
192
|
+
string.split("\n").each do |line|
|
193
|
+
uncommented_line = strip_comment(line)
|
194
|
+
if include = extract_include(uncommented_line)
|
195
|
+
@includes.push normalized_xcconfig_path(include)
|
196
|
+
else
|
197
|
+
key, value = extract_key_value(uncommented_line)
|
198
|
+
next unless key
|
199
|
+
|
200
|
+
value.gsub!(INHERITED_REGEXP) { |m| hash.fetch(key, m) }
|
201
|
+
hash[key] = value
|
202
|
+
end
|
203
|
+
end
|
204
|
+
hash
|
205
|
+
end
|
206
|
+
|
207
|
+
# Merges the given attributes hash while ensuring values are not duplicated.
|
208
|
+
#
|
209
|
+
# @param [Hash] attributes
|
210
|
+
# The attributes hash to merge into @attributes.
|
211
|
+
#
|
212
|
+
# @return [void]
|
213
|
+
#
|
214
|
+
def merge_attributes!(attributes)
|
215
|
+
@attributes.merge!(attributes) do |_, v1, v2|
|
216
|
+
v1 = v1.strip
|
217
|
+
v2 = v2.strip
|
218
|
+
v1_split = v1.shellsplit
|
219
|
+
v2_split = v2.shellsplit
|
220
|
+
if (v2_split - v1_split).empty? || v1_split.first(v2_split.size) == v2_split
|
221
|
+
v1
|
222
|
+
elsif v2_split.first(v1_split.size) == v1_split
|
223
|
+
v2
|
224
|
+
else
|
225
|
+
"#{v1} #{v2}"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Strips the comments from a line of an xcconfig string.
|
231
|
+
#
|
232
|
+
# @param [String] line
|
233
|
+
# the line to process.
|
234
|
+
#
|
235
|
+
# @return [String] the uncommented line.
|
236
|
+
#
|
237
|
+
def strip_comment(line)
|
238
|
+
line.partition('//').first
|
239
|
+
end
|
240
|
+
|
241
|
+
# Returns the file included by a line of an xcconfig string if present.
|
242
|
+
#
|
243
|
+
# @param [String] line
|
244
|
+
# the line to process.
|
245
|
+
#
|
246
|
+
# @return [String] the included file.
|
247
|
+
# @return [Nil] if no include was found in the line.
|
248
|
+
#
|
249
|
+
def extract_include(line)
|
250
|
+
regexp = /#include\s*"(.+)"/
|
251
|
+
match = line.match(regexp)
|
252
|
+
match[1] if match
|
253
|
+
end
|
254
|
+
|
255
|
+
# Returns the key and the value described by the given line of an xcconfig.
|
256
|
+
#
|
257
|
+
# @param [String] line
|
258
|
+
# the line to process.
|
259
|
+
#
|
260
|
+
# @return [Array] A tuple where the first entry is the key and the second
|
261
|
+
# entry is the value.
|
262
|
+
#
|
263
|
+
def extract_key_value(line)
|
264
|
+
match = line.match(KEY_VALUE_PATTERN)
|
265
|
+
if match
|
266
|
+
key = match[1]
|
267
|
+
value = match[2]
|
268
|
+
[key.strip, value.strip]
|
269
|
+
else
|
270
|
+
[]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
# Normalizes the given path to an xcconfing file to be used in includes,
|
275
|
+
# appending the extension if necessary.
|
276
|
+
#
|
277
|
+
# @param [String] path
|
278
|
+
# The path of the file which will be included in the xcconfig.
|
279
|
+
#
|
280
|
+
# @return [String] The normalized path.
|
281
|
+
#
|
282
|
+
def normalized_xcconfig_path(path)
|
283
|
+
if File.extname(path) == '.xcconfig'
|
284
|
+
path
|
285
|
+
else
|
286
|
+
"#{path}.xcconfig"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'xcconfig'
|
4
|
+
|
3
5
|
module HMap
|
4
6
|
# A collection of xcodeproj Helper functions used throughout hmap.
|
5
7
|
class XcodeprojHelper
|
@@ -12,12 +14,11 @@ module HMap
|
|
12
14
|
def initialize(path)
|
13
15
|
xc = Pathname(path)
|
14
16
|
@xcconfig_path = xc
|
15
|
-
@xcconfig =
|
17
|
+
@xcconfig = XCConfig.new(xc)
|
16
18
|
end
|
17
19
|
|
18
20
|
def add_build_settings_and_save(settings, use_origin: true)
|
19
21
|
add_build_settings(settings, use_origin)
|
20
|
-
build_settings = [Constants::HEADER_SEARCH_PATHS, Constants::USER_HEADER_SEARCH_PATHS]
|
21
22
|
if use_origin
|
22
23
|
remove_build_settings(settings)
|
23
24
|
else
|
@@ -40,7 +41,7 @@ module HMap
|
|
40
41
|
else
|
41
42
|
save_origin = save_build_setting(key)
|
42
43
|
e_value = value
|
43
|
-
e_value = "
|
44
|
+
e_value = "${#{save_xckey(key)}} #{e_value} " if use_origin && !save_origin.nil?
|
44
45
|
@xcconfig.attributes[hmap_xckey(key)] = e_value
|
45
46
|
@xcconfig.attributes[key] = "${#{hmap_xckey(key)}}"
|
46
47
|
end
|
@@ -61,10 +62,9 @@ module HMap
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def remove_build_settings_and_save
|
64
|
-
|
65
65
|
hmap_ks = @xcconfig.attributes.keys.each_with_object([]) do |key, sum|
|
66
|
-
sum << key[HMAP_XCKEY_START.length
|
67
|
-
sum << key[SAVE_XCKEY_START.length
|
66
|
+
sum << key[HMAP_XCKEY_START.length..] if key.start_with?(HMAP_XCKEY_START)
|
67
|
+
sum << key[SAVE_XCKEY_START.length..] if key.start_with?(SAVE_XCKEY_START)
|
68
68
|
end.compact
|
69
69
|
remove_build_settings(hmap_ks)
|
70
70
|
save_as
|
@@ -78,9 +78,7 @@ module HMap
|
|
78
78
|
def remove_build_setting(setting)
|
79
79
|
save_origin = @xcconfig.attributes[save_xckey(setting)]
|
80
80
|
origin = @xcconfig.attributes[setting]
|
81
|
-
if save_origin.nil? && !origin.nil? && origin.include?(hmap_xckey(setting))
|
82
|
-
@xcconfig.attributes.delete(setting)
|
83
|
-
end
|
81
|
+
@xcconfig.attributes.delete(setting) if save_origin.nil? && !origin.nil? && origin.include?(hmap_xckey(setting))
|
84
82
|
@xcconfig.attributes[setting] = save_origin unless save_origin.nil?
|
85
83
|
@xcconfig.attributes.delete(hmap_xckey(setting))
|
86
84
|
@xcconfig.attributes.delete(save_xckey(setting))
|
@@ -97,7 +95,6 @@ module HMap
|
|
97
95
|
!@xcconfig.attributes[key].nil?
|
98
96
|
end
|
99
97
|
|
100
|
-
|
101
98
|
def hmap_xckey(key)
|
102
99
|
"#{HMAP_XCKEY_START}#{key}"
|
103
100
|
end
|
@@ -22,7 +22,7 @@ module HMap
|
|
22
22
|
build_configurations = project.build_configuration_list.build_configurations
|
23
23
|
build_configurations += project.targets.flat_map do |target|
|
24
24
|
target.build_configuration_list.build_configurations
|
25
|
-
end
|
25
|
+
end
|
26
26
|
|
27
27
|
ps = build_configurations.flatten.each_with_object({}) do |configuration, sum|
|
28
28
|
bs = configuration.build_settings
|
@@ -39,16 +39,15 @@ module HMap
|
|
39
39
|
Platform.new_from_platforms(key, value.uniq)
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
def targets
|
44
44
|
return @targets if defined?(@targets)
|
45
45
|
|
46
46
|
project_dir = project.project_dir
|
47
|
-
|
47
|
+
|
48
48
|
h_ts = project.targets.map do |target|
|
49
49
|
next if target.is_a?(Constants::PBXAggregateTarget)
|
50
|
-
|
51
|
-
name = target.name
|
50
|
+
|
52
51
|
headers = target.build_phases.flat_map do |phase|
|
53
52
|
next unless phase.is_a?(Constants::PBXHeadersBuildPhase)
|
54
53
|
|
@@ -69,7 +68,11 @@ module HMap
|
|
69
68
|
types = %i[all_non_framework_target_headers project_headers all_target_headers all_product_headers]
|
70
69
|
datas = headers_hash(*types)
|
71
70
|
hmap_writer.write_or_symlink(nil, datas, %i[all_product_headers])
|
72
|
-
targets.each
|
71
|
+
targets.each do |target|
|
72
|
+
target.write_hmapfile!
|
73
|
+
UserInterface.puts("[hmapfile] #{target.target_name} hmap files generated".green)
|
74
|
+
end
|
75
|
+
UserInterface.puts("[hmapfile] There are #{targets.length} targets hmap files generated")
|
73
76
|
end
|
74
77
|
|
75
78
|
def save_hmap_settings!
|