plasmo_xcodeproj 1.21.1
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 +7 -0
- data/LICENSE +19 -0
- data/README.md +95 -0
- data/bin/xcodeproj +10 -0
- data/lib/xcodeproj/command/config_dump.rb +91 -0
- data/lib/xcodeproj/command/project_diff.rb +56 -0
- data/lib/xcodeproj/command/show.rb +60 -0
- data/lib/xcodeproj/command/sort.rb +44 -0
- data/lib/xcodeproj/command/target_diff.rb +43 -0
- data/lib/xcodeproj/command.rb +63 -0
- data/lib/xcodeproj/config/other_linker_flags_parser.rb +73 -0
- data/lib/xcodeproj/config.rb +386 -0
- data/lib/xcodeproj/constants.rb +465 -0
- data/lib/xcodeproj/differ.rb +239 -0
- data/lib/xcodeproj/gem_version.rb +5 -0
- data/lib/xcodeproj/helper.rb +30 -0
- data/lib/xcodeproj/plist.rb +94 -0
- data/lib/xcodeproj/project/case_converter.rb +90 -0
- data/lib/xcodeproj/project/object/build_configuration.rb +255 -0
- data/lib/xcodeproj/project/object/build_file.rb +84 -0
- data/lib/xcodeproj/project/object/build_phase.rb +369 -0
- data/lib/xcodeproj/project/object/build_rule.rb +109 -0
- data/lib/xcodeproj/project/object/configuration_list.rb +117 -0
- data/lib/xcodeproj/project/object/container_item_proxy.rb +116 -0
- data/lib/xcodeproj/project/object/file_reference.rb +338 -0
- data/lib/xcodeproj/project/object/group.rb +506 -0
- data/lib/xcodeproj/project/object/helpers/build_settings_array_settings_by_object_version.rb +72 -0
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +245 -0
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +260 -0
- data/lib/xcodeproj/project/object/native_target.rb +751 -0
- data/lib/xcodeproj/project/object/reference_proxy.rb +86 -0
- data/lib/xcodeproj/project/object/root_object.rb +100 -0
- data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +29 -0
- data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +33 -0
- data/lib/xcodeproj/project/object/target_dependency.rb +94 -0
- data/lib/xcodeproj/project/object.rb +534 -0
- data/lib/xcodeproj/project/object_attributes.rb +522 -0
- data/lib/xcodeproj/project/object_dictionary.rb +210 -0
- data/lib/xcodeproj/project/object_list.rb +223 -0
- data/lib/xcodeproj/project/project_helper.rb +341 -0
- data/lib/xcodeproj/project/uuid_generator.rb +132 -0
- data/lib/xcodeproj/project.rb +874 -0
- data/lib/xcodeproj/scheme/abstract_scheme_action.rb +100 -0
- data/lib/xcodeproj/scheme/analyze_action.rb +19 -0
- data/lib/xcodeproj/scheme/archive_action.rb +59 -0
- data/lib/xcodeproj/scheme/build_action.rb +298 -0
- data/lib/xcodeproj/scheme/buildable_product_runnable.rb +55 -0
- data/lib/xcodeproj/scheme/buildable_reference.rb +129 -0
- data/lib/xcodeproj/scheme/command_line_arguments.rb +162 -0
- data/lib/xcodeproj/scheme/environment_variables.rb +170 -0
- data/lib/xcodeproj/scheme/execution_action.rb +86 -0
- data/lib/xcodeproj/scheme/launch_action.rb +179 -0
- data/lib/xcodeproj/scheme/location_scenario_reference.rb +49 -0
- data/lib/xcodeproj/scheme/macro_expansion.rb +34 -0
- data/lib/xcodeproj/scheme/profile_action.rb +57 -0
- data/lib/xcodeproj/scheme/remote_runnable.rb +92 -0
- data/lib/xcodeproj/scheme/send_email_action_content.rb +84 -0
- data/lib/xcodeproj/scheme/shell_script_action_content.rb +77 -0
- data/lib/xcodeproj/scheme/test_action.rb +394 -0
- data/lib/xcodeproj/scheme/xml_element_wrapper.rb +82 -0
- data/lib/xcodeproj/scheme.rb +375 -0
- data/lib/xcodeproj/user_interface.rb +22 -0
- data/lib/xcodeproj/workspace/file_reference.rb +79 -0
- data/lib/xcodeproj/workspace/group_reference.rb +67 -0
- data/lib/xcodeproj/workspace/reference.rb +40 -0
- data/lib/xcodeproj/workspace.rb +277 -0
- data/lib/xcodeproj/xcodebuild_helper.rb +108 -0
- data/lib/xcodeproj.rb +29 -0
- metadata +208 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
# Encapsulates the information a specific build configuration referenced
|
5
|
+
# by a {XCConfigurationList} which in turn might be referenced by a
|
6
|
+
# {PBXProject} or a {PBXNativeTarget}.
|
7
|
+
#
|
8
|
+
class XCBuildConfiguration < AbstractObject
|
9
|
+
MUTUAL_RECURSION_SENTINEL = 'xcodeproj.mutual_recursion_sentinel'.freeze
|
10
|
+
|
11
|
+
private_constant :MUTUAL_RECURSION_SENTINEL
|
12
|
+
|
13
|
+
# @!group Attributes
|
14
|
+
|
15
|
+
# @return [String] the name of the configuration.
|
16
|
+
#
|
17
|
+
attribute :name, String
|
18
|
+
|
19
|
+
# @return [Hash] the build settings to use for building the target.
|
20
|
+
#
|
21
|
+
attribute :build_settings, Hash, {}
|
22
|
+
|
23
|
+
# @return [PBXFileReference] an optional file reference to a
|
24
|
+
# configuration file (`.xcconfig`).
|
25
|
+
#
|
26
|
+
has_one :base_configuration_reference, PBXFileReference
|
27
|
+
|
28
|
+
public
|
29
|
+
|
30
|
+
# @!group AbstractObject Hooks
|
31
|
+
#---------------------------------------------------------------------#
|
32
|
+
|
33
|
+
# @return [Hash{String => Hash}] A hash suitable to display the object
|
34
|
+
# to the user.
|
35
|
+
#
|
36
|
+
def pretty_print
|
37
|
+
data = {}
|
38
|
+
data['Build Settings'] = sorted_build_settings
|
39
|
+
if base_configuration_reference
|
40
|
+
data['Base Configuration'] = base_configuration_reference.pretty_print
|
41
|
+
end
|
42
|
+
{ name => data }
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_hash_as(method = :to_hash)
|
46
|
+
super.tap do |hash|
|
47
|
+
normalize_array_settings(hash['buildSettings'])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sorts the build settings. Valid only in Ruby > 1.9.2 because in
|
52
|
+
# previous versions the hash are not sorted.
|
53
|
+
#
|
54
|
+
# @return [void]
|
55
|
+
#
|
56
|
+
def sort(_options = nil)
|
57
|
+
self.build_settings = sorted_build_settings
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Boolean] Whether this configuration is configured for
|
61
|
+
# debugging.
|
62
|
+
#
|
63
|
+
def debug?
|
64
|
+
gcc_preprocessor_definitions = resolve_build_setting('GCC_PREPROCESSOR_DEFINITIONS')
|
65
|
+
gcc_preprocessor_definitions && gcc_preprocessor_definitions.include?('DEBUG=1')
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Symbol] The symbolic type of this configuration, either
|
69
|
+
# `:debug` or `:release`.
|
70
|
+
#
|
71
|
+
def type
|
72
|
+
debug? ? :debug : :release
|
73
|
+
end
|
74
|
+
|
75
|
+
# @!group Helpers
|
76
|
+
#---------------------------------------------------------------------#
|
77
|
+
|
78
|
+
# Gets the value for the given build setting considering any configuration
|
79
|
+
# file present and resolving inheritance between them. It also takes in
|
80
|
+
# consideration environment variables.
|
81
|
+
#
|
82
|
+
# @param [String] key
|
83
|
+
# the key of the build setting.
|
84
|
+
#
|
85
|
+
# @param [PBXNativeTarget] root_target
|
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.
|
90
|
+
#
|
91
|
+
# @return [String] The value of the build setting
|
92
|
+
#
|
93
|
+
def resolve_build_setting(key, root_target = nil, previous_key = nil)
|
94
|
+
setting = build_settings[key]
|
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)
|
99
|
+
|
100
|
+
project_setting = project.build_configuration_list[name]
|
101
|
+
project_setting = nil if equal?(project_setting)
|
102
|
+
project_setting &&= project_setting.resolve_build_setting(key, root_target)
|
103
|
+
|
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|
|
116
|
+
expand_build_setting(value, inherited)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#---------------------------------------------------------------------#
|
121
|
+
|
122
|
+
private
|
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
|
+
|
130
|
+
CAPTURE_VARIABLE_IN_BUILD_CONFIG = /
|
131
|
+
\$ # matches dollar sign literally
|
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
|
+
)
|
141
|
+
/x
|
142
|
+
private_constant :CAPTURE_VARIABLE_IN_BUILD_CONFIG
|
143
|
+
|
144
|
+
def expand_build_setting(build_setting_value, config_value)
|
145
|
+
if build_setting_value.is_a?(Array) && config_value.is_a?(String)
|
146
|
+
config_value = split_build_setting_array_to_string(config_value)
|
147
|
+
elsif build_setting_value.is_a?(String) && config_value.is_a?(Array)
|
148
|
+
build_setting_value = split_build_setting_array_to_string(build_setting_value)
|
149
|
+
end
|
150
|
+
|
151
|
+
default = build_setting_value.is_a?(String) ? '' : []
|
152
|
+
inherited = config_value || default
|
153
|
+
|
154
|
+
return build_setting_value.gsub(Regexp.union(Constants::INHERITED_KEYWORDS), inherited) if build_setting_value.is_a? String
|
155
|
+
build_setting_value.flat_map { |value| Constants::INHERITED_KEYWORDS.include?(value) ? inherited : value }
|
156
|
+
end
|
157
|
+
|
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}"
|
169
|
+
end
|
170
|
+
|
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
|
201
|
+
end
|
202
|
+
|
203
|
+
def sorted_build_settings
|
204
|
+
sorted = {}
|
205
|
+
build_settings.keys.sort.each do |key|
|
206
|
+
sorted[key] = build_settings[key]
|
207
|
+
end
|
208
|
+
sorted
|
209
|
+
end
|
210
|
+
|
211
|
+
def normalize_array_settings(settings)
|
212
|
+
return unless settings
|
213
|
+
|
214
|
+
array_settings = BuildSettingsArraySettingsByObjectVersion[project.object_version]
|
215
|
+
|
216
|
+
settings.keys.each do |key|
|
217
|
+
next unless value = settings[key]
|
218
|
+
stripped_key = key.sub(/\[[^\]]+\]$/, '')
|
219
|
+
case value
|
220
|
+
when String
|
221
|
+
next unless array_settings.include?(stripped_key)
|
222
|
+
array_value = split_build_setting_array_to_string(value)
|
223
|
+
next unless array_value.size > 1
|
224
|
+
settings[key] = array_value
|
225
|
+
when Array
|
226
|
+
next if value.size > 1 && array_settings.include?(stripped_key)
|
227
|
+
settings[key] = value.join(' ')
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def split_build_setting_array_to_string(string)
|
233
|
+
regexp = / *((['"]?).*?[^\\]\2)(?=( |\z))/
|
234
|
+
string.scan(regexp).map(&:first)
|
235
|
+
end
|
236
|
+
|
237
|
+
def config
|
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
|
247
|
+
end
|
248
|
+
|
249
|
+
#---------------------------------------------------------------------#
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
require 'xcodeproj/project/object/helpers/build_settings_array_settings_by_object_version'
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
# Contains the information about the build settings of a file used by an
|
5
|
+
# {AbstractBuildPhase}.
|
6
|
+
#
|
7
|
+
class PBXBuildFile < AbstractObject
|
8
|
+
# @!group Attributes
|
9
|
+
|
10
|
+
# @return [Hash] the list of build settings for this file.
|
11
|
+
#
|
12
|
+
# @note The contents of this array depend on the phase of the build
|
13
|
+
# file.
|
14
|
+
#
|
15
|
+
# For PBXHeadersBuildPhase is `{ "ATTRIBUTES" => [:value] }`
|
16
|
+
# where `:value` can be `Public`, `Private`, or nil
|
17
|
+
# (Protected).
|
18
|
+
#
|
19
|
+
attribute :settings, Hash
|
20
|
+
|
21
|
+
# @return [PBXFileReference] the file to build.
|
22
|
+
#
|
23
|
+
# @todo I think that is possible to add any kind of group (for
|
24
|
+
# example folders linked to a path).
|
25
|
+
#
|
26
|
+
has_one :file_ref, [
|
27
|
+
PBXFileReference,
|
28
|
+
PBXGroup,
|
29
|
+
PBXVariantGroup,
|
30
|
+
XCVersionGroup,
|
31
|
+
PBXReferenceProxy,
|
32
|
+
]
|
33
|
+
|
34
|
+
# @return [XCSwiftPackageProductDependency] the Swift Package file to build.
|
35
|
+
#
|
36
|
+
has_one :product_ref, XCSwiftPackageProductDependency
|
37
|
+
|
38
|
+
# @return [String] the platform filter for this build file.
|
39
|
+
#
|
40
|
+
attribute :platform_filter, String
|
41
|
+
|
42
|
+
# @return [Array<String>] the platform filters for this build file.
|
43
|
+
#
|
44
|
+
attribute :platform_filters, Array
|
45
|
+
|
46
|
+
#---------------------------------------------------------------------#
|
47
|
+
|
48
|
+
public
|
49
|
+
|
50
|
+
# @!group AbstractObject Hooks
|
51
|
+
|
52
|
+
# @return [String] A name suitable for displaying the object to the
|
53
|
+
# user.
|
54
|
+
#
|
55
|
+
def display_name
|
56
|
+
if product_ref
|
57
|
+
product_ref.display_name
|
58
|
+
elsif file_ref
|
59
|
+
file_ref.display_name
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Hash{String => Hash}, String] A hash suitable to display the
|
66
|
+
# object to the user.
|
67
|
+
#
|
68
|
+
def pretty_print
|
69
|
+
if settings.nil? || settings.empty?
|
70
|
+
display_name
|
71
|
+
else
|
72
|
+
{ display_name => settings }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def ascii_plist_annotation
|
77
|
+
" #{display_name} in #{GroupableHelper.parent(self).display_name} "
|
78
|
+
end
|
79
|
+
|
80
|
+
#---------------------------------------------------------------------#
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,369 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class Project
|
3
|
+
module Object
|
4
|
+
# @abstract
|
5
|
+
#
|
6
|
+
# This class is abstract and it doesn't appear in the project document.
|
7
|
+
#
|
8
|
+
class AbstractBuildPhase < AbstractObject
|
9
|
+
# @!group Attributes
|
10
|
+
|
11
|
+
# @return [ObjectList<PBXBuildFile>] the files processed by this build
|
12
|
+
# configuration.
|
13
|
+
#
|
14
|
+
has_many :files, PBXBuildFile
|
15
|
+
|
16
|
+
# @return [String] some kind of magic number which usually is
|
17
|
+
# '2147483647' (can be also `8` and `12` in
|
18
|
+
# PBXCopyFilesBuildPhase, one of the masks is
|
19
|
+
# run_only_for_deployment_postprocessing).
|
20
|
+
#
|
21
|
+
attribute :build_action_mask, String, '2147483647'
|
22
|
+
|
23
|
+
# @return [String] whether or not this should only be processed before
|
24
|
+
# deployment. Can be either '0', or '1'.
|
25
|
+
#
|
26
|
+
# @note This option is exposed in Xcode in the UI of
|
27
|
+
# PBXCopyFilesBuildPhase as `Copy only when installing` or in
|
28
|
+
# PBXShellScriptBuildPhase as `Run script only when
|
29
|
+
# installing`.
|
30
|
+
#
|
31
|
+
attribute :run_only_for_deployment_postprocessing, String, '0'
|
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
|
+
|
43
|
+
# @return [String] Comments associated with this build phase.
|
44
|
+
#
|
45
|
+
# @note This is apparently no longer used by Xcode.
|
46
|
+
#
|
47
|
+
attribute :comments, String
|
48
|
+
|
49
|
+
#--------------------------------------#
|
50
|
+
|
51
|
+
public
|
52
|
+
|
53
|
+
# @!group Helpers
|
54
|
+
|
55
|
+
# @return [Array<PBXFileReference>] the list of all the files
|
56
|
+
# referenced by this build phase.
|
57
|
+
#
|
58
|
+
def files_references
|
59
|
+
files.map(&:file_ref)
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Array<String>] The display name of the build files.
|
63
|
+
#
|
64
|
+
def file_display_names
|
65
|
+
files.map(&:display_name)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [PBXBuildFile] the first build file associated with the given
|
69
|
+
# file reference if one exists.
|
70
|
+
#
|
71
|
+
def build_file(file_ref)
|
72
|
+
(file_ref.referrers & files).first
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns whether a build file for the given file reference exists.
|
76
|
+
#
|
77
|
+
# @param [PBXFileReference] file_ref
|
78
|
+
#
|
79
|
+
# @return [Bool] whether the reference is already present.
|
80
|
+
#
|
81
|
+
def include?(file_ref)
|
82
|
+
!build_file(file_ref).nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
# Adds a new build file, initialized with the given file reference, to
|
86
|
+
# the phase.
|
87
|
+
#
|
88
|
+
# @param [PBXFileReference] file_ref
|
89
|
+
# The file reference that should be added to the build phase.
|
90
|
+
#
|
91
|
+
# @return [PBXBuildFile] the build file generated.
|
92
|
+
#
|
93
|
+
def add_file_reference(file_ref, avoid_duplicates = false)
|
94
|
+
if avoid_duplicates && existing = build_file(file_ref)
|
95
|
+
existing
|
96
|
+
else
|
97
|
+
build_file = project.new(PBXBuildFile)
|
98
|
+
build_file.file_ref = file_ref
|
99
|
+
files << build_file
|
100
|
+
build_file
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Removes the build file associated with the given file reference from
|
105
|
+
# the phase.
|
106
|
+
#
|
107
|
+
# @param [PBXFileReference] file_ref
|
108
|
+
# The file to remove
|
109
|
+
#
|
110
|
+
# @return [void]
|
111
|
+
#
|
112
|
+
def remove_file_reference(file_ref)
|
113
|
+
build_file = files.find { |bf| bf.file_ref == file_ref }
|
114
|
+
remove_build_file(build_file) if build_file
|
115
|
+
end
|
116
|
+
|
117
|
+
# Removes a build file from the phase and clears its relationship to
|
118
|
+
# the file reference.
|
119
|
+
#
|
120
|
+
# @param [PBXBuildFile] build_file the file to remove
|
121
|
+
#
|
122
|
+
# @return [void]
|
123
|
+
#
|
124
|
+
def remove_build_file(build_file)
|
125
|
+
build_file.file_ref = nil
|
126
|
+
build_file.remove_from_project
|
127
|
+
end
|
128
|
+
|
129
|
+
# Removes all the build files from the phase and clears their
|
130
|
+
# relationship to the file reference.
|
131
|
+
#
|
132
|
+
# @return [void]
|
133
|
+
#
|
134
|
+
def clear
|
135
|
+
files.objects.each do |bf|
|
136
|
+
remove_build_file(bf)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
alias_method :clear_build_files, :clear
|
140
|
+
|
141
|
+
def display_name
|
142
|
+
super.gsub(/BuildPhase$/, '')
|
143
|
+
end
|
144
|
+
|
145
|
+
def ascii_plist_annotation
|
146
|
+
" #{display_name} "
|
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
|
169
|
+
end
|
170
|
+
|
171
|
+
#-----------------------------------------------------------------------#
|
172
|
+
|
173
|
+
# The phase responsible of copying headers. Known as `Copy Headers` in
|
174
|
+
# the UI.
|
175
|
+
#
|
176
|
+
# @note This phase can appear only once in a target.
|
177
|
+
#
|
178
|
+
class PBXHeadersBuildPhase < AbstractBuildPhase
|
179
|
+
end
|
180
|
+
|
181
|
+
#-----------------------------------------------------------------------#
|
182
|
+
|
183
|
+
# The phase responsible of compiling the files. Known as `Compile
|
184
|
+
# Sources` in the UI.
|
185
|
+
#
|
186
|
+
# @note This phase can appear only once in a target.
|
187
|
+
#
|
188
|
+
class PBXSourcesBuildPhase < AbstractBuildPhase
|
189
|
+
end
|
190
|
+
|
191
|
+
#-----------------------------------------------------------------------#
|
192
|
+
|
193
|
+
# The phase responsible on linking with frameworks. Known as `Link Binary
|
194
|
+
# With Libraries` in the UI.
|
195
|
+
#
|
196
|
+
# @note This phase can appear only once in a target.
|
197
|
+
#
|
198
|
+
class PBXFrameworksBuildPhase < AbstractBuildPhase
|
199
|
+
end
|
200
|
+
|
201
|
+
#-----------------------------------------------------------------------#
|
202
|
+
|
203
|
+
# The resources build phase apparently is a specialized copy build phase
|
204
|
+
# for resources. Known as `Copy Bundle Resources` in the UI. It is
|
205
|
+
# unclear if this is the only one capable of optimizing PNG.
|
206
|
+
#
|
207
|
+
# @note This phase can appear only once in a target.
|
208
|
+
#
|
209
|
+
class PBXResourcesBuildPhase < AbstractBuildPhase
|
210
|
+
end
|
211
|
+
|
212
|
+
#-----------------------------------------------------------------------#
|
213
|
+
|
214
|
+
# Phase that copies the files to the bundle of the target (aka `Copy
|
215
|
+
# Files`).
|
216
|
+
#
|
217
|
+
# @note This phase can appear multiple times in a target.
|
218
|
+
#
|
219
|
+
class PBXCopyFilesBuildPhase < AbstractBuildPhase
|
220
|
+
# @!group Attributes
|
221
|
+
|
222
|
+
# @return [String] the name of the build phase.
|
223
|
+
#
|
224
|
+
attribute :name, String
|
225
|
+
|
226
|
+
# @return [String] the subpath of `dst_subfolder_spec` where this file
|
227
|
+
# should be copied to.
|
228
|
+
#
|
229
|
+
# @note Can accept environment variables like `$(PRODUCT_NAME)`.
|
230
|
+
#
|
231
|
+
attribute :dst_path, String, ''
|
232
|
+
|
233
|
+
# @return [String] the path (destination) where the files should be
|
234
|
+
# copied to.
|
235
|
+
#
|
236
|
+
attribute :dst_subfolder_spec, String, Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[:resources]
|
237
|
+
|
238
|
+
# @return [Hash{String => Hash}] A hash suitable to display the build
|
239
|
+
# phase to the user.
|
240
|
+
#
|
241
|
+
def pretty_print
|
242
|
+
{
|
243
|
+
display_name => {
|
244
|
+
'Destination Path' => dst_path,
|
245
|
+
'Destination Subfolder' => Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS.key(dst_subfolder_spec).to_s,
|
246
|
+
'Files' => files.map(&:pretty_print),
|
247
|
+
},
|
248
|
+
}
|
249
|
+
end
|
250
|
+
|
251
|
+
# Alias method for #dst_subfolder_spec=, which accepts symbol values
|
252
|
+
# instead of numeric string values.
|
253
|
+
#
|
254
|
+
# @param [Symbol] value
|
255
|
+
# one of `COPY_FILES_BUILD_PHASE_DESTINATIONS.keys`
|
256
|
+
#
|
257
|
+
# @raise [StandardError] if value is not a valid known key
|
258
|
+
#
|
259
|
+
def symbol_dst_subfolder_spec=(value)
|
260
|
+
numeric_value = Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS[value]
|
261
|
+
raise "[Xcodeproj] Value checking error: got `#{value.inspect}` for" \
|
262
|
+
' attribute: dst_subfolder_spec' if numeric_value.nil?
|
263
|
+
self.dst_subfolder_spec = numeric_value
|
264
|
+
end
|
265
|
+
|
266
|
+
# Alias method for #dst_subfolder_spec, which returns symbol values
|
267
|
+
# instead of numeric string values.
|
268
|
+
#
|
269
|
+
# @return [Symbol]
|
270
|
+
#
|
271
|
+
def symbol_dst_subfolder_spec
|
272
|
+
key = Constants::COPY_FILES_BUILD_PHASE_DESTINATIONS.find { |_, num| num == dst_subfolder_spec }
|
273
|
+
key ? key.first : nil
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
#-----------------------------------------------------------------------#
|
278
|
+
|
279
|
+
# A phase responsible of running a shell script (aka `Run Script`).
|
280
|
+
#
|
281
|
+
# @note This phase can appear multiple times in a target.
|
282
|
+
#
|
283
|
+
class PBXShellScriptBuildPhase < AbstractBuildPhase
|
284
|
+
# @!group Attributes
|
285
|
+
|
286
|
+
# @return [String] the name of the build phase.
|
287
|
+
#
|
288
|
+
attribute :name, String
|
289
|
+
|
290
|
+
# @return [Array<String>] an array of the paths to pass to the script.
|
291
|
+
#
|
292
|
+
# @example
|
293
|
+
# "$(SRCROOT)/myfile"
|
294
|
+
#
|
295
|
+
attribute :input_paths, Array, []
|
296
|
+
|
297
|
+
# @return [Array<String>] an array of input file list paths of the script.
|
298
|
+
#
|
299
|
+
# @example
|
300
|
+
# "$(SRCROOT)/newInputFile.xcfilelist"
|
301
|
+
#
|
302
|
+
attribute :input_file_list_paths, Array, []
|
303
|
+
|
304
|
+
# @return [Array<String>] an array of output paths of the script.
|
305
|
+
#
|
306
|
+
# @example
|
307
|
+
# "$(DERIVED_FILE_DIR)/myfile"
|
308
|
+
#
|
309
|
+
attribute :output_paths, Array, []
|
310
|
+
|
311
|
+
# @return [Array<String>] an array of output file list paths of the script.
|
312
|
+
#
|
313
|
+
# @example
|
314
|
+
# "$(SRCROOT)/newOutputFile.xcfilelist"
|
315
|
+
#
|
316
|
+
attribute :output_file_list_paths, Array, []
|
317
|
+
|
318
|
+
# @return [String] the path to the script interpreter.
|
319
|
+
#
|
320
|
+
# @note Defaults to `/bin/sh`.
|
321
|
+
#
|
322
|
+
attribute :shell_path, String, '/bin/sh'
|
323
|
+
|
324
|
+
# @return [String] the actual script to perform.
|
325
|
+
#
|
326
|
+
# @note Defaults to a comment string.
|
327
|
+
#
|
328
|
+
attribute :shell_script, String, "# Type a script or drag a script file from your workspace to insert its path.\n"
|
329
|
+
|
330
|
+
# @return [String] whether or not the ENV variables should be shown in
|
331
|
+
# the build log.
|
332
|
+
#
|
333
|
+
attribute :show_env_vars_in_log, String
|
334
|
+
|
335
|
+
# @return [String] the discovered dependency file to use.
|
336
|
+
#
|
337
|
+
attribute :dependency_file, String
|
338
|
+
|
339
|
+
# @return [Hash{String => Hash}] A hash suitable to display the build
|
340
|
+
# phase to the user.
|
341
|
+
#
|
342
|
+
def pretty_print
|
343
|
+
{
|
344
|
+
display_name => {
|
345
|
+
'Input File List Paths' => input_file_list_paths || [],
|
346
|
+
'Input Paths' => input_paths || [],
|
347
|
+
'Output File List Paths' => output_file_list_paths || [],
|
348
|
+
'Output Paths' => output_paths || [],
|
349
|
+
'Shell Path' => shell_path,
|
350
|
+
'Shell Script' => shell_script,
|
351
|
+
},
|
352
|
+
}
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
#-----------------------------------------------------------------------#
|
357
|
+
|
358
|
+
# Apparently a build phase named `Build Carbon Resources` (Observed for
|
359
|
+
# kernel extensions targets).
|
360
|
+
#
|
361
|
+
# @note This phase can appear multiple times in a target.
|
362
|
+
#
|
363
|
+
class PBXRezBuildPhase < AbstractBuildPhase
|
364
|
+
end
|
365
|
+
|
366
|
+
#-----------------------------------------------------------------------#
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|