xcode-archive-cache 0.0.8.pre.2 → 0.0.10
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/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 +88 -5
- data/lib/build_graph/builder.rb +5 -1
- data/lib/build_graph/native_target_finder.rb +46 -11
- data/lib/build_graph/node.rb +50 -2
- data/lib/build_graph/rebuild_evaluator.rb +30 -4
- data/lib/build_graph/sha_calculator.rb +22 -1
- 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 +173 -4
- data/lib/injection/dependency_remover.rb +22 -1
- data/lib/injection/headers_mover.rb +27 -3
- data/lib/injection/injector.rb +69 -20
- data/lib/injection/storage.rb +47 -6
- data/lib/modulemap/file_handler.rb +20 -0
- data/lib/modulemap/header_path_extractor.rb +67 -0
- data/lib/modulemap/header_path_fixer.rb +65 -0
- data/lib/runner/runner.rb +31 -24
- data/lib/shell/executor.rb +2 -2
- data/lib/xcode-archive-cache.rb +4 -0
- data/lib/xcodebuild/executor.rb +4 -0
- metadata +32 -17
@@ -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
|
@@ -7,9 +7,9 @@ module XcodeArchiveCache
|
|
7
7
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
8
8
|
# @param [String] path
|
9
9
|
#
|
10
|
-
def
|
10
|
+
def replace_or_add_framework_search_path(build_configuration, target_name, path)
|
11
11
|
debug("using framework search path #{path}")
|
12
|
-
|
12
|
+
replace_or_add_flag(build_configuration, [FRAMEWORK_SEARCH_PATHS_KEY], nil, [target_name], path_to_search_path(path), true)
|
13
13
|
end
|
14
14
|
|
15
15
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
@@ -26,6 +26,37 @@ module XcodeArchiveCache
|
|
26
26
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
27
27
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
28
28
|
#
|
29
|
+
def add_static_lib_linker_flag(build_configuration, node)
|
30
|
+
flag = get_linker_flag(node)
|
31
|
+
if flag
|
32
|
+
debug("using ld flag #{flag}")
|
33
|
+
add_linker_flag(build_configuration, flag)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
38
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
39
|
+
#
|
40
|
+
def add_static_lib_libtool_flag(build_configuration, node)
|
41
|
+
flag = get_linker_flag(node)
|
42
|
+
if flag
|
43
|
+
debug("using libtool flag #{flag}")
|
44
|
+
add_libtool_flag(build_configuration, flag)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
49
|
+
# @param [String] path
|
50
|
+
#
|
51
|
+
def add_swift_include_path(build_configuration, path)
|
52
|
+
debug("adding #{path} to SWIFT_INCLUDE_PATHS")
|
53
|
+
add_flag_to_configuration(build_configuration, SWIFT_INCLUDE_PATHS_KEY, path_to_search_path(path))
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
57
|
+
# @param [String] artifact_location
|
58
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
59
|
+
#
|
29
60
|
def add_framework_headers_iquote(build_configuration, artifact_location, node)
|
30
61
|
headers_search_path = get_framework_headers_iquote(artifact_location, node)
|
31
62
|
debug("using -iquote path #{headers_search_path}")
|
@@ -35,9 +66,9 @@ module XcodeArchiveCache
|
|
35
66
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
36
67
|
# @param [String] path
|
37
68
|
#
|
38
|
-
def
|
69
|
+
def replace_or_add_library_search_path(build_configuration, target_name, path)
|
39
70
|
debug("using library search path #{path}")
|
40
|
-
|
71
|
+
replace_or_add_flag(build_configuration, [LIBRARY_SEARCH_PATHS_KEY], nil, [target_name], path_to_search_path(path), true)
|
41
72
|
end
|
42
73
|
|
43
74
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
@@ -64,15 +95,32 @@ module XcodeArchiveCache
|
|
64
95
|
add_cflag(build_configuration, path_to_capital_i(path))
|
65
96
|
end
|
66
97
|
|
98
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
99
|
+
# @param [Array<String>] old_modulemap_names
|
100
|
+
# @param [String] path
|
101
|
+
#
|
102
|
+
def fix_module_map_path(build_configuration, old_modulemap_names, path)
|
103
|
+
debug("using #{path}")
|
104
|
+
|
105
|
+
settings_with_modulemaps = [OTHER_CFLAGS_KEY, OTHER_CPLUSPLUSFLAGS_KEY, OTHER_SWIFT_FLAGS_KEY]
|
106
|
+
replace_or_add_flag(build_configuration, settings_with_modulemaps, MODULE_MAP_FLAG, old_modulemap_names, path_to_search_path(path), false)
|
107
|
+
end
|
108
|
+
|
67
109
|
private
|
68
110
|
|
69
111
|
FRAMEWORK_SEARCH_PATHS_KEY = "FRAMEWORK_SEARCH_PATHS"
|
70
112
|
LIBRARY_SEARCH_PATHS_KEY = "LIBRARY_SEARCH_PATHS"
|
71
113
|
HEADER_SEARCH_PATHS_KEY = "HEADER_SEARCH_PATHS"
|
72
114
|
OTHER_CFLAGS_KEY = "OTHER_CFLAGS"
|
115
|
+
OTHER_CPLUSPLUSFLAGS_KEY = "OTHER_CPLUSPLUSFLAGS"
|
73
116
|
OTHER_LDFLAGS_KEY = "OTHER_LDFLAGS"
|
117
|
+
OTHER_LIBTOOLFLAGS_KEY = "OTHER_LIBTOOLFLAGS"
|
118
|
+
OTHER_SWIFT_FLAGS_KEY = "OTHER_SWIFT_FLAGS"
|
119
|
+
SWIFT_INCLUDE_PATHS_KEY = "SWIFT_INCLUDE_PATHS"
|
74
120
|
INHERITED_SETTINGS_VALUE = "$(inherited)"
|
75
121
|
|
122
|
+
MODULE_MAP_FLAG = "-fmodule-map-file="
|
123
|
+
|
76
124
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
77
125
|
# @param [String] flag
|
78
126
|
#
|
@@ -80,6 +128,13 @@ module XcodeArchiveCache
|
|
80
128
|
add_flag_to_configuration(build_configuration, OTHER_LDFLAGS_KEY, flag)
|
81
129
|
end
|
82
130
|
|
131
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
132
|
+
# @param [String] flag
|
133
|
+
#
|
134
|
+
def add_libtool_flag(build_configuration, flag)
|
135
|
+
add_flag_to_configuration(build_configuration, OTHER_LIBTOOLFLAGS_KEY, flag)
|
136
|
+
end
|
137
|
+
|
83
138
|
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
84
139
|
# @param [String] flag
|
85
140
|
#
|
@@ -167,6 +222,120 @@ module XcodeArchiveCache
|
|
167
222
|
|
168
223
|
"-framework \"#{framework_name}\""
|
169
224
|
end
|
225
|
+
|
226
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
227
|
+
#
|
228
|
+
# @return [String]
|
229
|
+
#
|
230
|
+
# libSomething.a -> -lSomething
|
231
|
+
#
|
232
|
+
def get_linker_flag(node)
|
233
|
+
return unless node.product_file_name
|
234
|
+
|
235
|
+
node.product_file_name.gsub(/^lib/, "-l").gsub(/\.a$/, "")
|
236
|
+
end
|
237
|
+
|
238
|
+
# @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
|
239
|
+
# @param [Array<String>] setting_keys
|
240
|
+
# @param [String] flag_name
|
241
|
+
# @param [Array<String>] possible_old_values
|
242
|
+
# @param [String] new_value
|
243
|
+
#
|
244
|
+
def replace_or_add_flag(build_configuration, setting_keys, flag_name, possible_old_values, new_value, add_if_missing)
|
245
|
+
replaced = false
|
246
|
+
|
247
|
+
setting_keys.each do |setting|
|
248
|
+
replaced = replace_flag_value(build_configuration.build_settings, setting, flag_name, possible_old_values, new_value) || replaced
|
249
|
+
end
|
250
|
+
|
251
|
+
if build_configuration.base_configuration_reference
|
252
|
+
xcconfig_path = build_configuration.base_configuration_reference.real_path
|
253
|
+
project_dir = File.dirname(build_configuration.project.path)
|
254
|
+
|
255
|
+
replaced = replace_flag_value_in_xcconfig_recursively(xcconfig_path, project_dir, setting_keys, flag_name, possible_old_values, new_value) || replaced
|
256
|
+
end
|
257
|
+
|
258
|
+
if !replaced && add_if_missing
|
259
|
+
full_value = get_full_flag_value(flag_name, new_value)
|
260
|
+
|
261
|
+
setting_keys.each do |setting|
|
262
|
+
add_flag_to_configuration(build_configuration, setting, full_value)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# @param [String] xcconfig_path
|
268
|
+
# @param [String] project_dir
|
269
|
+
# @param [Array<String>] setting_keys
|
270
|
+
# @param [String] flag_name
|
271
|
+
# @param [Array<String>] possible_old_values
|
272
|
+
# @param [String] new_value
|
273
|
+
#
|
274
|
+
def replace_flag_value_in_xcconfig_recursively(xcconfig_path, project_dir, setting_keys, flag_name, possible_old_values, new_value)
|
275
|
+
debug("changing #{possible_old_values} to #{new_value} in #{File.basename(xcconfig_path)}")
|
276
|
+
return unless File.exist?(xcconfig_path)
|
277
|
+
|
278
|
+
replaced = false
|
279
|
+
xcconfig = Xcodeproj::Config.new(xcconfig_path)
|
280
|
+
|
281
|
+
setting_keys.each do |key|
|
282
|
+
replaced = replace_flag_value(xcconfig.attributes, key, flag_name, possible_old_values, new_value) || replaced
|
283
|
+
end
|
284
|
+
|
285
|
+
xcconfig.save_as(Pathname.new(xcconfig_path))
|
286
|
+
|
287
|
+
xcconfig.includes.each do |included_xcconfig|
|
288
|
+
included_xcconfig_path = File.join(project_dir, included_xcconfig)
|
289
|
+
replaced = replace_flag_value_in_xcconfig_recursively(included_xcconfig_path, project_dir, setting_keys, flag_name, possible_old_values, new_value) || replaced
|
290
|
+
end
|
291
|
+
|
292
|
+
replaced
|
293
|
+
end
|
294
|
+
|
295
|
+
# @param [Hash] attributes
|
296
|
+
# @param [String] setting_key
|
297
|
+
# @param [String] flag_name
|
298
|
+
# @param [Array<String>] possible_old_values
|
299
|
+
# @param [String] new_value
|
300
|
+
#
|
301
|
+
def replace_flag_value(attributes, setting_key, flag_name, possible_old_values, new_value)
|
302
|
+
build_settings = attributes[setting_key]
|
303
|
+
return unless build_settings
|
304
|
+
|
305
|
+
replaced = false
|
306
|
+
is_string = build_settings.is_a?(String)
|
307
|
+
build_settings = build_settings.split(" ") if is_string
|
308
|
+
full_value = get_full_flag_value(flag_name, new_value)
|
309
|
+
old_value_regexps = possible_old_values.map { |value| Regexp.new("#{value}\"*$") }
|
310
|
+
|
311
|
+
updated_settings = build_settings
|
312
|
+
.map { |line| line.split(" ") }
|
313
|
+
.flatten
|
314
|
+
.map do |line|
|
315
|
+
if flag_name
|
316
|
+
next line unless line.include?(flag_name)
|
317
|
+
end
|
318
|
+
|
319
|
+
updated_line = line
|
320
|
+
|
321
|
+
old_value_regexps.each do |regexp|
|
322
|
+
if regexp.match?(line)
|
323
|
+
replaced = true
|
324
|
+
updated_line = full_value
|
325
|
+
break
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
updated_line
|
330
|
+
end
|
331
|
+
|
332
|
+
attributes[setting_key] = is_string ? updated_settings.join(" ") : updated_settings
|
333
|
+
replaced
|
334
|
+
end
|
335
|
+
|
336
|
+
def get_full_flag_value(flag_name, value)
|
337
|
+
"#{flag_name}#{value}"
|
338
|
+
end
|
170
339
|
end
|
171
340
|
end
|
172
341
|
end
|
@@ -12,11 +12,21 @@ module XcodeArchiveCache
|
|
12
12
|
debug("removing #{prebuilt_target.name} from #{dependent_target.display_name}")
|
13
13
|
|
14
14
|
remove_from_dependencies(prebuilt_target, dependent_target)
|
15
|
+
remove_from_linking(prebuilt_node, dependent_target)
|
15
16
|
remove_from_schemes(prebuilt_target, dependent_target)
|
16
17
|
|
17
18
|
debug("finished removing #{prebuilt_target.name} from #{dependent_target.display_name}")
|
18
19
|
end
|
19
20
|
|
21
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
|
22
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
|
23
|
+
#
|
24
|
+
# @return [Boolean]
|
25
|
+
#
|
26
|
+
def is_linked(prebuilt_node, dependent_target)
|
27
|
+
!find_linked(prebuilt_node, dependent_target).empty?
|
28
|
+
end
|
29
|
+
|
20
30
|
private
|
21
31
|
|
22
32
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] prebuilt_target
|
@@ -46,7 +56,7 @@ module XcodeArchiveCache
|
|
46
56
|
#
|
47
57
|
def remove_from_linking(prebuilt_node, dependent_target)
|
48
58
|
debug("product name is #{prebuilt_node.product_file_name}")
|
49
|
-
frameworks = dependent_target
|
59
|
+
frameworks = find_linked(prebuilt_node, dependent_target)
|
50
60
|
debug("found #{frameworks.length} linked products")
|
51
61
|
|
52
62
|
frameworks.each do |framework|
|
@@ -67,6 +77,17 @@ module XcodeArchiveCache
|
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
80
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
|
81
|
+
# @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
|
82
|
+
#
|
83
|
+
# @return [Array<PBXBuildFile>]
|
84
|
+
#
|
85
|
+
def find_linked(prebuilt_node, dependent_target)
|
86
|
+
return [] unless dependent_target.frameworks_build_phase
|
87
|
+
|
88
|
+
dependent_target.frameworks_build_phase.files.select {|file| file.display_name == prebuilt_node.product_file_name}
|
89
|
+
end
|
90
|
+
|
70
91
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
71
92
|
#
|
72
93
|
# @return [Array<Xcodeproj::XCScheme>]
|
@@ -9,6 +9,7 @@ module XcodeArchiveCache
|
|
9
9
|
def initialize(storage)
|
10
10
|
@storage = storage
|
11
11
|
@build_settings_interpolator = XcodeArchiveCache::BuildSettings::StringInterpolator.new
|
12
|
+
@modulemap_header_path_extractor = XcodeArchiveCache::Modulemap::HeaderPathExtractor.new
|
12
13
|
end
|
13
14
|
|
14
15
|
# @param [XcodeArchiveCache::BuildGraph::Node] node
|
@@ -19,17 +20,36 @@ module XcodeArchiveCache
|
|
19
20
|
|
20
21
|
node.native_target.copy_files_build_phases.each do |build_phase|
|
21
22
|
file_paths = build_phase.files
|
22
|
-
.map {|build_file| get_real_path(build_file)}
|
23
|
+
.map { |build_file| get_real_path(build_file) }
|
23
24
|
.compact
|
24
25
|
.uniq
|
25
|
-
.select {|path| File.extname(path) == ".h"}
|
26
|
+
.select { |path| File.extname(path) == ".h" }
|
26
27
|
destination_path = get_destination_dir_path(node, build_phase)
|
27
28
|
storage.store_headers(node, destination_path, file_paths)
|
28
29
|
|
29
30
|
header_count += file_paths.length
|
30
31
|
end
|
31
32
|
|
32
|
-
|
33
|
+
if node.has_static_library_product?
|
34
|
+
headers_file_paths = node.native_target
|
35
|
+
.headers_build_phase
|
36
|
+
.files
|
37
|
+
.select { |file| file.settings && file.settings["ATTRIBUTES"].include?("Public") }
|
38
|
+
.map { |header| get_real_path(header) }
|
39
|
+
.uniq
|
40
|
+
storage.store_default_headers(node, headers_file_paths)
|
41
|
+
|
42
|
+
header_count += headers_file_paths.length
|
43
|
+
end
|
44
|
+
|
45
|
+
modulemap_file_path = node.original_modulemap_file_path
|
46
|
+
if modulemap_file_path && File.exist?(modulemap_file_path)
|
47
|
+
header_file_paths = modulemap_header_path_extractor.extract_all_paths(modulemap_file_path)
|
48
|
+
storage.store_modulemap_headers(node, header_file_paths)
|
49
|
+
header_count += header_file_paths.length
|
50
|
+
end
|
51
|
+
|
52
|
+
debug("found #{header_count} header(s)")
|
33
53
|
end
|
34
54
|
|
35
55
|
private
|
@@ -42,6 +62,10 @@ module XcodeArchiveCache
|
|
42
62
|
#
|
43
63
|
attr_reader :build_settings_interpolator
|
44
64
|
|
65
|
+
# @return [XcodeArchiveCache::Modulemap::HeaderPathExtractor]
|
66
|
+
#
|
67
|
+
attr_reader :modulemap_header_path_extractor
|
68
|
+
|
45
69
|
# @param [Xcodeproj::Project::Object::PBXBuildFile] build_file
|
46
70
|
#
|
47
71
|
# @return [String]
|
data/lib/injection/injector.rb
CHANGED
@@ -14,13 +14,14 @@ module XcodeArchiveCache
|
|
14
14
|
@dependency_remover = DependencyRemover.new
|
15
15
|
@build_flags_changer = BuildFlagsChanger.new
|
16
16
|
@pods_fixer = PodsScriptFixer.new
|
17
|
+
@modulemap_fixer = XcodeArchiveCache::Modulemap::HeaderPathFixer.new(storage)
|
17
18
|
@framework_embedder = FrameworkEmbedder.new
|
18
19
|
end
|
19
20
|
|
20
21
|
# @param [XcodeArchiveCache::BuildGraph::Graph] graph
|
21
22
|
#
|
22
23
|
def perform_internal_injection(graph)
|
23
|
-
|
24
|
+
inject_unpacked_and_rebuilt(graph.nodes)
|
24
25
|
add_header_paths(graph.nodes)
|
25
26
|
save_graph_projects(graph)
|
26
27
|
end
|
@@ -34,9 +35,15 @@ 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
|
-
|
39
|
-
|
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
|
+
|
46
|
+
add_as_prebuilt_dependency(node, target)
|
40
47
|
remove_native_target_from_project(node)
|
41
48
|
end
|
42
49
|
|
@@ -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,16 +93,26 @@ 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
|
92
103
|
|
93
104
|
# @param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
|
94
105
|
#
|
95
|
-
def
|
96
|
-
cached_nodes = nodes.select {|node| node.state == :unpacked}
|
106
|
+
def inject_unpacked_and_rebuilt(nodes)
|
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)
|
111
|
+
add_as_prebuilt_to_dependents(node)
|
112
|
+
end
|
113
|
+
|
114
|
+
built_nodes = nodes.select { |node| node.state == :rebuilt_and_cached }
|
115
|
+
built_nodes.each do |node|
|
99
116
|
add_as_prebuilt_to_dependents(node)
|
100
117
|
end
|
101
118
|
end
|
@@ -104,10 +121,11 @@ module XcodeArchiveCache
|
|
104
121
|
#
|
105
122
|
def add_header_paths(nodes)
|
106
123
|
header_storage_paths = storage.get_all_headers_storage_paths
|
124
|
+
return if header_storage_paths.length == 0
|
107
125
|
|
108
126
|
nodes
|
109
127
|
.select(&:waiting_for_rebuild)
|
110
|
-
.each {|node| add_header_paths_to_target(node.native_target, header_storage_paths)}
|
128
|
+
.each { |node| add_header_paths_to_target(node.native_target, header_storage_paths) }
|
111
129
|
end
|
112
130
|
|
113
131
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
@@ -133,8 +151,7 @@ module XcodeArchiveCache
|
|
133
151
|
.all_dependent_nodes
|
134
152
|
.select(&:waiting_for_rebuild)
|
135
153
|
dependent_to_rebuild.each do |dependent_node|
|
136
|
-
|
137
|
-
add_as_prebuilt_dependency(prebuilt_node, dependent_node.native_target, should_link)
|
154
|
+
add_as_prebuilt_dependency(prebuilt_node, dependent_node.native_target)
|
138
155
|
end
|
139
156
|
|
140
157
|
remove_native_target_from_project(prebuilt_node)
|
@@ -145,13 +162,16 @@ module XcodeArchiveCache
|
|
145
162
|
def save_graph_projects(graph)
|
146
163
|
projects = graph.nodes.map(&:native_target).map(&:project).uniq
|
147
164
|
debug("updating #{projects.length} projects")
|
148
|
-
projects.each {|project| project.save}
|
165
|
+
projects.each { |project| project.save }
|
149
166
|
end
|
150
167
|
|
151
168
|
# @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
|
152
169
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
|
153
170
|
#
|
154
|
-
def add_as_prebuilt_dependency(prebuilt_node, dependent_target
|
171
|
+
def add_as_prebuilt_dependency(prebuilt_node, dependent_target)
|
172
|
+
target_identifier = get_target_identifier(dependent_target)
|
173
|
+
return if prebuilt_node.targets_injected_to.include?(target_identifier)
|
174
|
+
|
155
175
|
debug("adding #{prebuilt_node.name} as prebuilt to #{dependent_target.display_name}")
|
156
176
|
|
157
177
|
unless prebuilt_node.has_acceptable_product?
|
@@ -161,9 +181,11 @@ module XcodeArchiveCache
|
|
161
181
|
if prebuilt_node.has_framework_product?
|
162
182
|
add_as_prebuilt_framework(prebuilt_node, dependent_target)
|
163
183
|
elsif prebuilt_node.has_static_library_product?
|
164
|
-
add_as_prebuilt_static_lib(prebuilt_node, dependent_target
|
184
|
+
add_as_prebuilt_static_lib(prebuilt_node, dependent_target)
|
165
185
|
end
|
166
186
|
|
187
|
+
prebuilt_node.targets_injected_to.push(target_identifier)
|
188
|
+
|
167
189
|
debug("done with #{prebuilt_node.name} for #{dependent_target.display_name}")
|
168
190
|
end
|
169
191
|
|
@@ -174,22 +196,41 @@ module XcodeArchiveCache
|
|
174
196
|
build_configuration = find_build_configuration(dependent_target)
|
175
197
|
|
176
198
|
artifact_location = storage.get_storage_path(prebuilt_node)
|
177
|
-
build_flags_changer.
|
199
|
+
build_flags_changer.replace_or_add_framework_search_path(build_configuration, prebuilt_node.native_target.name, artifact_location)
|
178
200
|
build_flags_changer.add_framework_headers_iquote(build_configuration, artifact_location, prebuilt_node)
|
179
201
|
|
202
|
+
if dependency_remover.is_linked(prebuilt_node, dependent_target)
|
203
|
+
build_flags_changer.add_framework_linker_flag(build_configuration, prebuilt_node)
|
204
|
+
end
|
205
|
+
|
180
206
|
dependency_remover.remove_dependency(prebuilt_node, dependent_target)
|
181
207
|
end
|
182
208
|
|
183
209
|
# @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
|
184
210
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
|
185
|
-
# @param [Boolean] should_link
|
186
211
|
#
|
187
|
-
def add_as_prebuilt_static_lib(prebuilt_node, dependent_target
|
212
|
+
def add_as_prebuilt_static_lib(prebuilt_node, dependent_target)
|
188
213
|
build_configuration = find_build_configuration(dependent_target)
|
189
214
|
|
190
|
-
|
191
|
-
|
192
|
-
|
215
|
+
injected_modulemap_file_path = storage.get_modulemap_path(prebuilt_node)
|
216
|
+
if injected_modulemap_file_path
|
217
|
+
modulemap_file_names = [prebuilt_node.resulting_modulemap_file_name]
|
218
|
+
build_flags_changer.fix_module_map_path(build_configuration, modulemap_file_names, injected_modulemap_file_path)
|
219
|
+
|
220
|
+
original_modulemap_path = prebuilt_node.original_modulemap_file_path
|
221
|
+
add_header_paths_to_target(dependent_target, [File.dirname(original_modulemap_path)])
|
222
|
+
end
|
223
|
+
|
224
|
+
artifact_location = storage.get_storage_path(prebuilt_node)
|
225
|
+
build_flags_changer.replace_or_add_library_search_path(build_configuration, prebuilt_node.native_target.name, artifact_location)
|
226
|
+
build_flags_changer.add_swift_include_path(build_configuration, artifact_location)
|
227
|
+
|
228
|
+
if dependency_remover.is_linked(prebuilt_node, dependent_target)
|
229
|
+
if dependent_target.product_type == Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]
|
230
|
+
build_flags_changer.add_static_lib_libtool_flag(build_configuration, prebuilt_node)
|
231
|
+
else
|
232
|
+
build_flags_changer.add_static_lib_linker_flag(build_configuration, prebuilt_node)
|
233
|
+
end
|
193
234
|
end
|
194
235
|
|
195
236
|
dependency_remover.remove_dependency(prebuilt_node, dependent_target)
|
@@ -198,7 +239,7 @@ module XcodeArchiveCache
|
|
198
239
|
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
199
240
|
#
|
200
241
|
def find_build_configuration(target)
|
201
|
-
build_configuration = target.build_configurations.select {|configuration| configuration.name == configuration_name}.first
|
242
|
+
build_configuration = target.build_configurations.select { |configuration| configuration.name == configuration_name }.first
|
202
243
|
unless build_configuration
|
203
244
|
raise Informative, "#{configuration_name} build configuration not found on target #{node.name}"
|
204
245
|
end
|
@@ -223,6 +264,14 @@ module XcodeArchiveCache
|
|
223
264
|
debug("deleting #{node.name} target")
|
224
265
|
node.native_target.project.targets.delete(node.native_target)
|
225
266
|
end
|
267
|
+
|
268
|
+
# @param [Xcodeproj::Project::Object::PBXNativeTarget] target
|
269
|
+
#
|
270
|
+
# @return [String]
|
271
|
+
#
|
272
|
+
def get_target_identifier(target)
|
273
|
+
target.uuid + target.project.path.realpath.to_s
|
274
|
+
end
|
226
275
|
end
|
227
276
|
end
|
228
277
|
end
|