xcode-archive-cache 0.0.10.pre.1 → 0.0.12

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.
data/lib/config/config.rb CHANGED
@@ -52,7 +52,7 @@ module XcodeArchiveCache
52
52
  def active_configuration
53
53
  configuration = configurations.select{|config| config.name == active_configuration_name }.first
54
54
  if configuration == nil
55
- raise Informative, "Found no configuration with name \"#{active_configuration_name}\""
55
+ raise XcodeArchiveCache::Informative, "Found no configuration with name \"#{active_configuration_name}\""
56
56
  end
57
57
 
58
58
  configuration
@@ -172,7 +172,7 @@ module XcodeArchiveCache
172
172
  begin
173
173
  eval(contents, nil, path)
174
174
  rescue Exception => e
175
- raise Informative, "Invalid #{File.basename(path)} file: #{e.message}"
175
+ raise XcodeArchiveCache::Informative, "Invalid #{File.basename(path)} file: #{e.message}"
176
176
  end
177
177
  end
178
178
 
@@ -0,0 +1,26 @@
1
+ module XCConfigExtensions
2
+ # @return [Bool]
3
+ #
4
+ def has_xcconfig?
5
+ base_configuration_reference != nil
6
+ end
7
+
8
+ # @return [String]
9
+ #
10
+ def get_xcconfig_path
11
+ base_configuration_reference.real_path
12
+ end
13
+ end
14
+
15
+ module ProjectDir
16
+ # @return [String]
17
+ #
18
+ def get_project_dir
19
+ File.dirname(project.path)
20
+ end
21
+ end
22
+
23
+ class Xcodeproj::Project::Object::XCBuildConfiguration
24
+ include XCConfigExtensions
25
+ include ProjectDir
26
+ end
@@ -0,0 +1,58 @@
1
+ module TargetEqualityCheck
2
+ # @return [String]
3
+ #
4
+ def equatable_identifier
5
+ uuid + display_name
6
+ end
7
+ end
8
+
9
+ module BuildConfigurationSearch
10
+ # @param [String] configuration_name
11
+ #
12
+ # @return [Xcodeproj::Project::Object::XCBuildConfiguration]
13
+ #
14
+ def find_build_configuration(configuration_name, raise_if_not_found: true)
15
+ build_configuration = build_configurations
16
+ .select { |configuration| configuration.name == configuration_name }
17
+ .first
18
+ if raise_if_not_found && build_configuration == nil
19
+ raise XcodeArchiveCache::Informative, "#{configuration_name} build configuration not found on target #{display_name} #{project.path}"
20
+ end
21
+
22
+ build_configuration
23
+ end
24
+ end
25
+
26
+ module SchellScriptBuildPhaseSearch
27
+ # @param [XcodeArchiveCache::BuildSettings::StringInterpolator] build_settings_interpolator
28
+ # @param [XcodeArchiveCache::BuildSettings::Container] build_settings
29
+ # @param [String] script_name
30
+ #
31
+ # @return [String]
32
+ #
33
+ def find_script(build_settings_interpolator, build_settings, script_name)
34
+ shell_script_build_phases.each do |phase|
35
+ if phase.display_name == script_name
36
+ return build_settings_interpolator.interpolate(phase.shell_script, build_settings)
37
+ .gsub(/^"|"$/, "")
38
+ .strip
39
+ end
40
+ end
41
+
42
+ nil
43
+ end
44
+ end
45
+
46
+ class Xcodeproj::Project::Object::PBXAggregateTarget
47
+ include XcodeArchiveCache::Logs
48
+ include TargetEqualityCheck
49
+ include BuildConfigurationSearch
50
+ include SchellScriptBuildPhaseSearch
51
+ end
52
+
53
+ class Xcodeproj::Project::Object::PBXNativeTarget
54
+ include XcodeArchiveCache::Logs
55
+ include TargetEqualityCheck
56
+ include BuildConfigurationSearch
57
+ include SchellScriptBuildPhaseSearch
58
+ 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 add_framework_search_path(build_configuration, path)
10
+ def replace_or_add_framework_search_path(build_configuration, target_name, path)
11
11
  debug("using framework search path #{path}")
12
- add_flag_to_configuration(build_configuration, FRAMEWORK_SEARCH_PATHS_KEY, path_to_search_path(path))
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 add_library_search_path(build_configuration, path)
69
+ def replace_or_add_library_search_path(build_configuration, target_name, path)
39
70
  debug("using library search path #{path}")
40
- add_flag_to_configuration(build_configuration, LIBRARY_SEARCH_PATHS_KEY, path_to_search_path(path))
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
@@ -65,24 +96,14 @@ module XcodeArchiveCache
65
96
  end
66
97
 
67
98
  # @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
99
+ # @param [Array<String>] old_modulemap_names
68
100
  # @param [String] path
69
101
  #
70
102
  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)
103
+ debug("using #{path}")
74
104
 
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
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)
86
107
  end
87
108
 
88
109
  private
@@ -93,9 +114,13 @@ module XcodeArchiveCache
93
114
  OTHER_CFLAGS_KEY = "OTHER_CFLAGS"
94
115
  OTHER_CPLUSPLUSFLAGS_KEY = "OTHER_CPLUSPLUSFLAGS"
95
116
  OTHER_LDFLAGS_KEY = "OTHER_LDFLAGS"
117
+ OTHER_LIBTOOLFLAGS_KEY = "OTHER_LIBTOOLFLAGS"
96
118
  OTHER_SWIFT_FLAGS_KEY = "OTHER_SWIFT_FLAGS"
119
+ SWIFT_INCLUDE_PATHS_KEY = "SWIFT_INCLUDE_PATHS"
97
120
  INHERITED_SETTINGS_VALUE = "$(inherited)"
98
121
 
122
+ MODULE_MAP_FLAG = "-fmodule-map-file="
123
+
99
124
  # @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
100
125
  # @param [String] flag
101
126
  #
@@ -103,6 +128,13 @@ module XcodeArchiveCache
103
128
  add_flag_to_configuration(build_configuration, OTHER_LDFLAGS_KEY, flag)
104
129
  end
105
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
+
106
138
  # @param [Xcodeproj::Project::Object::XCBuildConfiguration] build_configuration
107
139
  # @param [String] flag
108
140
  #
@@ -191,50 +223,121 @@ module XcodeArchiveCache
191
223
  "-framework \"#{framework_name}\""
192
224
  end
193
225
 
194
- # @param [Hash] build_settings
195
- # @param [String] flags_key
196
- # @param [Array<String>] old_modulemap_names
197
- # @param [String] path
226
+ # @param [XcodeArchiveCache::BuildGraph::Node] node
198
227
  #
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
228
+ # @return [String]
229
+ #
230
+ # libSomething.a -> -lSomething
231
+ #
232
+ def get_linker_flag(node)
233
+ return unless node.product_file_name
205
234
 
206
- MODULE_MAP_FLAG = "-fmodule-map-file="
235
+ node.product_file_name.gsub(/^lib/, "-l").gsub(/\.a$/, "")
236
+ end
207
237
 
208
- # @param [String] flags
209
- # @param [Array<String>] old_modulemap_names
210
- # @param [String] path
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
211
243
  #
212
- # @return [String]
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.has_xcconfig?
252
+ replaced = replace_flag_value_in_xcconfig_recursively(
253
+ build_configuration.get_xcconfig_path,
254
+ build_configuration.get_project_dir,
255
+ setting_keys,
256
+ flag_name,
257
+ possible_old_values,
258
+ new_value) || replaced
259
+ end
260
+
261
+ if !replaced && add_if_missing
262
+ full_value = get_full_flag_value(flag_name, new_value)
263
+
264
+ setting_keys.each do |setting|
265
+ add_flag_to_configuration(build_configuration, setting, full_value)
266
+ end
267
+ end
268
+ end
269
+
270
+ # @param [String] xcconfig_path
271
+ # @param [String] project_dir
272
+ # @param [Array<String>] setting_keys
273
+ # @param [String] flag_name
274
+ # @param [Array<String>] possible_old_values
275
+ # @param [String] new_value
213
276
  #
214
- def replace_module_map_path(flags, old_modulemap_names, path)
215
- return if flags == nil
277
+ def replace_flag_value_in_xcconfig_recursively(xcconfig_path, project_dir, setting_keys, flag_name, possible_old_values, new_value)
278
+ debug("changing #{possible_old_values} to #{new_value} in #{File.basename(xcconfig_path)}")
279
+ return unless File.exist?(xcconfig_path)
280
+
281
+ replaced = false
282
+ xcconfig = Xcodeproj::Config.new(xcconfig_path)
283
+
284
+ setting_keys.each do |key|
285
+ replaced = replace_flag_value(xcconfig.attributes, key, flag_name, possible_old_values, new_value) || replaced
286
+ end
287
+
288
+ xcconfig.save_as(Pathname.new(xcconfig_path))
289
+
290
+ xcconfig.includes.each do |included_xcconfig|
291
+ included_xcconfig_path = File.join(project_dir, included_xcconfig)
292
+ replaced = replace_flag_value_in_xcconfig_recursively(included_xcconfig_path, project_dir, setting_keys, flag_name, possible_old_values, new_value) || replaced
293
+ end
294
+
295
+ replaced
296
+ end
216
297
 
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(" ") }
298
+ # @param [Hash] attributes
299
+ # @param [String] setting_key
300
+ # @param [String] flag_name
301
+ # @param [Array<String>] possible_old_values
302
+ # @param [String] new_value
303
+ #
304
+ def replace_flag_value(attributes, setting_key, flag_name, possible_old_values, new_value)
305
+ build_settings = attributes[setting_key]
306
+ return unless build_settings
307
+
308
+ replaced = false
309
+ is_string = build_settings.is_a?(String)
310
+ build_settings = build_settings.split(" ") if is_string
311
+ full_value = get_full_flag_value(flag_name, new_value)
312
+ old_value_regexps = possible_old_values.map { |value| Regexp.new("/#{value}\"*$") }
313
+
314
+ updated_settings = build_settings
315
+ .map { |line| line.split(" ") }
221
316
  .flatten
222
317
  .map do |line|
318
+ if flag_name
319
+ next line unless line.include?(flag_name)
320
+ end
321
+
223
322
  updated_line = line
224
323
 
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
324
+ old_value_regexps.each do |regexp|
325
+ if regexp.match?(line)
326
+ replaced = true
327
+ updated_line = full_value
328
+ break
231
329
  end
232
330
  end
233
331
 
234
332
  updated_line
235
333
  end
236
334
 
237
- is_flags_string ? updated_flags.join(" ") : updated_flags
335
+ attributes[setting_key] = is_string ? updated_settings.join(" ") : updated_settings
336
+ replaced
337
+ end
338
+
339
+ def get_full_flag_value(flag_name, value)
340
+ "#{flag_name}#{value}"
238
341
  end
239
342
  end
240
343
  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.frameworks_build_phase.files.select {|file| file.display_name == prebuilt_node.product_file_name}
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
@@ -33,16 +34,22 @@ module XcodeArchiveCache
33
34
  headers_file_paths = node.native_target
34
35
  .headers_build_phase
35
36
  .files
37
+ .select { |file| file.settings && file.settings["ATTRIBUTES"].include?("Public") }
36
38
  .map { |header| get_real_path(header) }
37
39
  .uniq
38
40
  storage.store_default_headers(node, headers_file_paths)
39
41
 
40
42
  header_count += headers_file_paths.length
43
+ end
41
44
 
42
- storage.store_modulemap(node)
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
43
50
  end
44
51
 
45
- debug("found #{header_count} headers")
52
+ debug("found #{header_count} header(s)")
46
53
  end
47
54
 
48
55
  private
@@ -55,6 +62,10 @@ module XcodeArchiveCache
55
62
  #
56
63
  attr_reader :build_settings_interpolator
57
64
 
65
+ # @return [XcodeArchiveCache::Modulemap::HeaderPathExtractor]
66
+ #
67
+ attr_reader :modulemap_header_path_extractor
68
+
58
69
  # @param [Xcodeproj::Project::Object::PBXBuildFile] build_file
59
70
  #
60
71
  # @return [String]
@@ -13,15 +13,15 @@ module XcodeArchiveCache
13
13
  @headers_mover = HeadersMover.new(storage)
14
14
  @dependency_remover = DependencyRemover.new
15
15
  @build_flags_changer = BuildFlagsChanger.new
16
- @pods_fixer = PodsScriptFixer.new
17
- @modulemap_fixer = ModulemapFixer.new(storage)
16
+ @pods_fixer = PodsScriptFixer.new(storage)
17
+ @modulemap_fixer = XcodeArchiveCache::Modulemap::HeaderPathFixer.new(storage)
18
18
  @framework_embedder = FrameworkEmbedder.new
19
19
  end
20
20
 
21
21
  # @param [XcodeArchiveCache::BuildGraph::Graph] graph
22
22
  #
23
23
  def perform_internal_injection(graph)
24
- inject_unpacked(graph.nodes)
24
+ inject_unpacked_and_rebuilt(graph.nodes)
25
25
  add_header_paths(graph.nodes)
26
26
  save_graph_projects(graph)
27
27
  end
@@ -43,7 +43,7 @@ module XcodeArchiveCache
43
43
  modulemap_fixer.fix_modulemap(node)
44
44
  end
45
45
 
46
- add_as_prebuilt_dependency(node, target, node.is_root)
46
+ add_as_prebuilt_dependency(node, target)
47
47
  remove_native_target_from_project(node)
48
48
  end
49
49
 
@@ -55,8 +55,8 @@ module XcodeArchiveCache
55
55
  # are covered by "Embed Pods Frameworks" script
56
56
  #
57
57
  if graph.node_by_name(get_pods_target_name(target))
58
- pods_fixer.fix_embed_frameworks_script(target, graph, storage.container_dir_path)
59
- pods_fixer.fix_copy_resources_script(target, graph, storage.container_dir_path)
58
+ pods_fixer.fix_embed_frameworks_script(target, graph)
59
+ pods_fixer.fix_copy_resources_script(target, graph)
60
60
  else
61
61
  framework_nodes = graph.nodes.select { |node| node.has_framework_product? }
62
62
  framework_file_paths = framework_nodes.map { |node| File.join(storage.get_storage_path(node), node.product_file_name) }
@@ -103,13 +103,18 @@ module XcodeArchiveCache
103
103
 
104
104
  # @param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
105
105
  #
106
- def inject_unpacked(nodes)
106
+ def inject_unpacked_and_rebuilt(nodes)
107
107
  cached_nodes = nodes.select { |node| node.state == :unpacked }
108
108
  cached_nodes.each do |node|
109
109
  headers_mover.prepare_headers_for_injection(node)
110
110
  modulemap_fixer.fix_modulemap(node)
111
111
  add_as_prebuilt_to_dependents(node)
112
112
  end
113
+
114
+ built_nodes = nodes.select { |node| node.state == :rebuilt_and_cached }
115
+ built_nodes.each do |node|
116
+ add_as_prebuilt_to_dependents(node)
117
+ end
113
118
  end
114
119
 
115
120
  # @param [Array<XcodeArchiveCache::BuildGraph::Node>] nodes
@@ -131,7 +136,7 @@ module XcodeArchiveCache
131
136
 
132
137
  debug("adding #{paths} to #{target.display_name}")
133
138
 
134
- build_configuration = find_build_configuration(target)
139
+ build_configuration = target.find_build_configuration(configuration_name)
135
140
  paths.each do |path|
136
141
  build_flags_changer.add_headers_search_path(build_configuration, path)
137
142
  build_flags_changer.add_iquote_path(build_configuration, path)
@@ -146,8 +151,7 @@ module XcodeArchiveCache
146
151
  .all_dependent_nodes
147
152
  .select(&:waiting_for_rebuild)
148
153
  dependent_to_rebuild.each do |dependent_node|
149
- should_link = prebuilt_node.dependent.include?(dependent_node)
150
- add_as_prebuilt_dependency(prebuilt_node, dependent_node.native_target, should_link)
154
+ add_as_prebuilt_dependency(prebuilt_node, dependent_node.native_target)
151
155
  end
152
156
 
153
157
  remove_native_target_from_project(prebuilt_node)
@@ -164,19 +168,24 @@ module XcodeArchiveCache
164
168
  # @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
165
169
  # @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
166
170
  #
167
- def add_as_prebuilt_dependency(prebuilt_node, dependent_target, should_link)
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
+
168
175
  debug("adding #{prebuilt_node.name} as prebuilt to #{dependent_target.display_name}")
169
176
 
170
177
  unless prebuilt_node.has_acceptable_product?
171
- raise Informative, "#{prebuilt_node.name} has unsupported product type: #{prebuilt_node.native_target.product_type}"
178
+ raise XcodeArchiveCache::Informative, "#{prebuilt_node.name} has unsupported product type: #{prebuilt_node.native_target.product_type}"
172
179
  end
173
180
 
174
181
  if prebuilt_node.has_framework_product?
175
182
  add_as_prebuilt_framework(prebuilt_node, dependent_target)
176
183
  elsif prebuilt_node.has_static_library_product?
177
- add_as_prebuilt_static_lib(prebuilt_node, dependent_target, should_link)
184
+ add_as_prebuilt_static_lib(prebuilt_node, dependent_target)
178
185
  end
179
186
 
187
+ prebuilt_node.targets_injected_to.push(target_identifier)
188
+
180
189
  debug("done with #{prebuilt_node.name} for #{dependent_target.display_name}")
181
190
  end
182
191
 
@@ -184,45 +193,47 @@ module XcodeArchiveCache
184
193
  # @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
185
194
  #
186
195
  def add_as_prebuilt_framework(prebuilt_node, dependent_target)
187
- build_configuration = find_build_configuration(dependent_target)
196
+ build_configuration = dependent_target.find_build_configuration(configuration_name)
188
197
 
189
198
  artifact_location = storage.get_storage_path(prebuilt_node)
190
- build_flags_changer.add_framework_search_path(build_configuration, artifact_location)
199
+ build_flags_changer.replace_or_add_framework_search_path(build_configuration, prebuilt_node.native_target.name, artifact_location)
191
200
  build_flags_changer.add_framework_headers_iquote(build_configuration, artifact_location, prebuilt_node)
192
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
+
193
206
  dependency_remover.remove_dependency(prebuilt_node, dependent_target)
194
207
  end
195
208
 
196
209
  # @param [XcodeArchiveCache::BuildGraph::Node] prebuilt_node
197
210
  # @param [Xcodeproj::Project::Object::PBXNativeTarget] dependent_target
198
- # @param [Boolean] should_link
199
211
  #
200
- def add_as_prebuilt_static_lib(prebuilt_node, dependent_target, should_link)
201
- build_configuration = find_build_configuration(dependent_target)
212
+ def add_as_prebuilt_static_lib(prebuilt_node, dependent_target)
213
+ build_configuration = dependent_target.find_build_configuration(configuration_name)
202
214
 
203
215
  injected_modulemap_file_path = storage.get_modulemap_path(prebuilt_node)
204
216
  if injected_modulemap_file_path
205
- modulemap_file_names = ["#{prebuilt_node.module_name}.modulemap", File.basename(prebuilt_node.modulemap_file_path)]
217
+ modulemap_file_names = [prebuilt_node.resulting_modulemap_file_name]
206
218
  build_flags_changer.fix_module_map_path(build_configuration, modulemap_file_names, injected_modulemap_file_path)
207
- end
208
-
209
- # if should_link
210
- artifact_location = storage.get_storage_path(prebuilt_node)
211
- build_flags_changer.add_library_search_path(build_configuration, artifact_location)
212
- # end
213
219
 
214
- dependency_remover.remove_dependency(prebuilt_node, dependent_target)
215
- end
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
216
223
 
217
- # @param [Xcodeproj::Project::Object::PBXNativeTarget] target
218
- #
219
- def find_build_configuration(target)
220
- build_configuration = target.build_configurations.select { |configuration| configuration.name == configuration_name }.first
221
- unless build_configuration
222
- raise Informative, "#{configuration_name} build configuration not found on target #{node.name}"
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
223
234
  end
224
235
 
225
- build_configuration
236
+ dependency_remover.remove_dependency(prebuilt_node, dependent_target)
226
237
  end
227
238
 
228
239
  # @param [Xcodeproj::Project::Object::PBXNativeTarget] target
@@ -242,6 +253,14 @@ module XcodeArchiveCache
242
253
  debug("deleting #{node.name} target")
243
254
  node.native_target.project.targets.delete(node.native_target)
244
255
  end
256
+
257
+ # @param [Xcodeproj::Project::Object::PBXNativeTarget] target
258
+ #
259
+ # @return [String]
260
+ #
261
+ def get_target_identifier(target)
262
+ target.uuid + target.project.path.realpath.to_s
263
+ end
245
264
  end
246
265
  end
247
266
  end