xcodeproj 1.14.0 → 1.21.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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/xcodeproj/command/sort.rb +12 -1
  4. data/lib/xcodeproj/config/other_linker_flags_parser.rb +5 -0
  5. data/lib/xcodeproj/config.rb +12 -2
  6. data/lib/xcodeproj/constants.rb +63 -49
  7. data/lib/xcodeproj/gem_version.rb +1 -1
  8. data/lib/xcodeproj/project/object/build_configuration.rb +33 -8
  9. data/lib/xcodeproj/project/object/build_file.rb +7 -1
  10. data/lib/xcodeproj/project/object/build_phase.rb +31 -0
  11. data/lib/xcodeproj/project/object/group.rb +11 -9
  12. data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +8 -6
  13. data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +2 -2
  14. data/lib/xcodeproj/project/object/native_target.rb +43 -0
  15. data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +10 -0
  16. data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +14 -0
  17. data/lib/xcodeproj/project/object/target_dependency.rb +1 -0
  18. data/lib/xcodeproj/project/project_helper.rb +6 -6
  19. data/lib/xcodeproj/project.rb +9 -6
  20. data/lib/xcodeproj/scheme/abstract_scheme_action.rb +72 -0
  21. data/lib/xcodeproj/scheme/build_action.rb +108 -1
  22. data/lib/xcodeproj/scheme/execution_action.rb +86 -0
  23. data/lib/xcodeproj/scheme/launch_action.rb +33 -2
  24. data/lib/xcodeproj/scheme/location_scenario_reference.rb +49 -0
  25. data/lib/xcodeproj/scheme/profile_action.rb +5 -5
  26. data/lib/xcodeproj/scheme/send_email_action_content.rb +84 -0
  27. data/lib/xcodeproj/scheme/shell_script_action_content.rb +77 -0
  28. data/lib/xcodeproj/scheme/test_action.rb +26 -3
  29. data/lib/xcodeproj/scheme.rb +5 -1
  30. data/lib/xcodeproj/workspace/file_reference.rb +1 -1
  31. data/lib/xcodeproj/workspace.rb +3 -2
  32. metadata +26 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3af9cb46ce94c2bb3e0bff2b7b28e82f5a037788378fa512274f685d41c2910b
4
- data.tar.gz: 4047b7ac654f2aaeaba3363e56362249c2ce4456cea8e73eb27cd731648d4792
3
+ metadata.gz: 7bab98461310ae1a7572bae0b8dd9025cdf12ee53a64c7d457e8d4982d71982d
4
+ data.tar.gz: 59d1ddc2130ee7f88eb646a1c98dbf14e45da612448a12425df004d416f93961
5
5
  SHA512:
6
- metadata.gz: c47d7f26b3c3078f7cf2094aa81fd809cf938d9741530d09c166a37b3bc0a98e9e4e59e2b51222d1c43b64f9620ff35c0c83077ca6331b49bebed117fa6891f8
7
- data.tar.gz: 65a27789a94d192a1d7c25c851d3ab36fab276f70145432c5a1ca3ecd398ca6f571206aee498d59c05dc688542ca2facd4bac7de08845a936e8cb54452c3073e
6
+ metadata.gz: 4e2431ba9cbf960b7e1ef53ff3dae65565b51fbba1cbb0c6a096d29251ca49c751403575c46fdae6252e176b8ada16ac5aa659d6b015f142eb338e21718a7a38
7
+ data.tar.gz: dfe1895012ba35e32dd44b15b4b2cb5e8ab2957eb7919f39a514c7675b8a261a4f4688006ace24e6eae0dcfc07be70392cf047f0cb66bd8f1036bc3fe817f366
data/README.md CHANGED
@@ -10,7 +10,7 @@ support for Xcode workspaces (`.xcworkspace`), configuration files (`.xcconfig`)
10
10
  Xcode Scheme files (`.xcscheme`).
11
11
 
12
12
  It is used in [CocoaPods](https://github.com/CocoaPods/CocoaPods) to create a
13
- a collection of supplemental libraries or frameworks, for all platforms Xcode supports.
13
+ collection of supplemental libraries or frameworks, for all platforms Xcode supports.
14
14
 
15
15
  The API reference can be found [here](http://www.rubydoc.info/gems/xcodeproj).
16
16
 
@@ -9,22 +9,33 @@ module Xcodeproj
9
9
 
10
10
  self.summary = 'Sorts the given project.'
11
11
 
12
+ def self.options
13
+ [
14
+ ['--group-option=[above|below]', 'The position of the groups when sorting. If no option is specified, sorting will interleave groups and files.'],
15
+ ].concat(super)
16
+ end
17
+
12
18
  self.arguments = [
13
19
  CLAide::Argument.new('PROJECT', false),
14
20
  ]
15
21
 
16
22
  def initialize(argv)
17
23
  self.xcodeproj_path = argv.shift_argument
24
+ @group_option = argv.option('group-option')
25
+ @group_option &&= @group_option.to_sym
18
26
  super
19
27
  end
20
28
 
21
29
  def validate!
22
30
  super
31
+ unless [nil, :above, :below].include?(@group_option)
32
+ help! "Unknown format `#{@group_option}`"
33
+ end
23
34
  open_project!
24
35
  end
25
36
 
26
37
  def run
27
- xcodeproj.sort
38
+ xcodeproj.sort(:groups_position => @group_option)
28
39
  xcodeproj.save
29
40
  puts "The `#{File.basename(xcodeproj_path)}` project was sorted"
30
41
  end
@@ -16,6 +16,7 @@ module Xcodeproj
16
16
  :frameworks => [],
17
17
  :weak_frameworks => [],
18
18
  :libraries => [],
19
+ :arg_files => [],
19
20
  :simple => [],
20
21
  :force_load => [],
21
22
  }
@@ -32,6 +33,8 @@ module Xcodeproj
32
33
  key = :weak_frameworks
33
34
  when '-l'
34
35
  key = :libraries
36
+ when '@'
37
+ key = :arg_files
35
38
  when '-force_load'
36
39
  key = :force_load
37
40
  else
@@ -58,6 +61,8 @@ module Xcodeproj
58
61
  flags.strip.shellsplit.flat_map do |string|
59
62
  if string =~ /\A-l.+/
60
63
  ['-l', string[2..-1]]
64
+ elsif string =~ /\A@.+/
65
+ ['@', string[1..-1]]
61
66
  else
62
67
  string
63
68
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'shellwords'
2
3
  require 'xcodeproj/config/other_linker_flags_parser'
3
4
 
@@ -58,7 +59,7 @@ module Xcodeproj
58
59
  @attributes = {}
59
60
  @includes = []
60
61
  @other_linker_flags = {}
61
- [:simple, :frameworks, :weak_frameworks, :libraries, :force_load].each do |key|
62
+ [:simple, :frameworks, :weak_frameworks, :libraries, :arg_files, :force_load].each do |key|
62
63
  @other_linker_flags[key] = Set.new
63
64
  end
64
65
  merge!(extract_hash(xcconfig_hash_or_file))
@@ -125,9 +126,10 @@ module Xcodeproj
125
126
  :frameworks => '-framework ',
126
127
  :weak_frameworks => '-weak_framework ',
127
128
  :libraries => '-l',
129
+ :arg_files => '@',
128
130
  :force_load => '-force_load',
129
131
  }
130
- [:libraries, :frameworks, :weak_frameworks, :force_load].each do |key|
132
+ [:libraries, :frameworks, :weak_frameworks, :arg_files, :force_load].each do |key|
131
133
  modifier = modifiers[key]
132
134
  sorted = other_linker_flags[key].to_a.sort
133
135
  if key == :force_load
@@ -180,6 +182,13 @@ module Xcodeproj
180
182
  other_linker_flags[:libraries]
181
183
  end
182
184
 
185
+ # @return [Set<String>] The list of the arg files required by this
186
+ # settings file.
187
+ #
188
+ def arg_files
189
+ other_linker_flags[:arg_files]
190
+ end
191
+
183
192
  public
184
193
 
185
194
  # @!group Merging
@@ -254,6 +263,7 @@ module Xcodeproj
254
263
  # @return [Hash]
255
264
  #
256
265
  def extract_hash(argument)
266
+ return argument if argument.is_a?(Hash)
257
267
  if argument.respond_to? :read
258
268
  @filepath = Pathname.new(argument.to_path)
259
269
  hash_from_file_content(argument.read)
@@ -4,19 +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 = '12.2'
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.14'
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 = '12.2'
15
+ LAST_KNOWN_TVOS_SDK = '14.0'
16
16
 
17
17
  # @return [String] The last known watchOS SDK (stable).
18
18
  #
19
- LAST_KNOWN_WATCHOS_SDK = '5.2'
19
+ LAST_KNOWN_WATCHOS_SDK = '7.0'
20
20
 
21
21
  # @return [String] The last known archive version to Xcodeproj.
22
22
  #
@@ -32,15 +32,15 @@ module Xcodeproj
32
32
 
33
33
  # @return [String] The last known object version to Xcodeproj.
34
34
  #
35
- LAST_KNOWN_OBJECT_VERSION = 52
35
+ LAST_KNOWN_OBJECT_VERSION = 55
36
36
 
37
- # @return [String] The last known object version to Xcodeproj.
37
+ # @return [String] The last known Xcode version to Xcodeproj.
38
38
  #
39
- LAST_UPGRADE_CHECK = '1100'
39
+ LAST_UPGRADE_CHECK = '1240'
40
40
 
41
- # @return [String] The last known object version to Xcodeproj.
41
+ # @return [String] The last known Xcode version to Xcodeproj.
42
42
  #
43
- LAST_SWIFT_UPGRADE_CHECK = '1100'
43
+ LAST_SWIFT_UPGRADE_CHECK = '1240'
44
44
 
45
45
  # @return [String] The version of `.xcscheme` files supported by Xcodeproj
46
46
  #
@@ -93,12 +93,14 @@ module Xcodeproj
93
93
  'app' => 'wrapper.application',
94
94
  'appex' => 'wrapper.app-extension',
95
95
  'bundle' => 'wrapper.plug-in',
96
+ 'cpp' => 'sourcecode.cpp.cpp',
96
97
  'dylib' => 'compiled.mach-o.dylib',
97
98
  'entitlements' => 'text.plist.entitlements',
98
99
  'framework' => 'wrapper.framework',
99
100
  'gif' => 'image.gif',
100
101
  'gpx' => 'text.xml',
101
102
  'h' => 'sourcecode.c.h',
103
+ 'hpp' => 'sourcecode.cpp.h',
102
104
  'm' => 'sourcecode.c.objc',
103
105
  'markdown' => 'text',
104
106
  'mdimporter' => 'wrapper.cfbundle',
@@ -126,6 +128,9 @@ module Xcodeproj
126
128
  # @return [Hash] The compatibility version string for different object versions.
127
129
  #
128
130
  COMPATIBILITY_VERSION_BY_OBJECT_VERSION = {
131
+ 55 => 'Xcode 13.0',
132
+ 54 => 'Xcode 12.0',
133
+ 53 => 'Xcode 11.4',
129
134
  52 => 'Xcode 11.0',
130
135
  51 => 'Xcode 10.0',
131
136
  50 => 'Xcode 9.3',
@@ -138,46 +143,48 @@ module Xcodeproj
138
143
  # @return [Hash] The uniform type identifier of various product types.
139
144
  #
140
145
  PRODUCT_TYPE_UTI = {
141
- :application => 'com.apple.product-type.application',
142
- :framework => 'com.apple.product-type.framework',
143
- :dynamic_library => 'com.apple.product-type.library.dynamic',
144
- :static_library => 'com.apple.product-type.library.static',
145
- :bundle => 'com.apple.product-type.bundle',
146
- :octest_bundle => 'com.apple.product-type.bundle',
147
- :unit_test_bundle => 'com.apple.product-type.bundle.unit-test',
148
- :ui_test_bundle => 'com.apple.product-type.bundle.ui-testing',
149
- :app_extension => 'com.apple.product-type.app-extension',
150
- :command_line_tool => 'com.apple.product-type.tool',
151
- :watch_app => 'com.apple.product-type.application.watchapp',
152
- :watch2_app => 'com.apple.product-type.application.watchapp2',
153
- :watch2_app_container => 'com.apple.product-type.application.watchapp2-container',
154
- :watch_extension => 'com.apple.product-type.watchkit-extension',
155
- :watch2_extension => 'com.apple.product-type.watchkit2-extension',
156
- :tv_extension => 'com.apple.product-type.tv-app-extension',
157
- :messages_application => 'com.apple.product-type.application.messages',
158
- :messages_extension => 'com.apple.product-type.app-extension.messages',
159
- :sticker_pack => 'com.apple.product-type.app-extension.messages-sticker-pack',
160
- :xpc_service => 'com.apple.product-type.xpc-service',
146
+ :application => 'com.apple.product-type.application',
147
+ :application_on_demand_install_capable => 'com.apple.product-type.application.on-demand-install-capable',
148
+ :framework => 'com.apple.product-type.framework',
149
+ :dynamic_library => 'com.apple.product-type.library.dynamic',
150
+ :static_library => 'com.apple.product-type.library.static',
151
+ :bundle => 'com.apple.product-type.bundle',
152
+ :octest_bundle => 'com.apple.product-type.bundle',
153
+ :unit_test_bundle => 'com.apple.product-type.bundle.unit-test',
154
+ :ui_test_bundle => 'com.apple.product-type.bundle.ui-testing',
155
+ :app_extension => 'com.apple.product-type.app-extension',
156
+ :command_line_tool => 'com.apple.product-type.tool',
157
+ :watch_app => 'com.apple.product-type.application.watchapp',
158
+ :watch2_app => 'com.apple.product-type.application.watchapp2',
159
+ :watch2_app_container => 'com.apple.product-type.application.watchapp2-container',
160
+ :watch_extension => 'com.apple.product-type.watchkit-extension',
161
+ :watch2_extension => 'com.apple.product-type.watchkit2-extension',
162
+ :tv_extension => 'com.apple.product-type.tv-app-extension',
163
+ :messages_application => 'com.apple.product-type.application.messages',
164
+ :messages_extension => 'com.apple.product-type.app-extension.messages',
165
+ :sticker_pack => 'com.apple.product-type.app-extension.messages-sticker-pack',
166
+ :xpc_service => 'com.apple.product-type.xpc-service',
161
167
  }.freeze
162
168
 
163
169
  # @return [Hash] The extensions or the various product UTIs.
164
170
  #
165
171
  PRODUCT_UTI_EXTENSIONS = {
166
- :application => 'app',
167
- :framework => 'framework',
168
- :dynamic_library => 'dylib',
169
- :static_library => 'a',
170
- :bundle => 'bundle',
171
- :octest_bundle => 'octest',
172
- :unit_test_bundle => 'xctest',
173
- :ui_test_bundle => 'xctest',
174
- :app_extension => 'appex',
175
- :messages_application => 'app',
176
- :messages_extension => 'appex',
177
- :sticker_pack => 'appex',
178
- :watch2_extension => 'appex',
179
- :watch2_app => 'app',
180
- :watch2_app_container => 'app',
172
+ :application => 'app',
173
+ :application_on_demand_install_capable => 'app',
174
+ :framework => 'framework',
175
+ :dynamic_library => 'dylib',
176
+ :static_library => 'a',
177
+ :bundle => 'bundle',
178
+ :octest_bundle => 'octest',
179
+ :unit_test_bundle => 'xctest',
180
+ :ui_test_bundle => 'xctest',
181
+ :app_extension => 'appex',
182
+ :messages_application => 'app',
183
+ :messages_extension => 'appex',
184
+ :sticker_pack => 'appex',
185
+ :watch2_extension => 'appex',
186
+ :watch2_app => 'app',
187
+ :watch2_app_container => 'app',
181
188
  }.freeze
182
189
 
183
190
  # @return [Hash] The common build settings grouped by platform, and build
@@ -198,11 +205,9 @@ module Xcodeproj
198
205
  }.freeze,
199
206
  [:ios] => {
200
207
  'SDKROOT' => 'iphoneos',
201
- 'CODE_SIGN_IDENTITY' => 'iPhone Developer',
202
208
  }.freeze,
203
209
  [:osx] => {
204
210
  'SDKROOT' => 'macosx',
205
- 'CODE_SIGN_IDENTITY' => '-',
206
211
  }.freeze,
207
212
  [:tvos] => {
208
213
  'SDKROOT' => 'appletvos',
@@ -251,7 +256,6 @@ module Xcodeproj
251
256
  [:debug, :static_library, :swift] => {
252
257
  }.freeze,
253
258
  [:framework] => {
254
- 'CODE_SIGN_IDENTITY' => '',
255
259
  'CURRENT_PROJECT_VERSION' => '1',
256
260
  'DEFINES_MODULE' => 'YES',
257
261
  'DYLIB_COMPATIBILITY_VERSION' => '1',
@@ -269,7 +273,6 @@ module Xcodeproj
269
273
  }.freeze,
270
274
  [:osx, :framework] => {
271
275
  'COMBINE_HIDPI_IMAGES' => 'YES',
272
- 'FRAMEWORK_VERSION' => 'A',
273
276
  'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) @executable_path/../Frameworks @loader_path/Frameworks',
274
277
  }.freeze,
275
278
  [:watchos, :framework] => {
@@ -311,6 +314,7 @@ module Xcodeproj
311
314
  }.freeze,
312
315
  [:application] => {
313
316
  'ASSETCATALOG_COMPILER_APPICON_NAME' => 'AppIcon',
317
+ 'ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME' => 'AccentColor',
314
318
  }.freeze,
315
319
  [:ios, :application] => {
316
320
  'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) @executable_path/Frameworks',
@@ -326,10 +330,12 @@ module Xcodeproj
326
330
  }.freeze,
327
331
  [:tvos, :application] => {
328
332
  'ASSETCATALOG_COMPILER_APPICON_NAME' => 'App Icon & Top Shelf Image',
329
- 'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME' => 'LaunchImage',
330
333
  'LD_RUNPATH_SEARCH_PATHS' => '$(inherited) @executable_path/Frameworks',
331
334
  'TARGETED_DEVICE_FAMILY' => '3',
332
335
  }.freeze,
336
+ [:tvos, :application, :swift] => {
337
+ 'ENABLE_PREVIEWS' => 'YES',
338
+ }.freeze,
333
339
  [:watchos, :application, :swift] => {
334
340
  'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES' => 'YES',
335
341
  }.freeze,
@@ -375,6 +381,7 @@ module Xcodeproj
375
381
  'CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF' => 'YES',
376
382
  'CLANG_WARN_OBJC_LITERAL_CONVERSION' => 'YES',
377
383
  'CLANG_WARN_OBJC_ROOT_CLASS' => 'YES_ERROR',
384
+ 'CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER' => 'YES',
378
385
  'CLANG_WARN_RANGE_LOOP_ANALYSIS' => 'YES',
379
386
  'CLANG_WARN_STRICT_PROTOTYPES' => 'YES',
380
387
  'CLANG_WARN_SUSPICIOUS_MOVE' => 'YES',
@@ -447,5 +454,12 @@ module Xcodeproj
447
454
  $(inherited)
448
455
  ${inherited}
449
456
  ).freeze
457
+
458
+ # @return [Hash] Possible types for a scheme's 'ExecutionAction' node
459
+ #
460
+ EXECUTION_ACTION_TYPE = {
461
+ :shell_script => 'Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction',
462
+ :send_email => 'Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.SendEmailAction',
463
+ }.freeze
450
464
  end
451
465
  end
@@ -1,5 +1,5 @@
1
1
  module Xcodeproj
2
2
  # The version of the xcodeproj gem.
3
3
  #
4
- VERSION = '1.14.0'.freeze unless defined? Xcodeproj::VERSION
4
+ VERSION = '1.21.0'.freeze unless defined? Xcodeproj::VERSION
5
5
  end
@@ -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,16 +83,19 @@ 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)
95
+ setting = resolve_variable_substitution(key, setting, root_target, previous_key)
89
96
 
90
97
  config_setting = config[key]
91
- config_setting = resolve_variable_substitution(key, config_setting, root_target)
98
+ config_setting = resolve_variable_substitution(key, config_setting, root_target, previous_key)
92
99
 
93
100
  project_setting = project.build_configuration_list[name]
94
101
  project_setting = nil if equal?(project_setting)
@@ -99,6 +106,12 @@ module Xcodeproj
99
106
  'SRCROOT' => project.project_dir.to_s,
100
107
  }
101
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
+
102
115
  [defaults[key], project_setting, config_setting, setting, ENV[key]].compact.reduce(nil) do |inherited, value|
103
116
  expand_build_setting(value, inherited)
104
117
  end
@@ -142,7 +155,7 @@ module Xcodeproj
142
155
  build_setting_value.flat_map { |value| Constants::INHERITED_KEYWORDS.include?(value) ? inherited : value }
143
156
  end
144
157
 
145
- def resolve_variable_substitution(key, value, root_target)
158
+ def resolve_variable_substitution(key, value, root_target, previous_key = nil)
146
159
  case value
147
160
  when Array
148
161
  return value.map { |v| resolve_variable_substitution(key, v, root_target) }
@@ -168,9 +181,20 @@ module Xcodeproj
168
181
  when key
169
182
  # to prevent infinite recursion
170
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
171
188
  else
172
189
  configuration_to_resolve_against = root_target ? root_target.build_configuration_list[name] : self
173
- resolved_value_for_variable = configuration_to_resolve_against.resolve_build_setting(variable, root_target) || ''
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
+
174
198
  value = value.gsub(variable_reference, resolved_value_for_variable)
175
199
  resolve_variable_substitution(key, value, root_target)
176
200
  end
@@ -191,14 +215,15 @@ module Xcodeproj
191
215
 
192
216
  settings.keys.each do |key|
193
217
  next unless value = settings[key]
218
+ stripped_key = key.sub(/\[[^\]]+\]$/, '')
194
219
  case value
195
220
  when String
196
- next unless array_settings.include?(key)
221
+ next unless array_settings.include?(stripped_key)
197
222
  array_value = split_build_setting_array_to_string(value)
198
223
  next unless array_value.size > 1
199
224
  settings[key] = array_value
200
225
  when Array
201
- next if value.size > 1 && array_settings.include?(key)
226
+ next if value.size > 1 && array_settings.include?(stripped_key)
202
227
  settings[key] = value.join(' ')
203
228
  end
204
229
  end
@@ -39,6 +39,10 @@ module Xcodeproj
39
39
  #
40
40
  attribute :platform_filter, String
41
41
 
42
+ # @return [Array<String>] the platform filters for this build file.
43
+ #
44
+ attribute :platform_filters, Array
45
+
42
46
  #---------------------------------------------------------------------#
43
47
 
44
48
  public
@@ -49,7 +53,9 @@ module Xcodeproj
49
53
  # user.
50
54
  #
51
55
  def display_name
52
- if file_ref
56
+ if product_ref
57
+ product_ref.display_name
58
+ elsif file_ref
53
59
  file_ref.display_name
54
60
  else
55
61
  super
@@ -30,6 +30,16 @@ module Xcodeproj
30
30
  #
31
31
  attribute :run_only_for_deployment_postprocessing, String, '0'
32
32
 
33
+ # @return [String] whether or not this run script will be forced to
34
+ # run even on incremental builds. Can be either '1', or
35
+ # missing. By default this option is disabled in Xcode.
36
+ #
37
+ # @note This setting is exposed in Xcode in the UI of
38
+ # PBXShellScriptBuildPhase as `Based on
39
+ # dependency analysis` (selected by default).
40
+ #
41
+ attribute :always_out_of_date, String
42
+
33
43
  # @return [String] Comments associated with this build phase.
34
44
  #
35
45
  # @note This is apparently no longer used by Xcode.
@@ -135,6 +145,27 @@ module Xcodeproj
135
145
  def ascii_plist_annotation
136
146
  " #{display_name} "
137
147
  end
148
+
149
+ # Sorts the build files of the phase according to the display
150
+ # name or the path.
151
+ #
152
+ # @param [Hash] _options
153
+ # Not used.
154
+ #
155
+ # @return [void]
156
+ #
157
+ def sort(_options = nil)
158
+ files.sort! do |x, y|
159
+ result = File.basename(x.display_name.downcase, '.*') <=> File.basename(y.display_name.downcase, '.*')
160
+ if result.zero?
161
+ result = File.extname(x.display_name.downcase) <=> File.extname(y.display_name.downcase)
162
+ if result.zero? && x.file_ref.respond_to?(:full_path) && y.file_ref.respond_to?(:full_path)
163
+ result = x.file_ref.full_path.to_s.downcase <=> y.file_ref.full_path.to_s.downcase
164
+ end
165
+ end
166
+ result
167
+ end
168
+ end
138
169
  end
139
170
 
140
171
  #-----------------------------------------------------------------------#
@@ -226,24 +226,24 @@ module Xcodeproj
226
226
  # Creates a file reference to a static library and adds it to the
227
227
  # group.
228
228
  #
229
- # @param [#to_s] product_name
229
+ # @param [#to_s] product_basename
230
230
  # The name of the static library.
231
231
  #
232
232
  # @return [PBXFileReference] The new file reference.
233
233
  #
234
- def new_product_ref_for_target(target_name, product_type)
235
- FileReferencesFactory.new_product_ref_for_target(self, target_name, product_type)
234
+ def new_product_ref_for_target(product_basename, product_type)
235
+ FileReferencesFactory.new_product_ref_for_target(self, product_basename, product_type)
236
236
  end
237
237
 
238
238
  # Creates a file reference to a new bundle.
239
239
  #
240
- # @param [#to_s] product_name
240
+ # @param [#to_s] product_basename
241
241
  # The name of the bundle.
242
242
  #
243
243
  # @return [PBXFileReference] The new file reference.
244
244
  #
245
- def new_bundle(product_name)
246
- FileReferencesFactory.new_bundle(self, product_name)
245
+ def new_bundle(product_basename)
246
+ FileReferencesFactory.new_bundle(self, product_basename)
247
247
  end
248
248
 
249
249
  # Creates a file reference to a new bundle and adds it to the group.
@@ -440,10 +440,12 @@ module Xcodeproj
440
440
 
441
441
  result = File.basename(x.display_name.downcase, '.*') <=> File.basename(y.display_name.downcase, '.*')
442
442
  if result.zero?
443
- File.extname(x.display_name.downcase) <=> File.extname(y.display_name.downcase)
444
- else
445
- result
443
+ result = File.extname(x.display_name.downcase) <=> File.extname(y.display_name.downcase)
444
+ if result.zero?
445
+ result = x.path.downcase <=> y.path.downcase
446
+ end
446
447
  end
448
+ result
447
449
  end
448
450
  end
449
451
  end
@@ -42,17 +42,19 @@ module Xcodeproj
42
42
  # @param [PBXGroup] group
43
43
  # The group to which to add the reference.
44
44
  #
45
- # @param [#to_s] product_name
45
+ # @param [#to_s] product_basename
46
46
  # The name of the static library.
47
47
  #
48
48
  # @return [PBXFileReference] The new file reference.
49
49
  #
50
- def new_product_ref_for_target(group, target_name, product_type)
50
+ def new_product_ref_for_target(group, product_basename, product_type)
51
51
  if product_type == :static_library
52
52
  prefix = 'lib'
53
53
  end
54
54
  extension = Constants::PRODUCT_UTI_EXTENSIONS[product_type]
55
- ref = new_reference(group, "#{prefix}#{target_name}.#{extension}", :built_products)
55
+ path = "#{prefix}#{product_basename}"
56
+ path += ".#{extension}" if extension
57
+ ref = new_reference(group, path, :built_products)
56
58
  ref.include_in_index = '0'
57
59
  ref.set_explicit_file_type
58
60
  ref
@@ -64,13 +66,13 @@ module Xcodeproj
64
66
  # @param [PBXGroup] group
65
67
  # The group to which to add the reference.
66
68
  #
67
- # @param [#to_s] product_name
69
+ # @param [#to_s] product_basename
68
70
  # The name of the bundle.
69
71
  #
70
72
  # @return [PBXFileReference] The new file reference.
71
73
  #
72
- def new_bundle(group, product_name)
73
- ref = new_reference(group, "#{product_name}.bundle", :built_products)
74
+ def new_bundle(group, product_basename)
75
+ ref = new_reference(group, "#{product_basename}.bundle", :built_products)
74
76
  ref.include_in_index = '0'
75
77
  ref.set_explicit_file_type('wrapper.cfbundle')
76
78
  ref
@@ -148,7 +148,7 @@ module Xcodeproj
148
148
  when '<group>'
149
149
  object_parent = parent(object)
150
150
  if object_parent.isa == 'PBXProject'.freeze
151
- object.project.project_dir
151
+ object.project.project_dir + object.project.root_object.project_dir_path
152
152
  else
153
153
  real_path(object_parent)
154
154
  end
@@ -205,7 +205,7 @@ module Xcodeproj
205
205
  # @return [void]
206
206
  #
207
207
  def set_path_with_source_tree(object, path, source_tree)
208
- path = Pathname.new(path)
208
+ path = Pathname(path)
209
209
  source_tree = normalize_source_tree(source_tree)
210
210
  object.source_tree = source_tree
211
211