xcode-archive-cache 0.0.9 → 0.0.10.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/artifact_cache/archiver.rb +2 -1
- data/lib/artifact_cache/local_storage.rb +2 -1
- data/lib/build/performer.rb +1 -1
- data/lib/build/product_extractor.rb +16 -4
- data/lib/build_graph/node.rb +38 -2
- data/lib/build_graph/rebuild_evaluator.rb +30 -4
- data/lib/build_graph/sha_calculator.rb +3 -0
- data/lib/build_settings/extractor.rb +21 -1
- data/lib/build_settings/filter.rb +7 -3
- data/lib/build_settings/loader.rb +8 -1
- data/lib/build_settings/parser.rb +1 -1
- data/lib/injection/build_flags_changer.rb +69 -0
- data/lib/injection/headers_mover.rb +15 -2
- data/lib/injection/injector.rb +27 -9
- data/lib/injection/modulemap_fixer.rb +47 -0
- data/lib/injection/storage.rb +49 -3
- data/lib/runner/runner.rb +1 -9
- data/lib/shell/executor.rb +2 -2
- data/lib/xcode-archive-cache.rb +1 -0
- data/lib/xcodebuild/executor.rb +4 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea58d5804a6b809038af9c443a49426935c3f1b82673ce4029cadcd5dcdb21a2
|
4
|
+
data.tar.gz: edae37d1c99f73465be2486e910e32bb4b445811d4ef8dd4db91e45853f34a6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a753ce67b8129209b5da8e0afbdbd542da9660651ae47559fcfacbcf25ed9d35bedc45dbc05d23f13b33b1e4d05885f54bb43aaea2d3e2b4085f3fc1e960be63
|
7
|
+
data.tar.gz: c90dee530d492db4c3986c0e0ca6d651e0099a8f0348cdb4f5fa0110a32d143932809bdfce295ab4dc36e8180456320a208ff9f927cc2478f9b8d086cc016c32
|
@@ -9,7 +9,8 @@ module XcodeArchiveCache
|
|
9
9
|
#
|
10
10
|
def archive(path, destination)
|
11
11
|
if File.exists?(destination)
|
12
|
-
|
12
|
+
warn "Replacing artifact archive at path #{destination}"
|
13
|
+
FileUtils.rm_rf(destination)
|
13
14
|
end
|
14
15
|
|
15
16
|
if File.file?(path)
|
@@ -60,7 +60,8 @@ module XcodeArchiveCache
|
|
60
60
|
state_file_path = archive_path + ".state"
|
61
61
|
|
62
62
|
if File.exist?(state_file_path)
|
63
|
-
|
63
|
+
warn "Replacing state file #{state_file_path}"
|
64
|
+
FileUtils.rm_f(state_file_path)
|
64
65
|
end
|
65
66
|
|
66
67
|
dependency_shas = node.dependencies
|
data/lib/build/performer.rb
CHANGED
@@ -17,7 +17,7 @@ module XcodeArchiveCache
|
|
17
17
|
#
|
18
18
|
def list_product_contents(built_node)
|
19
19
|
file_paths = list_products(built_node)
|
20
|
-
file_paths.select {|path| File.exist?(path)}.map {|path| File.realpath(path)}
|
20
|
+
file_paths.select { |path| File.exist?(path) }.map { |path| File.realpath(path) }
|
21
21
|
end
|
22
22
|
|
23
23
|
private
|
@@ -78,7 +78,15 @@ module XcodeArchiveCache
|
|
78
78
|
raise Informative, "Product of type #{built_node.native_target.product_type} not found for #{built_node.name}"
|
79
79
|
end
|
80
80
|
|
81
|
-
[product_path]
|
81
|
+
paths = [product_path]
|
82
|
+
|
83
|
+
# this one is generated during Swift compilation
|
84
|
+
# so we need to cache it as well
|
85
|
+
#
|
86
|
+
swift_objc_interface_header_path = built_node.swift_objc_interface_header_path
|
87
|
+
paths << swift_objc_interface_header_path if swift_objc_interface_header_path
|
88
|
+
|
89
|
+
paths
|
82
90
|
end
|
83
91
|
|
84
92
|
# @param [XcodeArchiveCache::BuildGraph::Node] built_node
|
@@ -106,7 +114,7 @@ module XcodeArchiveCache
|
|
106
114
|
end
|
107
115
|
|
108
116
|
uuids = list_bc_symbolmap_uuids(executable_path)
|
109
|
-
uuids.map {|uuid| find_bc_symbolmap(uuid)}.flatten
|
117
|
+
uuids.map { |uuid| find_bc_symbolmap(uuid) }.flatten
|
110
118
|
end
|
111
119
|
|
112
120
|
# @param [String] executable_path
|
@@ -114,7 +122,11 @@ module XcodeArchiveCache
|
|
114
122
|
# @return [Array<String>]
|
115
123
|
#
|
116
124
|
def list_bc_symbolmap_uuids(executable_path)
|
117
|
-
|
125
|
+
begin
|
126
|
+
shell_executor.execute_for_output("otool -l #{executable_path} | grep uuid | awk {'print $2'}").split("\n")
|
127
|
+
rescue
|
128
|
+
[]
|
129
|
+
end
|
118
130
|
end
|
119
131
|
|
120
132
|
# @param [String] uuid
|
data/lib/build_graph/node.rb
CHANGED
@@ -86,9 +86,45 @@ module XcodeArchiveCache
|
|
86
86
|
# @return [String]
|
87
87
|
#
|
88
88
|
def dsym_file_name
|
89
|
-
|
89
|
+
build_settings ? build_settings[XcodeArchiveCache::BuildSettings::DWARF_DSYM_FILE_NAME_KEY] : nil
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [String]
|
93
|
+
#
|
94
|
+
def modulemap_file_path
|
95
|
+
modulemap_file = build_settings[XcodeArchiveCache::BuildSettings::MODULEMAP_FILE_KEY]
|
96
|
+
return unless modulemap_file
|
90
97
|
|
91
|
-
|
98
|
+
Pathname.new(modulemap_file).absolute? ? modulemap_file : File.join(File.dirname(native_target.project.path), modulemap_file)
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [String]
|
102
|
+
#
|
103
|
+
def swift_objc_interface_header_path
|
104
|
+
header_file = swift_objc_interface_header_file
|
105
|
+
return if header_file == nil
|
106
|
+
|
107
|
+
File.join(build_settings[XcodeArchiveCache::BuildSettings::DERIVED_SOURCES_DIR_KEY], header_file)
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [String]
|
111
|
+
#
|
112
|
+
def swift_objc_interface_header_file
|
113
|
+
header_file = build_settings[XcodeArchiveCache::BuildSettings::SWIFT_OBJC_INTERFACE_HEADER_NAME_KEY]
|
114
|
+
if header_file == nil
|
115
|
+
our_module_name = module_name
|
116
|
+
return if our_module_name == nil
|
117
|
+
|
118
|
+
header_file = our_module_name + "-Swift.h"
|
119
|
+
end
|
120
|
+
|
121
|
+
header_file
|
122
|
+
end
|
123
|
+
|
124
|
+
# @return [String]
|
125
|
+
#
|
126
|
+
def module_name
|
127
|
+
build_settings[XcodeArchiveCache::BuildSettings::PRODUCT_MODULE_NAME_KEY]
|
92
128
|
end
|
93
129
|
|
94
130
|
# @return [Array<Node>]
|
@@ -8,24 +8,50 @@ module XcodeArchiveCache
|
|
8
8
|
@cache_storage = cache_storage
|
9
9
|
end
|
10
10
|
|
11
|
+
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
12
|
+
#
|
13
|
+
def evaluate_build_graph(graph)
|
14
|
+
return if graph.root_node.state != :unknown
|
15
|
+
|
16
|
+
# DFS over graph, evaluating dependencies first
|
17
|
+
#
|
18
|
+
stack = [graph.root_node]
|
19
|
+
|
20
|
+
while stack.length > 0
|
21
|
+
last_node = stack.last
|
22
|
+
|
23
|
+
if last_node.state == :evaluating_dependencies
|
24
|
+
# dependencies were evaluated, we're good to go
|
25
|
+
evaluate(last_node)
|
26
|
+
stack.delete_at(stack.length - 1)
|
27
|
+
elsif last_node.state == :unknown
|
28
|
+
last_node.state = :evaluating_dependencies
|
29
|
+
stack += last_node.dependencies.select { |dependency| dependency.state == :unknown }
|
30
|
+
else
|
31
|
+
stack.delete_at(stack.length - 1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
11
38
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
12
39
|
#
|
13
40
|
def evaluate(node)
|
14
|
-
|
41
|
+
has_dependencies_waiting_for_rebuild = node.dependencies
|
42
|
+
.reduce(false) { |rebuild, dependency| rebuild || dependency.waiting_for_rebuild }
|
15
43
|
|
16
44
|
# we include dependency shas in every node sha calculation,
|
17
45
|
# so if some dependency changes, that change propagates
|
18
46
|
# all the way to the top level
|
19
47
|
#
|
20
|
-
if cache_storage.cached_artifact_path(node) == nil
|
48
|
+
if has_dependencies_waiting_for_rebuild || cache_storage.cached_artifact_path(node) == nil
|
21
49
|
node.state = :waiting_for_rebuild
|
22
50
|
else
|
23
51
|
node.state = :exists_in_cache
|
24
52
|
end
|
25
53
|
end
|
26
54
|
|
27
|
-
private
|
28
|
-
|
29
55
|
# @return [XcodeArchiveCache::ArtifactCache::AbstractStorage]
|
30
56
|
#
|
31
57
|
attr_reader :cache_storage
|
@@ -36,6 +36,9 @@ module XcodeArchiveCache
|
|
36
36
|
inputs << list_build_phase_inputs(build_phase)
|
37
37
|
end
|
38
38
|
|
39
|
+
modulemap_file_path = node.modulemap_file_path
|
40
|
+
inputs << modulemap_file_path if modulemap_file_path
|
41
|
+
|
39
42
|
# file path order should not affect evaluation result
|
40
43
|
inputs.flatten.compact.sort
|
41
44
|
end
|
@@ -13,7 +13,7 @@ module XcodeArchiveCache
|
|
13
13
|
# @return [Hash{String => Container}]
|
14
14
|
# Target build settings keyed by target name
|
15
15
|
#
|
16
|
-
def extract_per_target(build_settings)
|
16
|
+
def extract_per_target(build_settings, fix_simulator)
|
17
17
|
per_target_settings = build_settings.split("Build settings for action")
|
18
18
|
result = Hash.new
|
19
19
|
|
@@ -22,6 +22,7 @@ module XcodeArchiveCache
|
|
22
22
|
target_name = get_target_name(parsed_settings)
|
23
23
|
next unless target_name
|
24
24
|
|
25
|
+
replace_platform_with_simulator(parsed_settings) if fix_simulator
|
25
26
|
filtered_settings = filter.filter(parsed_settings)
|
26
27
|
result[target_name] = Container.new(parsed_settings, filtered_settings)
|
27
28
|
end
|
@@ -65,6 +66,25 @@ module XcodeArchiveCache
|
|
65
66
|
result
|
66
67
|
end
|
67
68
|
|
69
|
+
|
70
|
+
# @param [Hash{String => String}] settings
|
71
|
+
#
|
72
|
+
def replace_platform_with_simulator(settings)
|
73
|
+
original_platform = settings[EFFECTIVE_PLATFORM_NAME_KEY]
|
74
|
+
simulator_platform = settings[CORRESPONDING_SIMULATOR_PLATFORM_NAME_KEY]
|
75
|
+
settings[EFFECTIVE_PLATFORM_NAME_KEY] = "-#{simulator_platform}"
|
76
|
+
|
77
|
+
configuration = settings[CONFIGURATION_KEY]
|
78
|
+
path_regexp = Regexp.new("#{configuration}#{original_platform}")
|
79
|
+
simulator_path = "#{configuration}-#{simulator_platform}"
|
80
|
+
settings.each do |key, value|
|
81
|
+
settings[key] = value.gsub(path_regexp, simulator_path)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
EFFECTIVE_PLATFORM_NAME_KEY = "EFFECTIVE_PLATFORM_NAME".freeze
|
86
|
+
CORRESPONDING_SIMULATOR_PLATFORM_NAME_KEY = "CORRESPONDING_SIMULATOR_PLATFORM_NAME".freeze
|
87
|
+
CONFIGURATION_KEY = "CONFIGURATION".freeze
|
68
88
|
TARGET_NAME_KEY = "TARGETNAME".freeze
|
69
89
|
|
70
90
|
# @param [Hash{String => String}] parsed_settings
|
@@ -10,7 +10,7 @@ module XcodeArchiveCache
|
|
10
10
|
# Machine-dependent settings i.e. paths, user names, group names are rejected
|
11
11
|
#
|
12
12
|
def filter(settings, settings_to_keep = SETTINGS_TO_KEEP)
|
13
|
-
filtered_settings = settings.select {|name, _| settings_to_keep.include?(name)}
|
13
|
+
filtered_settings = settings.select { |name, _| settings_to_keep.include?(name) }
|
14
14
|
SETTINGS_TO_STRIP.each do |name|
|
15
15
|
value = filtered_settings[name]
|
16
16
|
next if value == nil
|
@@ -44,7 +44,9 @@ module XcodeArchiveCache
|
|
44
44
|
# splitting will be broken, but probability of
|
45
45
|
# someone using such path is quite low (or it isn't ?)
|
46
46
|
#
|
47
|
-
value_components = value_without_quotes
|
47
|
+
value_components = value_without_quotes
|
48
|
+
.split(/^-|\s-/)
|
49
|
+
.select { |component| component.length > 0 }
|
48
50
|
|
49
51
|
index = 0
|
50
52
|
indices_to_remove = []
|
@@ -66,7 +68,8 @@ module XcodeArchiveCache
|
|
66
68
|
kept_components.push(component) unless indices_to_remove.include?(component_index)
|
67
69
|
end
|
68
70
|
|
69
|
-
kept_components.join(" -")
|
71
|
+
result = kept_components.join(" -")
|
72
|
+
result.length > 0 ? "-#{result}" : ""
|
70
73
|
end
|
71
74
|
|
72
75
|
# TODO: extend
|
@@ -283,6 +286,7 @@ module XcodeArchiveCache
|
|
283
286
|
output-file-map
|
284
287
|
save-optimization-record-path
|
285
288
|
working-directory
|
289
|
+
fmodule-map-file
|
286
290
|
)
|
287
291
|
end
|
288
292
|
end
|
@@ -3,6 +3,11 @@ module XcodeArchiveCache
|
|
3
3
|
|
4
4
|
FULL_PRODUCT_NAME_KEY = "FULL_PRODUCT_NAME".freeze
|
5
5
|
DWARF_DSYM_FILE_NAME_KEY = "DWARF_DSYM_FILE_NAME".freeze
|
6
|
+
MODULEMAP_FILE_KEY = "MODULEMAP_FILE".freeze
|
7
|
+
SWIFT_OBJC_INTERFACE_HEADER_NAME_KEY = "SWIFT_OBJC_INTERFACE_HEADER_NAME".freeze
|
8
|
+
SWIFT_MODULE_NAME_KEY = "SWIFT_MODULE_NAME".freeze
|
9
|
+
PRODUCT_MODULE_NAME_KEY = "PRODUCT_MODULE_NAME".freeze
|
10
|
+
DERIVED_SOURCES_DIR_KEY = "DERIVED_SOURCES_DIR".freeze
|
6
11
|
|
7
12
|
class Container
|
8
13
|
|
@@ -58,9 +63,11 @@ module XcodeArchiveCache
|
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
66
|
+
should_fix_settings = executor.set_up_for_simulator?
|
67
|
+
|
61
68
|
threads.each do |thread|
|
62
69
|
project_path, all_targets_settings = thread.value
|
63
|
-
per_target_settings = extractor.extract_per_target(all_targets_settings)
|
70
|
+
per_target_settings = extractor.extract_per_target(all_targets_settings, should_fix_settings)
|
64
71
|
set_project_settings(project_path, per_target_settings)
|
65
72
|
end
|
66
73
|
end
|
@@ -64,13 +64,36 @@ module XcodeArchiveCache
|
|
64
64
|
add_cflag(build_configuration, path_to_capital_i(path))
|
65
65
|
end
|
66
66
|
|
67
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
68
|
+
# @param [String] path
|
69
|
+
#
|
70
|
+
def fix_module_map_path(build_configuration, old_modulemap_names, path)
|
71
|
+
replace_module_map_flag(build_configuration.build_settings, OTHER_CFLAGS_KEY, old_modulemap_names, path)
|
72
|
+
replace_module_map_flag(build_configuration.build_settings, OTHER_CPLUSPLUSFLAGS_KEY, old_modulemap_names, path)
|
73
|
+
replace_module_map_flag(build_configuration.build_settings, OTHER_SWIFT_FLAGS_KEY, old_modulemap_names, path)
|
74
|
+
|
75
|
+
if build_configuration.base_configuration_reference
|
76
|
+
xcconfig_path = build_configuration.base_configuration_reference.real_path
|
77
|
+
return unless File.exist?(xcconfig_path)
|
78
|
+
xcconfig = Xcodeproj::Config.new(xcconfig_path)
|
79
|
+
|
80
|
+
replace_module_map_flag(xcconfig.attributes, OTHER_CFLAGS_KEY, old_modulemap_names, path)
|
81
|
+
replace_module_map_flag(xcconfig.attributes, OTHER_CPLUSPLUSFLAGS_KEY, old_modulemap_names, path)
|
82
|
+
replace_module_map_flag(xcconfig.attributes, OTHER_SWIFT_FLAGS_KEY, old_modulemap_names, path)
|
83
|
+
|
84
|
+
xcconfig.save_as(Pathname.new(xcconfig_path))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
67
88
|
private
|
68
89
|
|
69
90
|
FRAMEWORK_SEARCH_PATHS_KEY = "FRAMEWORK_SEARCH_PATHS"
|
70
91
|
LIBRARY_SEARCH_PATHS_KEY = "LIBRARY_SEARCH_PATHS"
|
71
92
|
HEADER_SEARCH_PATHS_KEY = "HEADER_SEARCH_PATHS"
|
72
93
|
OTHER_CFLAGS_KEY = "OTHER_CFLAGS"
|
94
|
+
OTHER_CPLUSPLUSFLAGS_KEY = "OTHER_CPLUSPLUSFLAGS"
|
73
95
|
OTHER_LDFLAGS_KEY = "OTHER_LDFLAGS"
|
96
|
+
OTHER_SWIFT_FLAGS_KEY = "OTHER_SWIFT_FLAGS"
|
74
97
|
INHERITED_SETTINGS_VALUE = "$(inherited)"
|
75
98
|
|
76
99
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
@@ -167,6 +190,52 @@ module XcodeArchiveCache
|
|
167
190
|
|
168
191
|
"-framework \"#{framework_name}\""
|
169
192
|
end
|
193
|
+
|
194
|
+
# @param [Hash] build_settings
|
195
|
+
# @param [String] flags_key
|
196
|
+
# @param [Array<String>] old_modulemap_names
|
197
|
+
# @param [String] path
|
198
|
+
#
|
199
|
+
def replace_module_map_flag(build_settings, flags_key, old_modulemap_names, path)
|
200
|
+
flags = build_settings[flags_key]
|
201
|
+
if flags
|
202
|
+
build_settings[flags_key] = replace_module_map_path(flags, old_modulemap_names, path)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
MODULE_MAP_FLAG = "-fmodule-map-file="
|
207
|
+
|
208
|
+
# @param [String] flags
|
209
|
+
# @param [Array<String>] old_modulemap_names
|
210
|
+
# @param [String] path
|
211
|
+
#
|
212
|
+
# @return [String]
|
213
|
+
#
|
214
|
+
def replace_module_map_path(flags, old_modulemap_names, path)
|
215
|
+
return if flags == nil
|
216
|
+
|
217
|
+
is_flags_string = flags.is_a?(String)
|
218
|
+
flags = flags.split(" ") if is_flags_string
|
219
|
+
updated_flags = flags
|
220
|
+
.map { |flags_line| flags_line.split(" ") }
|
221
|
+
.flatten
|
222
|
+
.map do |line|
|
223
|
+
updated_line = line
|
224
|
+
|
225
|
+
if line.include?(MODULE_MAP_FLAG)
|
226
|
+
old_modulemap_names.each do |name|
|
227
|
+
if line.include?(name)
|
228
|
+
updated_line = "#{MODULE_MAP_FLAG}\"#{path}\""
|
229
|
+
break
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
updated_line
|
235
|
+
end
|
236
|
+
|
237
|
+
is_flags_string ? updated_flags.join(" ") : updated_flags
|
238
|
+
end
|
170
239
|
end
|
171
240
|
end
|
172
241
|
end
|
@@ -19,16 +19,29 @@ module XcodeArchiveCache
|
|
19
19
|
|
20
20
|
node.native_target.copy_files_build_phases.each do |build_phase|
|
21
21
|
file_paths = build_phase.files
|
22
|
-
.map {|build_file| get_real_path(build_file)}
|
22
|
+
.map { |build_file| get_real_path(build_file) }
|
23
23
|
.compact
|
24
24
|
.uniq
|
25
|
-
.select {|path| File.extname(path) == ".h"}
|
25
|
+
.select { |path| File.extname(path) == ".h" }
|
26
26
|
destination_path = get_destination_dir_path(node, build_phase)
|
27
27
|
storage.store_headers(node, destination_path, file_paths)
|
28
28
|
|
29
29
|
header_count += file_paths.length
|
30
30
|
end
|
31
31
|
|
32
|
+
if node.has_static_library_product?
|
33
|
+
headers_file_paths = node.native_target
|
34
|
+
.headers_build_phase
|
35
|
+
.files
|
36
|
+
.map { |header| get_real_path(header) }
|
37
|
+
.uniq
|
38
|
+
storage.store_default_headers(node, headers_file_paths)
|
39
|
+
|
40
|
+
header_count += headers_file_paths.length
|
41
|
+
|
42
|
+
storage.store_modulemap(node)
|
43
|
+
end
|
44
|
+
|
32
45
|
debug("found #{header_count} headers")
|
33
46
|
end
|
34
47
|
|
data/lib/injection/injector.rb
CHANGED
@@ -14,6 +14,7 @@ module XcodeArchiveCache
|
|
14
14
|
@dependency_remover = DependencyRemover.new
|
15
15
|
@build_flags_changer = BuildFlagsChanger.new
|
16
16
|
@pods_fixer = PodsScriptFixer.new
|
17
|
+
@modulemap_fixer = ModulemapFixer.new(storage)
|
17
18
|
@framework_embedder = FrameworkEmbedder.new
|
18
19
|
end
|
19
20
|
|
@@ -34,8 +35,14 @@ module XcodeArchiveCache
|
|
34
35
|
return
|
35
36
|
end
|
36
37
|
|
38
|
+
no_rebuild_performed = root_node.state == :unpacked
|
39
|
+
|
37
40
|
graph.nodes.each do |node|
|
38
|
-
|
41
|
+
if no_rebuild_performed || node.state == :rebuilt_and_cached
|
42
|
+
headers_mover.prepare_headers_for_injection(node)
|
43
|
+
modulemap_fixer.fix_modulemap(node)
|
44
|
+
end
|
45
|
+
|
39
46
|
add_as_prebuilt_dependency(node, target, node.is_root)
|
40
47
|
remove_native_target_from_project(node)
|
41
48
|
end
|
@@ -51,8 +58,8 @@ module XcodeArchiveCache
|
|
51
58
|
pods_fixer.fix_embed_frameworks_script(target, graph, storage.container_dir_path)
|
52
59
|
pods_fixer.fix_copy_resources_script(target, graph, storage.container_dir_path)
|
53
60
|
else
|
54
|
-
framework_nodes = graph.nodes.select {|node| node.has_framework_product?}
|
55
|
-
framework_file_paths = framework_nodes.map {|node| File.join(storage.get_storage_path(node), node.product_file_name)}
|
61
|
+
framework_nodes = graph.nodes.select { |node| node.has_framework_product? }
|
62
|
+
framework_file_paths = framework_nodes.map { |node| File.join(storage.get_storage_path(node), node.product_file_name) }
|
56
63
|
framework_embedder.embed(framework_file_paths, target)
|
57
64
|
end
|
58
65
|
|
@@ -86,6 +93,10 @@ module XcodeArchiveCache
|
|
86
93
|
#
|
87
94
|
attr_reader :pods_fixer
|
88
95
|
|
96
|
+
# @return [ModulemapFixer]
|
97
|
+
#
|
98
|
+
attr_reader :modulemap_fixer
|
99
|
+
|
89
100
|
# @return [FrameworkEmbedder]
|
90
101
|
#
|
91
102
|
attr_reader :framework_embedder
|
@@ -93,9 +104,10 @@ module XcodeArchiveCache
|
|
93
104
|
# @param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
|
94
105
|
#
|
95
106
|
def inject_unpacked(nodes)
|
96
|
-
cached_nodes = nodes.select {|node| node.state == :unpacked}
|
107
|
+
cached_nodes = nodes.select { |node| node.state == :unpacked }
|
97
108
|
cached_nodes.each do |node|
|
98
109
|
headers_mover.prepare_headers_for_injection(node)
|
110
|
+
modulemap_fixer.fix_modulemap(node)
|
99
111
|
add_as_prebuilt_to_dependents(node)
|
100
112
|
end
|
101
113
|
end
|
@@ -108,7 +120,7 @@ module XcodeArchiveCache
|
|
108
120
|
|
109
121
|
nodes
|
110
122
|
.select(&:waiting_for_rebuild)
|
111
|
-
.each {|node| add_header_paths_to_target(node.native_target, header_storage_paths)}
|
123
|
+
.each { |node| add_header_paths_to_target(node.native_target, header_storage_paths) }
|
112
124
|
end
|
113
125
|
|
114
126
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
@@ -146,7 +158,7 @@ module XcodeArchiveCache
|
|
146
158
|
def save_graph_projects(graph)
|
147
159
|
projects = graph.nodes.map(&:native_target).map(&:project).uniq
|
148
160
|
debug("updating #{projects.length} projects")
|
149
|
-
projects.each {|project| project.save}
|
161
|
+
projects.each { |project| project.save }
|
150
162
|
end
|
151
163
|
|
152
164
|
# @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
|
@@ -188,10 +200,16 @@ module XcodeArchiveCache
|
|
188
200
|
def add_as_prebuilt_static_lib(prebuilt_node, dependent_target, should_link)
|
189
201
|
build_configuration = find_build_configuration(dependent_target)
|
190
202
|
|
191
|
-
|
203
|
+
injected_modulemap_file_path = storage.get_modulemap_path(prebuilt_node)
|
204
|
+
if injected_modulemap_file_path
|
205
|
+
modulemap_file_names = ["#{prebuilt_node.module_name}.modulemap", File.basename(prebuilt_node.modulemap_file_path)]
|
206
|
+
build_flags_changer.fix_module_map_path(build_configuration, modulemap_file_names, injected_modulemap_file_path)
|
207
|
+
end
|
208
|
+
|
209
|
+
# if should_link
|
192
210
|
artifact_location = storage.get_storage_path(prebuilt_node)
|
193
211
|
build_flags_changer.add_library_search_path(build_configuration, artifact_location)
|
194
|
-
end
|
212
|
+
# end
|
195
213
|
|
196
214
|
dependency_remover.remove_dependency(prebuilt_node, dependent_target)
|
197
215
|
end
|
@@ -199,7 +217,7 @@ module XcodeArchiveCache
|
|
199
217
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
200
218
|
#
|
201
219
|
def find_build_configuration(target)
|
202
|
-
build_configuration = target.build_configurations.select {|configuration| configuration.name == configuration_name}.first
|
220
|
+
build_configuration = target.build_configurations.select { |configuration| configuration.name == configuration_name }.first
|
203
221
|
unless build_configuration
|
204
222
|
raise Informative, "#{configuration_name} build configuration not found on target #{node.name}"
|
205
223
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module XcodeArchiveCache
|
2
|
+
module Injection
|
3
|
+
|
4
|
+
class ModulemapFixer
|
5
|
+
|
6
|
+
# @param [Storage] storage
|
7
|
+
#
|
8
|
+
def initialize(storage)
|
9
|
+
@storage = storage
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
13
|
+
#
|
14
|
+
def fix_modulemap(node)
|
15
|
+
return unless node.has_static_library_product?
|
16
|
+
|
17
|
+
modulemap_file_path = node.modulemap_file_path
|
18
|
+
return if modulemap_file_path == nil
|
19
|
+
|
20
|
+
injected_modulemap_file_path = storage.get_modulemap_path(node)
|
21
|
+
return if injected_modulemap_file_path == nil
|
22
|
+
|
23
|
+
swift_objc_interface_header_file_name = node.swift_objc_interface_header_file
|
24
|
+
return if swift_objc_interface_header_file_name == nil
|
25
|
+
|
26
|
+
# add generated header to modulemap to make Swift stuff available module users
|
27
|
+
#
|
28
|
+
storage_path = storage.get_storage_path(node)
|
29
|
+
header_path = File.join(storage_path, swift_objc_interface_header_file_name)
|
30
|
+
return unless File.exist?(header_path)
|
31
|
+
|
32
|
+
File.open(injected_modulemap_file_path, "a") do |modulemap_file|
|
33
|
+
modulemap_file.puts "\nmodule #{node.module_name}.Swift {\n"
|
34
|
+
modulemap_file.puts " header \"#{header_path}\"\n"
|
35
|
+
modulemap_file.puts " requires objc\n"
|
36
|
+
modulemap_file.puts "}\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @return [Storage]
|
43
|
+
#
|
44
|
+
attr_accessor :storage
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/injection/storage.rb
CHANGED
@@ -31,12 +31,41 @@ module XcodeArchiveCache
|
|
31
31
|
end
|
32
32
|
|
33
33
|
file_paths.each do |file_path|
|
34
|
-
FileUtils.cp(file_path,
|
34
|
+
FileUtils.cp(file_path, get_stored_file_path(storage_path, file_path))
|
35
35
|
end
|
36
36
|
|
37
37
|
save_header_storage_path(storage_path, node)
|
38
38
|
end
|
39
39
|
|
40
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
41
|
+
# @param [Array<String>] file_paths
|
42
|
+
#
|
43
|
+
def store_default_headers(node, file_paths)
|
44
|
+
store_headers(node, get_default_headers_storage_path(node), file_paths)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
48
|
+
#
|
49
|
+
def store_modulemap(node)
|
50
|
+
modulemap_file_path = node.modulemap_file_path
|
51
|
+
if modulemap_file_path && File.exist?(modulemap_file_path)
|
52
|
+
store_headers(node, get_default_headers_storage_path(node), [modulemap_file_path])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
#
|
60
|
+
def get_modulemap_path(node)
|
61
|
+
modulemap_file_path = node.modulemap_file_path
|
62
|
+
return if modulemap_file_path == nil
|
63
|
+
|
64
|
+
storage_path = get_full_header_storage_path(get_default_headers_storage_path(node))
|
65
|
+
stored_modulemap_file_path = get_stored_file_path(storage_path, modulemap_file_path)
|
66
|
+
File.exist?(stored_modulemap_file_path) ? stored_modulemap_file_path : nil
|
67
|
+
end
|
68
|
+
|
40
69
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
41
70
|
# @param [Array<String>] file_paths
|
42
71
|
#
|
@@ -70,7 +99,7 @@ module XcodeArchiveCache
|
|
70
99
|
|
71
100
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
72
101
|
#
|
73
|
-
# @return [
|
102
|
+
# @return [String]
|
74
103
|
#
|
75
104
|
def get_headers_storage_paths(node)
|
76
105
|
headers_storage_dir_paths[node.name]
|
@@ -78,11 +107,19 @@ module XcodeArchiveCache
|
|
78
107
|
|
79
108
|
def get_all_headers_storage_paths
|
80
109
|
headers_storage_dir_paths
|
81
|
-
.map {|_, path| path}
|
110
|
+
.map { |_, path| path }
|
82
111
|
.flatten
|
83
112
|
.uniq
|
84
113
|
end
|
85
114
|
|
115
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
116
|
+
#
|
117
|
+
# @return [String]
|
118
|
+
#
|
119
|
+
def get_default_headers_storage_path(node)
|
120
|
+
"include/#{node.name}"
|
121
|
+
end
|
122
|
+
|
86
123
|
private
|
87
124
|
|
88
125
|
def prepare_container_dir
|
@@ -99,6 +136,15 @@ module XcodeArchiveCache
|
|
99
136
|
File.absolute_path(path, container_dir_path)
|
100
137
|
end
|
101
138
|
|
139
|
+
# @param [String] storage_path
|
140
|
+
# @param [String] file_path
|
141
|
+
#
|
142
|
+
# @return [String]
|
143
|
+
#
|
144
|
+
def get_stored_file_path(storage_path, file_path)
|
145
|
+
File.join(storage_path, File.basename(file_path))
|
146
|
+
end
|
147
|
+
|
102
148
|
# @param [String] path
|
103
149
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
104
150
|
#
|
data/lib/runner/runner.rb
CHANGED
@@ -92,20 +92,12 @@ module XcodeArchiveCache
|
|
92
92
|
graph_builder = XcodeArchiveCache::BuildGraph::Builder.new(@native_target_finder, xcodebuild_executor)
|
93
93
|
graph = graph_builder.build_graph(target, dependency_target)
|
94
94
|
|
95
|
-
|
95
|
+
@rebuild_evaluator.evaluate_build_graph(graph)
|
96
96
|
unpack_cached_artifacts(graph)
|
97
97
|
rebuild_if_needed(xcodebuild_executor, dependency_target, graph)
|
98
98
|
@injector.perform_outgoing_injection(graph, target)
|
99
99
|
end
|
100
100
|
|
101
|
-
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
102
|
-
#
|
103
|
-
def evaluate_for_rebuild(graph)
|
104
|
-
graph.nodes.each do |node|
|
105
|
-
@rebuild_evaluator.evaluate(node)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
101
|
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
110
102
|
#
|
111
103
|
def unpack_cached_artifacts(graph)
|
data/lib/shell/executor.rb
CHANGED
@@ -57,12 +57,12 @@ module XcodeArchiveCache
|
|
57
57
|
# @return [String]
|
58
58
|
#
|
59
59
|
def pipefail_flags(print_command)
|
60
|
-
flags =
|
60
|
+
flags = ["e", "o pipefail"]
|
61
61
|
if print_command
|
62
62
|
flags.insert(1, "x")
|
63
63
|
end
|
64
64
|
|
65
|
-
"-" + flags.join("")
|
65
|
+
"-" + flags.join(" -")
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
data/lib/xcode-archive-cache.rb
CHANGED
@@ -40,6 +40,7 @@ require 'build_settings/parser'
|
|
40
40
|
|
41
41
|
require 'injection/injector'
|
42
42
|
require 'injection/pods_script_fixer'
|
43
|
+
require 'injection/modulemap_fixer'
|
43
44
|
require 'injection/build_flags_changer'
|
44
45
|
require 'injection/dependency_remover'
|
45
46
|
require 'injection/headers_mover'
|
data/lib/xcodebuild/executor.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcode-archive-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ilya Dyakonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xcodeproj
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- lib/injection/framework_embedder.rb
|
113
113
|
- lib/injection/headers_mover.rb
|
114
114
|
- lib/injection/injector.rb
|
115
|
+
- lib/injection/modulemap_fixer.rb
|
115
116
|
- lib/injection/pods_script_fixer.rb
|
116
117
|
- lib/injection/storage.rb
|
117
118
|
- lib/logs/logs.rb
|
@@ -134,9 +135,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
134
135
|
version: 2.0.0
|
135
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
137
|
requirements:
|
137
|
-
- - "
|
138
|
+
- - ">"
|
138
139
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
140
|
+
version: 1.3.1
|
140
141
|
requirements: []
|
141
142
|
rubygems_version: 3.0.4
|
142
143
|
signing_key:
|