cocoapods-mapfile 0.2.5 → 0.2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 638ba36cc9be5ecffeed1c7b02cb466b173b3a74fe3b2903d049450e07a4fd18
|
4
|
+
data.tar.gz: 959264f5b51c9c9e0d1543306a381ca61021f2e92038300d257b3dcc0a72d4af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f96fd831a0215bb118c568a4a03a10ef3f039f5a1f51d9edb34d8a4ca3b8a44ec9071ef5f87aeed69833fc2cb7b6d175b0e4461a06bff8b9f6247c4bb26d0719
|
7
|
+
data.tar.gz: 55ba2200d4aca7fe0549a4fe79ad067b2b7aec25fa4c5beccbad06cccb4d296aabdcd7fdbebe3344032ff5d72d7e03b71667536799eb43a6aadfdd81f35d2f96
|
data/README.md
CHANGED
@@ -1,27 +1,29 @@
|
|
1
|
-
#
|
1
|
+
# hmapfile
|
2
2
|
|
3
|
-
[](https://raw.githubusercontent.com/
|
3
|
+
[](https://raw.githubusercontent.com/Cat1237/cocoapods-hmap/main/LICENSE)
|
4
4
|
|
5
5
|
A CocoaPods plugin which can gen/read header map file.
|
6
6
|
|
7
7
|
**hmap-gen** is able to scan the header files of the target referenced components in the specified Cocoapods project, and generates a header map file that public to all the components
|
8
8
|
as well as generates a public and private header map file for each referenced component.
|
9
9
|
|
10
|
-
-
|
11
|
-
- "header.h" :
|
10
|
+
- `<header.h>` : `-I<hmap file path>`
|
11
|
+
- `"header.h"` : `-iquote <hmap file path>`
|
12
12
|
|
13
13
|
For framework, use [yaml-vfs](https://github.com/Cat1237/yaml-vfs) create VFS file to map framework Headers and Modules dir and pass VFS file to `-ivfsoverlay` parameter.
|
14
14
|
|
15
|
-
- vfs :
|
15
|
+
- `vfs` : `-ivfsoverlay <all-product-headers.yaml>`
|
16
16
|
|
17
17
|
A hmap file includes four types of headers:
|
18
18
|
|
19
|
-
- "header.h"
|
20
|
-
-
|
21
|
-
-
|
22
|
-
-
|
23
|
-
- "*\*/**/header.h" **based on project**
|
24
|
-
- "module/header.h" **based on project**
|
19
|
+
- `"header.h"`
|
20
|
+
- `<module/header.h>` **based on project**
|
21
|
+
- `<project_name/header.h>` **based on project**
|
22
|
+
- `<*\*/**/header.h>` **based on project**
|
23
|
+
- `"*\*/**/header.h"` **based on project**
|
24
|
+
- `"module/header.h"` **based on project**
|
25
|
+
|
26
|
+
For hmapfile hashtbale, use [hashtbale](https://github.com/Cat1237/hashtable) create hashtable and bitmap to store headers.
|
25
27
|
|
26
28
|
## Installation
|
27
29
|
|
@@ -46,21 +48,25 @@ $ gem install cocoapods-mapfile
|
|
46
48
|
```
|
47
49
|
|
48
50
|
## Quickstart
|
51
|
+
|
49
52
|
To begin gen hmap file by opening an Xcodeproj dir, and to your command line with:
|
53
|
+
|
50
54
|
```shell
|
51
|
-
|
55
|
+
hmapfile gen
|
52
56
|
```
|
57
|
+
|
53
58
|
or to your podfile, add this line:
|
54
|
-
```
|
55
|
-
$ plugin 'cocoapods-mapfile'
|
56
|
-
```
|
57
59
|
|
60
|
+
```rb
|
61
|
+
plugin 'cocoapods-mapfile'
|
62
|
+
```
|
58
63
|
|
59
64
|
## Command Line Tool
|
60
65
|
|
61
66
|
Installing the `cocoapods-mapfile` gem will also install two command-line tool `hmapfile reader` and `hmapfile writer` which you can use to generate header map file and read hmap file.
|
62
67
|
|
63
68
|
For more information consult
|
69
|
+
|
64
70
|
- `hmapfile --help`
|
65
71
|
- `hmapfile gen --help`
|
66
72
|
- `hmapfile reader --help`
|
@@ -89,6 +95,33 @@ $ hmapfile COMMAND
|
|
89
95
|
- `--json-path=/project/dir/json`: The path to the hmap json data.
|
90
96
|
- `--output-path=/project/dir/hmap file`: The path json data to the hmap file.
|
91
97
|
|
98
|
+
**hmapfile writer json file:**
|
99
|
+
|
100
|
+
```json
|
101
|
+
{
|
102
|
+
"MM.h": [
|
103
|
+
"/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
|
104
|
+
"MM.h"
|
105
|
+
],
|
106
|
+
"Dog.h": [
|
107
|
+
"/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
|
108
|
+
"MM.h"
|
109
|
+
],
|
110
|
+
"Cat.h": [
|
111
|
+
"/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
|
112
|
+
"MM.h"
|
113
|
+
],
|
114
|
+
"TestAndTestApp/MM.h": [
|
115
|
+
"/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
|
116
|
+
"MM.h"
|
117
|
+
],
|
118
|
+
"TestAndTestApp/Dog.h": [
|
119
|
+
"/Users/ws/Desktop/TestAndTestApp/TestAndTestApp/",
|
120
|
+
"Dog.h"
|
121
|
+
]
|
122
|
+
}
|
123
|
+
```
|
124
|
+
|
92
125
|
example:
|
93
126
|
|
94
127
|
```shell
|
@@ -118,11 +151,13 @@ plugin 'cocoapods-mapfile'
|
|
118
151
|
This was equl:
|
119
152
|
|
120
153
|
```rb
|
121
|
-
|
154
|
+
hmapfile gen --project-directory=<project path>
|
122
155
|
```
|
156
|
+
|
123
157
|
or, you can set some value:
|
124
158
|
|
125
159
|
Every time you execute pod install or pod update, `cocoapods-mapfile` will automatically generate a `header map file` for you and modify:
|
160
|
+
|
126
161
|
- `OTHER_CPLUSPLUSFLAGS`
|
127
162
|
- `OTHER_CFLAGS`
|
128
163
|
- `USE_HEADERMAP`
|
@@ -42,11 +42,14 @@ module HMap
|
|
42
42
|
def run
|
43
43
|
name = 'Gen'
|
44
44
|
name = 'Clean' if @clean_hmap
|
45
|
-
UserInterface.puts("\n[hmapfile] #{name} start
|
45
|
+
UserInterface.puts("\n[hmapfile] #{name} start")
|
46
|
+
unless @project_directory.exist?
|
47
|
+
UserInterface.puts("\n[hmapfile] #{name} [ERROR] #{@project_directory} dir not exist!".red)
|
48
|
+
return
|
49
|
+
end
|
46
50
|
HMap::MapFileWriter.new(true, @project_directory, @clean_hmap)
|
47
|
-
UserInterface.puts("[hmapfile] #{name} finish
|
51
|
+
UserInterface.puts("[hmapfile] #{name} finish")
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
51
55
|
end
|
52
|
-
|
@@ -17,16 +17,14 @@ module HMap
|
|
17
17
|
|
18
18
|
def initialize(argv)
|
19
19
|
super
|
20
|
-
mapfile_path = argv.option('hmap-path')
|
21
|
-
|
22
|
-
|
23
|
-
@mapfile_path = Pathname.new(mapfile_path).expand_path
|
20
|
+
mapfile_path = argv.option('hmap-path') || ''
|
21
|
+
@mapfile_path = Pathname.new(mapfile_path).expand_path
|
24
22
|
end
|
25
23
|
|
26
24
|
def validate!
|
27
25
|
super
|
28
26
|
# banner! if help?
|
29
|
-
raise
|
27
|
+
raise "[hmapfile] Reader [ERROR]: --hmap-path #{@mapfile_path} no exist".red if @mapfile_path.nil?
|
30
28
|
end
|
31
29
|
|
32
30
|
def self.options
|
@@ -36,9 +34,13 @@ module HMap
|
|
36
34
|
end
|
37
35
|
|
38
36
|
def run
|
39
|
-
UserInterface.puts "\n[hmapfile] Reader start
|
40
|
-
|
41
|
-
|
37
|
+
UserInterface.puts "\n[hmapfile] Reader start\n"
|
38
|
+
if File.exist?(@mapfile_path)
|
39
|
+
HMap::MapFileReader.new(@mapfile_path)
|
40
|
+
else
|
41
|
+
UserInterface.puts "\n[hmapfile] Reader input path: #{@mapfile_path} no such file!\n".red
|
42
|
+
end
|
43
|
+
UserInterface.puts "\n[hmapfile] Reader finish\n"
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
@@ -19,8 +19,7 @@ module HMap
|
|
19
19
|
|
20
20
|
def initialize(argv)
|
21
21
|
super
|
22
|
-
json_path = argv.option('json-path')
|
23
|
-
@json_path = json_path unless json_path.nil?
|
22
|
+
@json_path = argv.option('json-path') || ''
|
24
23
|
output_path = argv.option('output-path')
|
25
24
|
@output_path = output_path.nil? ? Pathname('.') : Pathname(output_path)
|
26
25
|
end
|
@@ -28,7 +27,7 @@ module HMap
|
|
28
27
|
def validate!
|
29
28
|
super
|
30
29
|
help! 'error: no input json files which to use with the `--json-path` option.' if @json_path.nil?
|
31
|
-
help!
|
30
|
+
help! 'error: no output path which to use the `--output-path`' if @output_path.nil?
|
32
31
|
end
|
33
32
|
|
34
33
|
# help
|
@@ -40,15 +39,24 @@ module HMap
|
|
40
39
|
end
|
41
40
|
|
42
41
|
def run
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
UserInterface.puts "\n[hmapfile-from-json] start"
|
43
|
+
if File.exist?(@json_path) && File.exist?(@output_path)
|
44
|
+
require 'json'
|
45
|
+
json_file = File.read(@json_path)
|
46
|
+
json = JSON.parse(json_file)
|
47
|
+
path = @output_path
|
48
|
+
path = path.join("#{File.basename(@json_path, '.*')}.hmap") if path.directory?
|
49
|
+
HMapSaver.new_from_buckets(json).write_to(path)
|
50
|
+
UserInterface.puts "[hmapfile-from-json] output path #{path}".green
|
51
|
+
else
|
52
|
+
unless File.exist?(@json_path)
|
53
|
+
UserInterface.puts "\n[hmapfile-from-json] Error json path: #{@json_path} no such file!".red
|
54
|
+
end
|
55
|
+
unless File.exist?(@output_path)
|
56
|
+
UserInterface.puts "\n[hmapfile-from-json] Error output path: #{@output_path} no such file!".red
|
57
|
+
end
|
58
|
+
end
|
59
|
+
UserInterface.puts "\n[hmapfile-from-json] finish"
|
52
60
|
end
|
53
61
|
end
|
54
62
|
end
|
data/lib/hmap/constants.rb
CHANGED
@@ -9,7 +9,7 @@ module HMap
|
|
9
9
|
HMAP_DIR = 'HMap'
|
10
10
|
HMAP_GEN_DIR = 'HMAP_GEN_DIR'
|
11
11
|
HMAP_GEN_DIR_VALUE = '${HMAP_GEN_DIR}'
|
12
|
-
|
12
|
+
XC_BUILD_DATA = 'XCBuildData'
|
13
13
|
PROJECT_TEMP_DIR = '${PROJECT}.build'
|
14
14
|
TARGET_TEMP_DIR = '${TARGET_NAME}.build'
|
15
15
|
TARGET_NAME = '${TARGET_NAME}'
|
@@ -25,6 +25,7 @@ module HMap
|
|
25
25
|
OTHER_CFLAGS = 'OTHER_CFLAGS'
|
26
26
|
OTHER_CPLUSPLUSFLAGS = 'OTHER_CPLUSPLUSFLAGS'
|
27
27
|
CONFIGURATION_BUILD_DIR = 'CONFIGURATION_BUILD_DIR'
|
28
|
+
OTHER_SWIFT_FLAGS = 'OTHER_SWIFT_FLAGS'
|
28
29
|
|
29
30
|
XCBuildConfiguration = Xcodeproj::Project::Object::XCBuildConfiguration
|
30
31
|
PBXSourcesBuildPhase = Xcodeproj::Project::Object::PBXSourcesBuildPhase
|
@@ -34,9 +35,12 @@ module HMap
|
|
34
35
|
PBXBuildFile = Xcodeproj::Project::Object::PBXBuildFile
|
35
36
|
PBXAggregateTarget = Xcodeproj::Project::Object::PBXAggregateTarget
|
36
37
|
|
37
|
-
HMAP_TARGET_ROOT = [BUILD_DIR_KEY, '..', '..', HMAP_DIR,
|
38
|
-
|
39
|
-
|
38
|
+
# HMAP_TARGET_ROOT = [BUILD_DIR_KEY, '..', '..', HMAP_DIR,
|
39
|
+
# PROJECT_TEMP_DIR, CONFIGURATION_EFFECTIVE_PLATFORM,
|
40
|
+
# TARGET_TEMP_DIR].join('/')
|
41
|
+
HMAP_TARGET_ROOT = [SRCROOT, HMAP_DIR,
|
42
|
+
PROJECT_TEMP_DIR, CONFIGURATION_EFFECTIVE_PLATFORM,
|
43
|
+
TARGET_TEMP_DIR].join('/')
|
40
44
|
|
41
45
|
HMAP_GEN_DIR_ATTRIBUTE = { HMAP_GEN_DIR => HMAP_TARGET_ROOT }
|
42
46
|
|
@@ -58,9 +62,9 @@ module HMap
|
|
58
62
|
attr_writer :instance
|
59
63
|
end
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
def initialize
|
66
|
+
@build_as_framework = {}
|
67
|
+
end
|
64
68
|
|
65
69
|
def hmap_filename(type)
|
66
70
|
filenames[type]
|
@@ -97,26 +101,23 @@ module HMap
|
|
97
101
|
xc_filenames[type]
|
98
102
|
end
|
99
103
|
|
100
|
-
def hmap_build_settings
|
101
|
-
build_settings
|
104
|
+
def hmap_build_settings(build_as_framework)
|
105
|
+
build_settings(build_as_framework)
|
102
106
|
end
|
103
107
|
|
104
108
|
private
|
105
109
|
|
106
|
-
def build_settings
|
107
|
-
return @
|
110
|
+
def build_settings(build_as_framework)
|
111
|
+
return @build_as_framework[build_as_framework] unless @build_as_framework[build_as_framework].nil?
|
108
112
|
|
109
113
|
attributes = HMAP_GEN_DIR_ATTRIBUTE
|
110
|
-
|
111
|
-
# attributes[HMAP_HEADER_SETTING] = settings
|
112
|
-
attributes[HEADER_SEARCH_PATHS] = build_setting_values_i
|
114
|
+
attributes[HEADER_SEARCH_PATHS] = build_setting_values_i(build_as_framework)
|
113
115
|
attributes[OTHER_CFLAGS] = build_setting_values_c
|
114
116
|
attributes[OTHER_CPLUSPLUSFLAGS] = build_setting_values_c
|
117
|
+
attributes[OTHER_SWIFT_FLAGS] = build_setting_values_s
|
115
118
|
attributes[USER_HEADER_SEARCH_PATHS] = build_setting_values_iquote
|
116
|
-
# attributes[OTHER_CFLAGS] = HMAP_HEADER_SETTING_KEY
|
117
|
-
# attributes[OTHER_CPLUSPLUSFLAGS] = HMAP_HEADER_SETTING_KEY
|
118
119
|
attributes[USE_HEADERMAP] = 'NO'
|
119
|
-
@
|
120
|
+
@build_as_framework[build_as_framework] = attributes
|
120
121
|
end
|
121
122
|
|
122
123
|
def filenames
|
@@ -132,22 +133,32 @@ module HMap
|
|
132
133
|
end]
|
133
134
|
end
|
134
135
|
|
135
|
-
def
|
136
|
-
%i[own_target_headers
|
136
|
+
def build_setting_values_s
|
137
|
+
%i[all_non_framework_target_headers own_target_headers all_product_headers project_headers].map do |type|
|
138
|
+
key = build_setting_keys[type]
|
139
|
+
value = xc_filenames[type]
|
140
|
+
["-Xcc -#{key}", "-Xcc \"#{HMAP_GEN_DIR_VALUE}/#{value}\""].join(' ')
|
141
|
+
end.join(' ')
|
142
|
+
end
|
143
|
+
|
144
|
+
def build_setting_values_i(build_as_framework)
|
145
|
+
a = %i[all_non_framework_target_headers own_target_headers]
|
146
|
+
a << :all_target_headers unless build_as_framework
|
147
|
+
a.map do |type|
|
137
148
|
value = xc_filenames[type]
|
138
149
|
"\"#{HMAP_GEN_DIR_VALUE}/#{value}\""
|
139
150
|
end.join(' ')
|
140
151
|
end
|
141
152
|
|
142
153
|
def build_setting_values_iquote
|
143
|
-
%i[project_headers
|
154
|
+
%i[project_headers].map do |type|
|
144
155
|
value = xc_filenames[type]
|
145
156
|
"\"#{HMAP_GEN_DIR_VALUE}/#{value}\""
|
146
157
|
end.join(' ')
|
147
158
|
end
|
148
159
|
|
149
160
|
def build_setting_values_c
|
150
|
-
%i[
|
161
|
+
%i[all_product_headers].map do |type|
|
151
162
|
key = build_setting_keys[type]
|
152
163
|
value = xc_filenames[type]
|
153
164
|
blank = ' ' unless key == :I
|
data/lib/hmap/helper/utils.rb
CHANGED
@@ -57,10 +57,7 @@ module HMap
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def self.string_downcase_hash(str)
|
60
|
-
str.downcase.bytes.inject(
|
61
|
-
sum += value * 13
|
62
|
-
sum
|
63
|
-
end
|
60
|
+
str.downcase.bytes.inject(:+) * 13
|
64
61
|
end
|
65
62
|
|
66
63
|
def self.update_changed_file(path, contents)
|
@@ -73,6 +70,18 @@ module HMap
|
|
73
70
|
File.open(path, 'w') { |f| f.write(contents) }
|
74
71
|
end
|
75
72
|
|
73
|
+
def self.file_symlink_to(path, filepath)
|
74
|
+
return unless path.exist?
|
75
|
+
|
76
|
+
filepath.dirname.mkpath unless filepath.exist?
|
77
|
+
|
78
|
+
if Gem.win_platform?
|
79
|
+
FileUtils.ln(path, filepath, force: true)
|
80
|
+
else
|
81
|
+
FileUtils.ln_sf(path, filepath)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
76
85
|
def self.swapped_magic?(magic, version)
|
77
86
|
magic.eql?(HEADER_CONST[:HMAP_SWAPPED_MAGIC]) && version.eql?(HEADER_CONST[:HMAP_SWAPPED_VERSION])
|
78
87
|
end
|
@@ -34,10 +34,10 @@ module HMap
|
|
34
34
|
# @note This method is public, but should (almost) never need to be called.
|
35
35
|
def populate_fields
|
36
36
|
@header = populate_hmap_header
|
37
|
-
string_t = @raw_data[header.strings_offset
|
37
|
+
string_t = @raw_data[header.strings_offset..]
|
38
38
|
@bucktes = populate_buckets do |bucket|
|
39
39
|
bucket_s = bucket.to_a.map do |key|
|
40
|
-
string_t[key
|
40
|
+
string_t[key..].match(/[^\0]+/)[0]
|
41
41
|
end
|
42
42
|
BucketStr.new(*bucket_s)
|
43
43
|
end
|
data/lib/hmap/hmap/hmap_saver.rb
CHANGED
@@ -2,60 +2,34 @@
|
|
2
2
|
|
3
3
|
require 'hmap/hmap/hmap_struct'
|
4
4
|
require 'hmap/hmap/mapfile'
|
5
|
+
require 'hashtable'
|
5
6
|
|
6
7
|
module HMap
|
8
|
+
# @class HMapSaver
|
7
9
|
class HMapSaver
|
8
|
-
attr_reader :string_table
|
10
|
+
attr_reader :string_table
|
9
11
|
|
10
12
|
def self.new_from_buckets(buckets)
|
11
13
|
saver = new
|
12
|
-
saver.add_to_buckets(buckets)
|
14
|
+
saver.add_to_buckets(buckets) unless buckets.empty?
|
13
15
|
saver
|
14
16
|
end
|
15
17
|
|
16
|
-
def
|
17
|
-
|
18
|
-
@buckets = []
|
19
|
-
@headers = {}
|
20
|
-
end
|
21
|
-
|
22
|
-
def header_to_hash(keys, headers, index, buckets)
|
23
|
-
index = index.length
|
24
|
-
keys.inject('') do |sum, bucket|
|
25
|
-
buckte = BucketStr.new(*bucket)
|
26
|
-
string_t = buckte.bucket_to_string(headers, index + sum.length)
|
27
|
-
buckets.push(buckte)
|
28
|
-
sum + string_t
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def add_to_string_table(str)
|
33
|
-
@string_table += "#{Utils.safe_encode(str, 'ASCII-8BIT')}\0"
|
34
|
-
end
|
18
|
+
def add_to_buckets(buckets)
|
19
|
+
return if buckets.nil?
|
35
20
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
21
|
+
hash_t = HashTable::HashTable.new_from_vlaue_placeholder(buckets.length, EMPTY_BUCKET, expand: true)
|
22
|
+
ta = HashTable::StringHashTraits.new { |bs| HMapBucket.new(*bs).serialize }
|
23
|
+
buckets.each_pair do |key, value|
|
24
|
+
hash_t.set(key, value, ta)
|
40
25
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def add_to_bucket(buckte)
|
45
|
-
key = add_to_headers(buckte.key)
|
46
|
-
perfix = add_to_headers(buckte.perfix)
|
47
|
-
suffix = add_to_headers(buckte.suffix)
|
48
|
-
bucket = HMapBucket.new(key, perfix, suffix)
|
49
|
-
bucket.uuid = Utils.string_downcase_hash(buckte.key)
|
50
|
-
@buckets << bucket
|
51
|
-
end
|
52
|
-
|
53
|
-
def add_to_buckets(buckets)
|
54
|
-
buckets.each { |bucket| add_to_bucket(bucket) }
|
26
|
+
@strings = ta.string_table
|
27
|
+
@buckets = hash_t.values
|
28
|
+
@entries = hash_t.num_entries
|
55
29
|
end
|
56
30
|
|
57
31
|
def write_to(path)
|
58
|
-
MapFile.new(@
|
32
|
+
MapFile.new(@strings, @buckets, @entries).write(Pathname(path))
|
59
33
|
end
|
60
34
|
end
|
61
35
|
end
|
@@ -9,6 +9,9 @@ module HMap
|
|
9
9
|
HMAP_SWAPPED_VERSION: 0x0100
|
10
10
|
}.freeze
|
11
11
|
|
12
|
+
EMPTY_HMAP = "pamh\u0001\u0000\u0000\u0000x\u0000\u0000\u0000\u0000\u0000\u0000\u0000\b\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
|
13
|
+
EMPTY_BUCKET = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
14
|
+
private_constant :EMPTY_HMAP
|
12
15
|
# A general purpose pseudo-structure.
|
13
16
|
# @abstract
|
14
17
|
class HMapStructure
|
@@ -69,7 +72,7 @@ module HMap
|
|
69
72
|
# or nil if the HMapHeader was created via {create}.
|
70
73
|
attr_reader :num_entries, :magic, :version, :reserved, :strings_offset, :num_buckets, :max_value_length
|
71
74
|
|
72
|
-
FORMAT = 'L=1S=
|
75
|
+
FORMAT = 'L=1S=2L=4'
|
73
76
|
# @see HMapStructure::SIZEOF
|
74
77
|
# @api private
|
75
78
|
SIZEOF = 24
|
@@ -117,7 +120,7 @@ module HMap
|
|
117
120
|
# @see https://clang.llvm.org/doxygen/structclang_1_1HMapHeader.html
|
118
121
|
# @abstract
|
119
122
|
class HMapBucket < HMapStructure
|
120
|
-
attr_accessor :key, :perfix, :suffix
|
123
|
+
attr_accessor :key, :perfix, :suffix
|
121
124
|
|
122
125
|
SIZEOF = 12
|
123
126
|
FORMAT = 'L=3'
|
@@ -150,62 +153,24 @@ module HMap
|
|
150
153
|
|
151
154
|
# HMap blobs.
|
152
155
|
class HMapData
|
153
|
-
def initialize(buckets)
|
156
|
+
def initialize(strings, buckets, entries)
|
154
157
|
super()
|
155
|
-
|
156
|
-
nums = num_buckets(count, Utils.next_power_of_two(count))
|
157
|
-
entries = entries(count, nums)
|
158
|
-
@header = populate_hmap_header(nums, entries)
|
159
|
-
@buckets = add_bucket(buckets, nums)
|
160
|
-
end
|
161
|
-
|
162
|
-
def num_buckets(count, pow2)
|
163
|
-
if count < 8
|
164
|
-
pow2 <<= 1 if count * 4 >= pow2 * 3
|
165
|
-
pow2 < 8 ? 8 : pow2
|
166
|
-
else
|
167
|
-
index = count > 341 ? 2 : -3
|
168
|
-
padding = count / 85 % 7 + index
|
169
|
-
Utils.next_power_of_two(count * 3 + padding)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def entries(count, nums)
|
174
|
-
return count if nums == 8
|
158
|
+
return if strings.nil? || buckets.empty?
|
175
159
|
|
176
|
-
|
177
|
-
|
178
|
-
|
160
|
+
@buckets = buckets
|
161
|
+
@strings = strings
|
162
|
+
@header = populate_hmap_header(buckets.count, entries)
|
179
163
|
end
|
180
164
|
|
181
165
|
# @return [String] the serialized fields of the mafile
|
182
166
|
def serialize
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
empty_b.pack('L<3')
|
187
|
-
else
|
188
|
-
bucket
|
189
|
-
end
|
190
|
-
sum
|
191
|
-
end
|
167
|
+
return EMPTY_HMAP if @strings.nil?
|
168
|
+
|
169
|
+
@header.serialize + @buckets.join + @strings
|
192
170
|
end
|
193
171
|
|
194
172
|
private
|
195
173
|
|
196
|
-
def add_bucket(buckets, num)
|
197
|
-
buckets.each_with_object(Array.new(num)) do |bucket, sum|
|
198
|
-
serialize = bucket.serialize
|
199
|
-
i = Utils.index_of_range(bucket.uuid, num)
|
200
|
-
loop do
|
201
|
-
sum[i] = serialize if sum[i].nil?
|
202
|
-
break if serialize == sum[i]
|
203
|
-
|
204
|
-
i = Utils.index_of_range(i += 1, num)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
174
|
def populate_hmap_header(num_buckets, entries)
|
210
175
|
strings_offset = HMapHeader.bytesize + HMapBucket.bytesize * num_buckets
|
211
176
|
HMapHeader.new(HEADER_CONST[:HMAP_HEADER_MAGIC_NUMBER],
|
@@ -14,8 +14,8 @@ module HMap
|
|
14
14
|
# @param allow_targets this targets will save origin build setting
|
15
15
|
# @param use_build_in_headermap option use Xcode header map
|
16
16
|
def initialize(use_origin, project_root, clean_hmap)
|
17
|
-
UserInterface.puts("[hmapfile] Workspace/project root: #{project_root}
|
18
|
-
UserInterface.puts(
|
17
|
+
UserInterface.puts("[hmapfile] Workspace/project root: #{project_root}")
|
18
|
+
UserInterface.puts('[hmapfile] Analyzing dependencies')
|
19
19
|
Resolver.instance.installation_root = project_root
|
20
20
|
Resolver.instance.use_origin = use_origin
|
21
21
|
create_hmapfile(clean_hmap)
|
@@ -32,14 +32,17 @@ module HMap
|
|
32
32
|
# Though this looks like a regular expression quantifier, it isn't.
|
33
33
|
# For example, in regular expression, the pattern a{1,2} will match 1 or 2 'a' characters.
|
34
34
|
# In globbing, it will match the string a1 or a2.
|
35
|
-
paths = Dir.glob(File.join(Resolver.instance.installation_root, '*.{xcworkspace,xcodeproj}'))
|
35
|
+
paths = Dir.glob(File.join(Resolver.instance.installation_root, '*.{xcworkspace,xcodeproj}')) || []
|
36
36
|
workspace_paths = paths.select { |f| File.extname(f) == '.xcworkspace' }
|
37
|
-
xcs = if workspace_paths.
|
37
|
+
xcs = if workspace_paths.empty?
|
38
38
|
project_paths = paths.select { |f| File.extname(f) == '.xcodeproj' }
|
39
39
|
Workspace.new_from_xcprojects(project_paths) unless project_paths.nil?
|
40
40
|
else
|
41
41
|
Workspace.new_from_xcworkspaces(workspace_paths)
|
42
42
|
end
|
43
|
+
if xcs.empty?
|
44
|
+
UserInterface.puts("\n[hmapfile] Gen [ERROR] path: #{Resolver.instance.installation_root} not contain .{xcworkspace,xcodeproj} file!".red)
|
45
|
+
end
|
43
46
|
xcs.each do |xc|
|
44
47
|
if clean
|
45
48
|
xc.remove_hmap_settings!
|
data/lib/hmap/hmap/mapfile.rb
CHANGED
@@ -3,31 +3,22 @@
|
|
3
3
|
module HMap
|
4
4
|
# hmap file writer
|
5
5
|
class MapFile
|
6
|
-
# @return mapfile string_table
|
7
|
-
attr_reader :string_table
|
8
|
-
|
9
|
-
# @return [Array<HMap::BucketStr>] an array of the file's bucktes
|
10
|
-
# @note bucktes are provided in order of ascending offset.
|
11
|
-
attr_reader :buckets
|
12
|
-
|
13
6
|
# @api private
|
14
|
-
def initialize(strings, buckets)
|
15
|
-
@
|
16
|
-
@buckets = buckets
|
17
|
-
@map_data = HMapData.new(buckets)
|
7
|
+
def initialize(strings, buckets, entries)
|
8
|
+
@map_data = HMapData.new(strings, buckets, entries)
|
18
9
|
end
|
19
10
|
|
20
11
|
# @return [String] the serialized fields of the mafile
|
21
12
|
def serialize
|
22
|
-
@map_data.serialize
|
13
|
+
@map_data.serialize
|
23
14
|
end
|
24
15
|
|
25
16
|
# Write all mafile data to the given filename.
|
26
17
|
# @param filename [String] the file to write to
|
27
18
|
# @return [void]
|
28
|
-
def write(
|
29
|
-
contents = serialize
|
30
|
-
Utils.update_changed_file(
|
19
|
+
def write(filepath, contents = nil)
|
20
|
+
contents = serialize if contents.nil?
|
21
|
+
Utils.update_changed_file(filepath, contents)
|
31
22
|
end
|
32
23
|
end
|
33
24
|
end
|