xcodeproj 1.7.0 → 1.19.0
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/xcodeproj/command/config_dump.rb +5 -1
- data/lib/xcodeproj/config.rb +3 -1
- data/lib/xcodeproj/config/other_linker_flags_parser.rb +2 -2
- data/lib/xcodeproj/constants.rb +70 -44
- data/lib/xcodeproj/gem_version.rb +1 -1
- data/lib/xcodeproj/project.rb +23 -2
- data/lib/xcodeproj/project/object.rb +3 -1
- data/lib/xcodeproj/project/object/build_configuration.rb +96 -35
- data/lib/xcodeproj/project/object/build_file.rb +9 -1
- data/lib/xcodeproj/project/object/build_phase.rb +45 -4
- data/lib/xcodeproj/project/object/build_rule.rb +12 -0
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +11 -4
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +13 -6
- data/lib/xcodeproj/project/object/native_target.rb +52 -9
- data/lib/xcodeproj/project/object/root_object.rb +15 -2
- data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +19 -0
- data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +19 -0
- data/lib/xcodeproj/project/object/target_dependency.rb +9 -0
- data/lib/xcodeproj/project/project_helper.rb +2 -1
- data/lib/xcodeproj/project/uuid_generator.rb +41 -19
- data/lib/xcodeproj/scheme.rb +6 -4
- data/lib/xcodeproj/scheme/build_action.rb +21 -0
- data/lib/xcodeproj/scheme/buildable_reference.rb +3 -1
- data/lib/xcodeproj/scheme/launch_action.rb +50 -0
- data/lib/xcodeproj/scheme/test_action.rb +36 -1
- data/lib/xcodeproj/workspace.rb +16 -7
- data/lib/xcodeproj/workspace/file_reference.rb +7 -12
- data/lib/xcodeproj/workspace/group_reference.rb +18 -15
- data/lib/xcodeproj/workspace/reference.rb +40 -0
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72f6eb6645b557dea09ae4be0fd400e48b0d4f1e42c31b7b61af87fd3c31a9cd
|
4
|
+
data.tar.gz: 0c0bcfa7abc28721f61f48e295198da53576e90d62161c50a6cc7333c1e94455
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f856d8cbee5b9b7b6bcbe7acce4034e8277fd05ac7caf0d2c317f75d622bb5c518dd2ddee67dac1c6a7fb2773aebb5a5de2cf2232af3fffc2353323fd08623d
|
7
|
+
data.tar.gz: 9cf088a34dea380b56716f005c35fc601d9b193a0a4908556d4f8ccc80408ee328755ccb767dc0ed50adc0bc3e822cc9bcdcdeac405c97fc514f6dd429f746ac
|
@@ -76,7 +76,11 @@ module Xcodeproj
|
|
76
76
|
|
77
77
|
def dump_config_to_file(settings, file_path, includes = [])
|
78
78
|
dir = @output_path + file_path + '..'
|
79
|
-
dir.
|
79
|
+
dir.mkpath
|
80
|
+
|
81
|
+
settings = Hash[settings.map do |k, v|
|
82
|
+
[k, Array(v).join(' ')]
|
83
|
+
end]
|
80
84
|
|
81
85
|
config = Config.new(settings)
|
82
86
|
config.includes = includes
|
data/lib/xcodeproj/config.rb
CHANGED
@@ -157,6 +157,8 @@ module Xcodeproj
|
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
|
+
alias_method :to_h, :to_hash
|
161
|
+
|
160
162
|
# @return [Set<String>] The list of the frameworks required by this
|
161
163
|
# settings file.
|
162
164
|
#
|
@@ -275,7 +277,7 @@ module Xcodeproj
|
|
275
277
|
string.split("\n").each do |line|
|
276
278
|
uncommented_line = strip_comment(line)
|
277
279
|
if include = extract_include(uncommented_line)
|
278
|
-
@includes.push include
|
280
|
+
@includes.push normalized_xcconfig_path(include)
|
279
281
|
else
|
280
282
|
key, value = extract_key_value(uncommented_line)
|
281
283
|
next unless key
|
@@ -55,13 +55,13 @@ module Xcodeproj
|
|
55
55
|
# The other linker flags value.
|
56
56
|
#
|
57
57
|
def self.split(flags)
|
58
|
-
flags.strip.shellsplit.
|
58
|
+
flags.strip.shellsplit.flat_map do |string|
|
59
59
|
if string =~ /\A-l.+/
|
60
60
|
['-l', string[2..-1]]
|
61
61
|
else
|
62
62
|
string
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
data/lib/xcodeproj/constants.rb
CHANGED
@@ -4,17 +4,19 @@ module Xcodeproj
|
|
4
4
|
module Constants
|
5
5
|
# @return [String] The last known iOS SDK (stable).
|
6
6
|
#
|
7
|
-
LAST_KNOWN_IOS_SDK = '
|
7
|
+
LAST_KNOWN_IOS_SDK = '14.0'
|
8
8
|
|
9
9
|
# @return [String] The last known OS X SDK (stable).
|
10
10
|
#
|
11
|
-
LAST_KNOWN_OSX_SDK = '10.
|
11
|
+
LAST_KNOWN_OSX_SDK = '10.15'
|
12
12
|
|
13
13
|
# @return [String] The last known tvOS SDK (stable).
|
14
|
-
|
14
|
+
#
|
15
|
+
LAST_KNOWN_TVOS_SDK = '14.0'
|
15
16
|
|
16
17
|
# @return [String] The last known watchOS SDK (stable).
|
17
|
-
|
18
|
+
#
|
19
|
+
LAST_KNOWN_WATCHOS_SDK = '7.0'
|
18
20
|
|
19
21
|
# @return [String] The last known archive version to Xcodeproj.
|
20
22
|
#
|
@@ -22,22 +24,23 @@ module Xcodeproj
|
|
22
24
|
|
23
25
|
# @return [String] The last known Swift version (stable).
|
24
26
|
#
|
25
|
-
LAST_KNOWN_SWIFT_VERSION = '
|
27
|
+
LAST_KNOWN_SWIFT_VERSION = '5.0'
|
26
28
|
|
27
29
|
# @return [String] The default object version for Xcodeproj.
|
30
|
+
#
|
28
31
|
DEFAULT_OBJECT_VERSION = 46
|
29
32
|
|
30
33
|
# @return [String] The last known object version to Xcodeproj.
|
31
34
|
#
|
32
|
-
LAST_KNOWN_OBJECT_VERSION =
|
35
|
+
LAST_KNOWN_OBJECT_VERSION = 54
|
33
36
|
|
34
37
|
# @return [String] The last known object version to Xcodeproj.
|
35
38
|
#
|
36
|
-
LAST_UPGRADE_CHECK = '
|
39
|
+
LAST_UPGRADE_CHECK = '1100'
|
37
40
|
|
38
41
|
# @return [String] The last known object version to Xcodeproj.
|
39
42
|
#
|
40
|
-
LAST_SWIFT_UPGRADE_CHECK = '
|
43
|
+
LAST_SWIFT_UPGRADE_CHECK = '1100'
|
41
44
|
|
42
45
|
# @return [String] The version of `.xcscheme` files supported by Xcodeproj
|
43
46
|
#
|
@@ -90,12 +93,14 @@ module Xcodeproj
|
|
90
93
|
'app' => 'wrapper.application',
|
91
94
|
'appex' => 'wrapper.app-extension',
|
92
95
|
'bundle' => 'wrapper.plug-in',
|
96
|
+
'cpp' => 'sourcecode.cpp.cpp',
|
93
97
|
'dylib' => 'compiled.mach-o.dylib',
|
94
98
|
'entitlements' => 'text.plist.entitlements',
|
95
99
|
'framework' => 'wrapper.framework',
|
96
100
|
'gif' => 'image.gif',
|
97
101
|
'gpx' => 'text.xml',
|
98
102
|
'h' => 'sourcecode.c.h',
|
103
|
+
'hpp' => 'sourcecode.cpp.h',
|
99
104
|
'm' => 'sourcecode.c.objc',
|
100
105
|
'markdown' => 'text',
|
101
106
|
'mdimporter' => 'wrapper.cfbundle',
|
@@ -120,44 +125,65 @@ module Xcodeproj
|
|
120
125
|
'zip' => 'archive.zip',
|
121
126
|
}.freeze
|
122
127
|
|
128
|
+
# @return [Hash] The compatibility version string for different object versions.
|
129
|
+
#
|
130
|
+
COMPATIBILITY_VERSION_BY_OBJECT_VERSION = {
|
131
|
+
54 => 'Xcode 12.0',
|
132
|
+
53 => 'Xcode 11.4',
|
133
|
+
52 => 'Xcode 11.0',
|
134
|
+
51 => 'Xcode 10.0',
|
135
|
+
50 => 'Xcode 9.3',
|
136
|
+
48 => 'Xcode 8.0',
|
137
|
+
47 => 'Xcode 6.3',
|
138
|
+
46 => 'Xcode 3.2',
|
139
|
+
45 => 'Xcode 3.1',
|
140
|
+
}.freeze
|
141
|
+
|
123
142
|
# @return [Hash] The uniform type identifier of various product types.
|
124
143
|
#
|
125
144
|
PRODUCT_TYPE_UTI = {
|
126
|
-
:application
|
127
|
-
:
|
128
|
-
:
|
129
|
-
:
|
130
|
-
:
|
131
|
-
:
|
132
|
-
:
|
133
|
-
:
|
134
|
-
:
|
135
|
-
:
|
136
|
-
:
|
137
|
-
:
|
138
|
-
:
|
139
|
-
:
|
140
|
-
:
|
141
|
-
:
|
142
|
-
:
|
143
|
-
:
|
144
|
-
:
|
145
|
+
:application => 'com.apple.product-type.application',
|
146
|
+
:application_on_demand_install_capable => 'com.apple.product-type.application.on-demand-install-capable',
|
147
|
+
:framework => 'com.apple.product-type.framework',
|
148
|
+
:dynamic_library => 'com.apple.product-type.library.dynamic',
|
149
|
+
:static_library => 'com.apple.product-type.library.static',
|
150
|
+
:bundle => 'com.apple.product-type.bundle',
|
151
|
+
:octest_bundle => 'com.apple.product-type.bundle',
|
152
|
+
:unit_test_bundle => 'com.apple.product-type.bundle.unit-test',
|
153
|
+
:ui_test_bundle => 'com.apple.product-type.bundle.ui-testing',
|
154
|
+
:app_extension => 'com.apple.product-type.app-extension',
|
155
|
+
:command_line_tool => 'com.apple.product-type.tool',
|
156
|
+
:watch_app => 'com.apple.product-type.application.watchapp',
|
157
|
+
:watch2_app => 'com.apple.product-type.application.watchapp2',
|
158
|
+
:watch2_app_container => 'com.apple.product-type.application.watchapp2-container',
|
159
|
+
:watch_extension => 'com.apple.product-type.watchkit-extension',
|
160
|
+
:watch2_extension => 'com.apple.product-type.watchkit2-extension',
|
161
|
+
:tv_extension => 'com.apple.product-type.tv-app-extension',
|
162
|
+
:messages_application => 'com.apple.product-type.application.messages',
|
163
|
+
:messages_extension => 'com.apple.product-type.app-extension.messages',
|
164
|
+
:sticker_pack => 'com.apple.product-type.app-extension.messages-sticker-pack',
|
165
|
+
:xpc_service => 'com.apple.product-type.xpc-service',
|
145
166
|
}.freeze
|
146
167
|
|
147
168
|
# @return [Hash] The extensions or the various product UTIs.
|
148
169
|
#
|
149
170
|
PRODUCT_UTI_EXTENSIONS = {
|
150
|
-
:application
|
151
|
-
:
|
152
|
-
:
|
153
|
-
:
|
154
|
-
:
|
155
|
-
:
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
171
|
+
:application => 'app',
|
172
|
+
:application_on_demand_install_capable => 'app',
|
173
|
+
:framework => 'framework',
|
174
|
+
:dynamic_library => 'dylib',
|
175
|
+
:static_library => 'a',
|
176
|
+
:bundle => 'bundle',
|
177
|
+
:octest_bundle => 'octest',
|
178
|
+
:unit_test_bundle => 'xctest',
|
179
|
+
:ui_test_bundle => 'xctest',
|
180
|
+
:app_extension => 'appex',
|
181
|
+
:messages_application => 'app',
|
182
|
+
:messages_extension => 'appex',
|
183
|
+
:sticker_pack => 'appex',
|
184
|
+
:watch2_extension => 'appex',
|
185
|
+
:watch2_app => 'app',
|
186
|
+
:watch2_app_container => 'app',
|
161
187
|
}.freeze
|
162
188
|
|
163
189
|
# @return [Hash] The common build settings grouped by platform, and build
|
@@ -178,11 +204,9 @@ module Xcodeproj
|
|
178
204
|
}.freeze,
|
179
205
|
[:ios] => {
|
180
206
|
'SDKROOT' => 'iphoneos',
|
181
|
-
'CODE_SIGN_IDENTITY' => 'iPhone Developer',
|
182
207
|
}.freeze,
|
183
208
|
[:osx] => {
|
184
209
|
'SDKROOT' => 'macosx',
|
185
|
-
'CODE_SIGN_IDENTITY' => '-',
|
186
210
|
}.freeze,
|
187
211
|
[:tvos] => {
|
188
212
|
'SDKROOT' => 'appletvos',
|
@@ -231,7 +255,6 @@ module Xcodeproj
|
|
231
255
|
[:debug, :static_library, :swift] => {
|
232
256
|
}.freeze,
|
233
257
|
[:framework] => {
|
234
|
-
'CODE_SIGN_IDENTITY' => '',
|
235
258
|
'CURRENT_PROJECT_VERSION' => '1',
|
236
259
|
'DEFINES_MODULE' => 'YES',
|
237
260
|
'DYLIB_COMPATIBILITY_VERSION' => '1',
|
@@ -249,7 +272,6 @@ module Xcodeproj
|
|
249
272
|
}.freeze,
|
250
273
|
[:osx, :framework] => {
|
251
274
|
'COMBINE_HIDPI_IMAGES' => 'YES',
|
252
|
-
'FRAMEWORK_VERSION' => 'A',
|
253
275
|
'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) @executable_path/../Frameworks @loader_path/Frameworks',
|
254
276
|
}.freeze,
|
255
277
|
[:watchos, :framework] => {
|
@@ -291,6 +313,7 @@ module Xcodeproj
|
|
291
313
|
}.freeze,
|
292
314
|
[:application] => {
|
293
315
|
'ASSETCATALOG_COMPILER_APPICON_NAME' => 'AppIcon',
|
316
|
+
'ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME' => 'AccentColor',
|
294
317
|
}.freeze,
|
295
318
|
[:ios, :application] => {
|
296
319
|
'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) @executable_path/Frameworks',
|
@@ -306,10 +329,12 @@ module Xcodeproj
|
|
306
329
|
}.freeze,
|
307
330
|
[:tvos, :application] => {
|
308
331
|
'ASSETCATALOG_COMPILER_APPICON_NAME' => 'App Icon & Top Shelf Image',
|
309
|
-
'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME' => 'LaunchImage',
|
310
332
|
'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) @executable_path/Frameworks',
|
311
333
|
'TARGETED_DEVICE_FAMILY' => '3',
|
312
334
|
}.freeze,
|
335
|
+
[:tvos, :application, :swift] => {
|
336
|
+
'ENABLE_PREVIEWS' => 'YES',
|
337
|
+
}.freeze,
|
313
338
|
[:watchos, :application, :swift] => {
|
314
339
|
'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES' => 'YES',
|
315
340
|
}.freeze,
|
@@ -355,6 +380,7 @@ module Xcodeproj
|
|
355
380
|
'CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF' => 'YES',
|
356
381
|
'CLANG_WARN_OBJC_LITERAL_CONVERSION' => 'YES',
|
357
382
|
'CLANG_WARN_OBJC_ROOT_CLASS' => 'YES_ERROR',
|
383
|
+
'CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER' => 'YES',
|
358
384
|
'CLANG_WARN_RANGE_LOOP_ANALYSIS' => 'YES',
|
359
385
|
'CLANG_WARN_STRICT_PROTOTYPES' => 'YES',
|
360
386
|
'CLANG_WARN_SUSPICIOUS_MOVE' => 'YES',
|
@@ -372,7 +398,7 @@ module Xcodeproj
|
|
372
398
|
'GCC_WARN_UNUSED_VARIABLE' => 'YES',
|
373
399
|
'MTL_FAST_MATH' => 'YES',
|
374
400
|
'PRODUCT_NAME' => '$(TARGET_NAME)',
|
375
|
-
'SWIFT_VERSION' => '
|
401
|
+
'SWIFT_VERSION' => '5.0',
|
376
402
|
},
|
377
403
|
:release => {
|
378
404
|
'DEBUG_INFORMATION_FORMAT' => 'dwarf-with-dsym',
|
data/lib/xcodeproj/project.rb
CHANGED
@@ -80,6 +80,10 @@ module Xcodeproj
|
|
80
80
|
unless skip_initialization
|
81
81
|
initialize_from_scratch
|
82
82
|
@object_version = object_version.to_s
|
83
|
+
unless Constants::COMPATIBILITY_VERSION_BY_OBJECT_VERSION.key?(object_version)
|
84
|
+
raise ArgumentError, "[Xcodeproj] Unable to find compatibility version string for object version `#{object_version}`."
|
85
|
+
end
|
86
|
+
root_object.compatibility_version = Constants::COMPATIBILITY_VERSION_BY_OBJECT_VERSION[object_version]
|
83
87
|
end
|
84
88
|
end
|
85
89
|
|
@@ -388,7 +392,24 @@ module Xcodeproj
|
|
388
392
|
# @return [void]
|
389
393
|
#
|
390
394
|
def predictabilize_uuids
|
391
|
-
UUIDGenerator.new(self).generate!
|
395
|
+
UUIDGenerator.new([self]).generate!
|
396
|
+
end
|
397
|
+
|
398
|
+
# Replaces all the UUIDs in the list of provided projects with deterministic MD5 checksums.
|
399
|
+
#
|
400
|
+
# @param [Array<Project>] projects
|
401
|
+
#
|
402
|
+
# @note The current sorting of the project is taken into account when
|
403
|
+
# generating the new UUIDs.
|
404
|
+
#
|
405
|
+
# @note This method should only be used for entirely machine-generated
|
406
|
+
# projects, as true UUIDs are useful for tracking changes in the
|
407
|
+
# project.
|
408
|
+
#
|
409
|
+
# @return [void]
|
410
|
+
#
|
411
|
+
def self.predictabilize_uuids(projects)
|
412
|
+
UUIDGenerator.new(projects).generate!
|
392
413
|
end
|
393
414
|
|
394
415
|
public
|
@@ -568,7 +589,7 @@ module Xcodeproj
|
|
568
589
|
#
|
569
590
|
def embedded_targets_in_native_target(native_target)
|
570
591
|
native_targets.select do |target|
|
571
|
-
host_targets_for_embedded_target(target).
|
592
|
+
host_targets_for_embedded_target(target).any? { |host| host.uuid == native_target.uuid }
|
572
593
|
end
|
573
594
|
end
|
574
595
|
|
@@ -350,7 +350,7 @@ module Xcodeproj
|
|
350
350
|
unless object = project.objects_by_uuid[uuid] || project.new_from_plist(uuid, objects_by_uuid_plist)
|
351
351
|
UI.warn "`#{inspect}` attempted to initialize an object with " \
|
352
352
|
"an unknown UUID. `#{uuid}` for attribute: " \
|
353
|
-
"`#{attribute.name}`. This can be the result of a merge and
|
353
|
+
"`#{attribute.name}`. This can be the result of a merge and " \
|
354
354
|
'the unknown UUID is being discarded.'
|
355
355
|
end
|
356
356
|
object
|
@@ -518,6 +518,8 @@ Xcodeproj::Constants::KNOWN_ISAS.each do |superclass_name, isas|
|
|
518
518
|
end
|
519
519
|
|
520
520
|
# Now load the concrete subclasses.
|
521
|
+
require 'xcodeproj/project/object/swift_package_remote_reference'
|
522
|
+
require 'xcodeproj/project/object/swift_package_product_dependency'
|
521
523
|
require 'xcodeproj/project/object/build_configuration'
|
522
524
|
require 'xcodeproj/project/object/build_file'
|
523
525
|
require 'xcodeproj/project/object/build_phase'
|
@@ -6,6 +6,10 @@ module Xcodeproj
|
|
6
6
|
# {PBXProject} or a {PBXNativeTarget}.
|
7
7
|
#
|
8
8
|
class XCBuildConfiguration < AbstractObject
|
9
|
+
MUTUAL_RECURSION_SENTINEL = 'xcodeproj.mutual_recursion_sentinel'.freeze
|
10
|
+
|
11
|
+
private_constant :MUTUAL_RECURSION_SENTINEL
|
12
|
+
|
9
13
|
# @!group Attributes
|
10
14
|
|
11
15
|
# @return [String] the name of the Target.
|
@@ -79,21 +83,36 @@ module Xcodeproj
|
|
79
83
|
# the key of the build setting.
|
80
84
|
#
|
81
85
|
# @param [PBXNativeTarget] root_target
|
82
|
-
# use this to resolve complete recursion between project and targets
|
86
|
+
# use this to resolve complete recursion between project and targets.
|
87
|
+
#
|
88
|
+
# @param [String] previous_key
|
89
|
+
# use this to resolve complete recursion between different build settings.
|
83
90
|
#
|
84
91
|
# @return [String] The value of the build setting
|
85
92
|
#
|
86
|
-
def resolve_build_setting(key, root_target = nil)
|
93
|
+
def resolve_build_setting(key, root_target = nil, previous_key = nil)
|
87
94
|
setting = build_settings[key]
|
88
|
-
setting = resolve_variable_substitution(key, setting, root_target
|
89
|
-
|
90
|
-
config_setting =
|
95
|
+
setting = resolve_variable_substitution(key, setting, root_target, previous_key)
|
96
|
+
|
97
|
+
config_setting = config[key]
|
98
|
+
config_setting = resolve_variable_substitution(key, config_setting, root_target, previous_key)
|
91
99
|
|
92
100
|
project_setting = project.build_configuration_list[name]
|
93
|
-
project_setting = nil if project_setting
|
101
|
+
project_setting = nil if equal?(project_setting)
|
94
102
|
project_setting &&= project_setting.resolve_build_setting(key, root_target)
|
95
103
|
|
96
|
-
|
104
|
+
defaults = {
|
105
|
+
'CONFIGURATION' => name,
|
106
|
+
'SRCROOT' => project.project_dir.to_s,
|
107
|
+
}
|
108
|
+
|
109
|
+
# if previous_key is nil, it means that we're back at the first call, so we can replace our sentinel string
|
110
|
+
# used to prevent recursion with nil
|
111
|
+
if previous_key.nil? && setting == MUTUAL_RECURSION_SENTINEL
|
112
|
+
setting = nil
|
113
|
+
end
|
114
|
+
|
115
|
+
[defaults[key], project_setting, config_setting, setting, ENV[key]].compact.reduce(nil) do |inherited, value|
|
97
116
|
expand_build_setting(value, inherited)
|
98
117
|
end
|
99
118
|
end
|
@@ -102,15 +121,25 @@ module Xcodeproj
|
|
102
121
|
|
103
122
|
private
|
104
123
|
|
124
|
+
VARIABLE_NAME_PATTERN =
|
125
|
+
'( # capture block
|
126
|
+
[_a-zA-Z0-9]+? # non-greedy lookup for everything contained in this list
|
127
|
+
)'.freeze
|
128
|
+
private_constant :VARIABLE_NAME_PATTERN
|
129
|
+
|
105
130
|
CAPTURE_VARIABLE_IN_BUILD_CONFIG = /
|
106
131
|
\$ # matches dollar sign literally
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
[
|
111
|
-
|
112
|
-
|
132
|
+
(?: # non-capturing group
|
133
|
+
[{] # matches a single character on this list
|
134
|
+
#{VARIABLE_NAME_PATTERN}
|
135
|
+
[}] # matches a single character on this list
|
136
|
+
| # or
|
137
|
+
[(] # matches a single character on this list
|
138
|
+
#{VARIABLE_NAME_PATTERN}
|
139
|
+
[)] # matches a single character on this list
|
140
|
+
)
|
113
141
|
/x
|
142
|
+
private_constant :CAPTURE_VARIABLE_IN_BUILD_CONFIG
|
114
143
|
|
115
144
|
def expand_build_setting(build_setting_value, config_value)
|
116
145
|
if build_setting_value.is_a?(Array) && config_value.is_a?(String)
|
@@ -123,27 +152,52 @@ module Xcodeproj
|
|
123
152
|
inherited = config_value || default
|
124
153
|
|
125
154
|
return build_setting_value.gsub(Regexp.union(Constants::INHERITED_KEYWORDS), inherited) if build_setting_value.is_a? String
|
126
|
-
build_setting_value.
|
155
|
+
build_setting_value.flat_map { |value| Constants::INHERITED_KEYWORDS.include?(value) ? inherited : value }
|
127
156
|
end
|
128
157
|
|
129
|
-
def resolve_variable_substitution(key, value, root_target)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
158
|
+
def resolve_variable_substitution(key, value, root_target, previous_key = nil)
|
159
|
+
case value
|
160
|
+
when Array
|
161
|
+
return value.map { |v| resolve_variable_substitution(key, v, root_target) }
|
162
|
+
when nil
|
163
|
+
return
|
164
|
+
when String
|
165
|
+
# we know how to resolve strings!
|
166
|
+
nil
|
167
|
+
else
|
168
|
+
raise ArgumentError, "Settings values can only be nil, string, or array, got #{value.inspect} for #{key}"
|
139
169
|
end
|
140
|
-
resolve_variable_substitution(key, value.sub(CAPTURE_VARIABLE_IN_BUILD_CONFIG, resolve_variable_substitution(key, variable, root_target)), root_target)
|
141
|
-
end
|
142
170
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
171
|
+
unless variable_match_data = value.match(CAPTURE_VARIABLE_IN_BUILD_CONFIG)
|
172
|
+
# no variables left, return the value unchanged
|
173
|
+
return value
|
174
|
+
end
|
175
|
+
variable_reference, variable = *variable_match_data.values_at(0, 1, 2).compact
|
176
|
+
|
177
|
+
case variable
|
178
|
+
when 'inherited'
|
179
|
+
# this is handled separately, after resolving all other variable references
|
180
|
+
value
|
181
|
+
when key
|
182
|
+
# to prevent infinite recursion
|
183
|
+
nil
|
184
|
+
when previous_key
|
185
|
+
# to prevent infinite recursion; we don't return nil as for the self recursion because it needs to be
|
186
|
+
# distinguished outside this method too
|
187
|
+
MUTUAL_RECURSION_SENTINEL
|
188
|
+
else
|
189
|
+
configuration_to_resolve_against = root_target ? root_target.build_configuration_list[name] : self
|
190
|
+
resolved_value_for_variable = configuration_to_resolve_against.resolve_build_setting(variable, root_target, key) || ''
|
191
|
+
|
192
|
+
# we use this sentinel string instead of nil, because, otherwise, it would be swallowed by the default empty
|
193
|
+
# string from the preceding line, and we want to distinguish between mutual recursion and other cases
|
194
|
+
if resolved_value_for_variable == MUTUAL_RECURSION_SENTINEL
|
195
|
+
return MUTUAL_RECURSION_SENTINEL
|
196
|
+
end
|
197
|
+
|
198
|
+
value = value.gsub(variable_reference, resolved_value_for_variable)
|
199
|
+
resolve_variable_substitution(key, value, root_target)
|
200
|
+
end
|
147
201
|
end
|
148
202
|
|
149
203
|
def sorted_build_settings
|
@@ -161,14 +215,15 @@ module Xcodeproj
|
|
161
215
|
|
162
216
|
settings.keys.each do |key|
|
163
217
|
next unless value = settings[key]
|
218
|
+
stripped_key = key.sub(/\[[^\]]+\]$/, '')
|
164
219
|
case value
|
165
220
|
when String
|
166
|
-
next unless array_settings.include?(
|
221
|
+
next unless array_settings.include?(stripped_key)
|
167
222
|
array_value = split_build_setting_array_to_string(value)
|
168
223
|
next unless array_value.size > 1
|
169
224
|
settings[key] = array_value
|
170
225
|
when Array
|
171
|
-
next if value.size > 1 && array_settings.include?(
|
226
|
+
next if value.size > 1 && array_settings.include?(stripped_key)
|
172
227
|
settings[key] = value.join(' ')
|
173
228
|
end
|
174
229
|
end
|
@@ -180,9 +235,15 @@ module Xcodeproj
|
|
180
235
|
end
|
181
236
|
|
182
237
|
def config
|
183
|
-
|
184
|
-
|
185
|
-
|
238
|
+
return {} unless base_configuration_reference
|
239
|
+
@config ||=
|
240
|
+
if base_configuration_reference.real_path.exist?
|
241
|
+
Xcodeproj::Config.new(base_configuration_reference.real_path).to_hash.tap do |hash|
|
242
|
+
normalize_array_settings(hash)
|
243
|
+
end
|
244
|
+
else
|
245
|
+
{}
|
246
|
+
end
|
186
247
|
end
|
187
248
|
|
188
249
|
#---------------------------------------------------------------------#
|