Module: Xcodeproj::Project::ProjectHelper

Includes:
Object
Defined in:
lib/xcodeproj/project/project_helper.rb

Targets collapse

Private Helpers collapse

Class Method Details

.build_phases_for_target_type(type) ⇒ Array<String>

Returns the build phases, in order, that appear by default on a target of the given type.

Parameters:

  • type (Symbol)

    the name of the target type.

Returns:

  • (Array<String>)

    The list of build phase class names for the target type.


325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/xcodeproj/project/project_helper.rb', line 325

def self.build_phases_for_target_type(type)
  case type
  when :static_library, :dynamic_library
    %w(Headers Sources Frameworks)
  when :framework
    %w(Headers Sources Frameworks Resources)
  when :command_line_tool
    %w(Sources Frameworks)
  else
    %w(Sources Frameworks Resources)
  end.map { |phase| "PBX#{phase}BuildPhase" }
end

.common_build_settings(type, platform = nil, deployment_target = nil, target_product_type = nil, language = :objc) ⇒ Hash

Returns the common build settings for a given platform and configuration name.

Parameters:

  • type (Symbol)

    the type of the build configuration, can be `:release` or `:debug`.

  • platform (Symbol) (defaults to: nil)

    the platform for the build settings, can be `:ios` or `:osx`.

  • deployment_target (String) (defaults to: nil)

    the deployment target for the platform.

  • target_product_type (Symbol) (defaults to: nil)

    the product type of the target, can be any of `Constants::PRODUCT_TYPE_UTI.values` or `Constants::PRODUCT_TYPE_UTI.keys`. Default is :application.

  • language (Symbol) (defaults to: :objc)

    the primary language of the target, can be `:objc` or `:swift`.

Returns:

  • (Hash)

    The common build settings


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/xcodeproj/project/project_helper.rb', line 263

def self.common_build_settings(type, platform = nil, deployment_target = nil, target_product_type = nil, language = :objc)
  target_product_type = (Constants::PRODUCT_TYPE_UTI.find { |_, v| v == target_product_type } || [target_product_type || :application])[0]
  common_settings = Constants::COMMON_BUILD_SETTINGS

  # Use intersecting settings for all key sets as base
  settings = deep_dup(common_settings[:all])

  # Match further common settings by key sets
  keys = [type, platform, target_product_type, language].compact
  key_combinations = (1..keys.length).flat_map { |n| keys.combination(n).to_a }
  key_combinations.each do |key_combination|
    settings.merge!(deep_dup(common_settings[key_combination] || {}))
  end

  if deployment_target
    case platform
    when :ios
      settings['IPHONEOS_DEPLOYMENT_TARGET'] = deployment_target
      settings['CLANG_ENABLE_OBJC_WEAK'] = 'NO' if deployment_target < '5'
    when :osx
      settings['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
      settings['CLANG_ENABLE_OBJC_WEAK'] = 'NO' if deployment_target < '10.7'
    when :tvos
      settings['TVOS_DEPLOYMENT_TARGET'] = deployment_target
    when :watchos
      settings['WATCHOS_DEPLOYMENT_TARGET'] = deployment_target
    end
  end

  settings
end

.configuration_list(project, platform = nil, deployment_target = nil, target_product_type = nil, language = nil) ⇒ XCConfigurationList

Returns a new configuration list, populated with release and debug configurations with common build settings for the given platform.

Parameters:

  • project (Project)

    the project to which the configuration list should be added.

  • platform (Symbol) (defaults to: nil)

    the platform for the configuration list, can be `:ios` or `:osx`.

  • deployment_target (String) (defaults to: nil)

    the deployment target for the platform.

  • target_product_type (Symbol) (defaults to: nil)

    the product type of the target, can be any of `Constants::PRODUCT_TYPE_UTI.values` or `Constants::PRODUCT_TYPE_UTI.keys`.

  • language (Symbol) (defaults to: nil)

    the primary language of the target, can be `:objc` or `:swift`.

Returns:


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/xcodeproj/project/project_helper.rb', line 211

def self.configuration_list(project, platform = nil, deployment_target = nil, target_product_type = nil, language = nil)
  cl = project.new(XCConfigurationList)
  cl.default_configuration_is_visible = '0'
  cl.default_configuration_name = 'Release'

  release_conf = project.new(XCBuildConfiguration)
  release_conf.name = 'Release'
  release_conf.build_settings = common_build_settings(:release, platform, deployment_target, target_product_type, language)

  debug_conf = project.new(XCBuildConfiguration)
  debug_conf.name = 'Debug'
  debug_conf.build_settings = common_build_settings(:debug, platform, deployment_target, target_product_type, language)

  cl.build_configurations << release_conf
  cl.build_configurations << debug_conf

  existing_configurations = cl.build_configurations.map(&:name)
  project.build_configurations.each do |configuration|
    next if existing_configurations.include?(configuration.name)

    new_config = project.new(XCBuildConfiguration)
    new_config.name = configuration.name
    new_config.build_settings = common_build_settings(configuration.type, platform, deployment_target, target_product_type, language)
    cl.build_configurations << new_config
  end

  cl
end

.deep_dup(object) ⇒ Object

Creates a deep copy of the given object

Parameters:

  • object (Object)

    the object to copy.

Returns:

  • (Object)

    The deep copy of the object.


302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/xcodeproj/project/project_helper.rb', line 302

def self.deep_dup(object)
  case object
  when Hash
    new_hash = {}
    object.each do |key, value|
      new_hash[key] = deep_dup(value)
    end
    new_hash
  when Array
    object.map { |value| deep_dup(value) }
  else
    object.dup
  end
end

.new_aggregate_target(project, name, platform, deployment_target) ⇒ PBXAggregateTarget

Creates a new aggregate target and adds it to the project.

The target is configured for the given platform.

Parameters:

  • project (Project)

    the project to which the target should be added.

  • name (String)

    the name of the aggregate target.

  • platform (Symbol)

    the platform of the aggregate target. Can be `:ios` or `:osx`.

  • deployment_target (String)

    the deployment target for the platform.

Returns:


141
142
143
144
145
146
147
# File 'lib/xcodeproj/project/project_helper.rb', line 141

def self.new_aggregate_target(project, name, platform, deployment_target)
  target = project.new(PBXAggregateTarget)
  project.targets << target
  target.name = name
  target.build_configuration_list = configuration_list(project, platform, deployment_target)
  target
end

.new_legacy_target(project, name, build_tool_path = '/usr/bin/make', build_arguments_string = '$(ACTION)', build_working_directory = nil, pass_build_settings_in_environment = '1') ⇒ PBXLegacyTarget

Creates a new legacy target and adds it to the project.

The target is configured for the given platform.

Parameters:

  • project (Project)

    the project to which the target should be added.

  • name (String)

    the name of the aggregate target.

  • build_tool_path (String) (defaults to: '/usr/bin/make')

    the build tool path to use for this target.

  • build_arguments_string (String) (defaults to: '$(ACTION)')

    the build arguments string to use for this target.

  • build_working_directory (String) (defaults to: nil)

    the build working directory to use for this target.

  • pass_build_settings_in_environment (String) (defaults to: '1')

    whether to pass build settings in the environment during execution of this target.

Returns:


173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/xcodeproj/project/project_helper.rb', line 173

def self.new_legacy_target(project, name, build_tool_path = '/usr/bin/make', build_arguments_string = '$(ACTION)',
                           build_working_directory = nil, pass_build_settings_in_environment = '1')
  target = project.new(PBXLegacyTarget)
  project.targets << target
  target.name = name
  target.build_configuration_list = configuration_list(project)
  target.build_tool_path = build_tool_path
  target.build_arguments_string = build_arguments_string
  target.build_working_directory = build_working_directory
  target.pass_build_settings_in_environment = pass_build_settings_in_environment
  target
end

.new_resources_bundle(project, name, platform, product_group) ⇒ PBXNativeTarget

Creates a new resource bundles target and adds it to the project.

The target is configured for the given platform and its file reference it is added to the Xcodeproj::Project#products_group.

The target is pre-populated with common build settings

Parameters:

  • project (Project)

    the project to which the target should be added.

  • name (String)

    the name of the resources bundle.

  • platform (Symbol)

    the platform of the resources bundle. Can be `:ios` or `:osx`.

  • product_group (PBXGroup)

    the product group, where to add to a file reference of the created target.

Returns:


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/xcodeproj/project/project_helper.rb', line 91

def self.new_resources_bundle(project, name, platform, product_group)
  # Target
  target = project.new(PBXNativeTarget)
  project.targets << target
  target.name = name
  target.product_name = name
  target.product_type = Constants::PRODUCT_TYPE_UTI[:bundle]

  # Configuration List
  cl = project.new(XCConfigurationList)
  cl.default_configuration_is_visible = '0'
  cl.default_configuration_name = 'Release'
  release_conf = project.new(XCBuildConfiguration)
  release_conf.name = 'Release'
  release_conf.build_settings = common_build_settings(nil, platform, nil, target.product_type)
  debug_conf = project.new(XCBuildConfiguration)
  debug_conf.name = 'Debug'
  debug_conf.build_settings = common_build_settings(nil, platform, nil, target.product_type)
  cl.build_configurations << release_conf
  cl.build_configurations << debug_conf
  target.build_configuration_list = cl

  # Product
  product = product_group.new_bundle(name)
  target.product_reference = product

  # Build phases
  build_phases_for_target_type(:bundle).each { |phase| target.build_phases << project.new(phase) }

  target
end

.new_target(project, type, name, platform, deployment_target, product_group, language) ⇒ PBXNativeTarget

Creates a new target and adds it to the project.

The target is configured for the given platform and its file reference it is added to the Xcodeproj::Project#products_group.

The target is pre-populated with common build settings, and the appropriate Framework according to the platform is added to to its Frameworks phase.

Parameters:

  • project (Project)

    the project to which the target should be added.

  • type (Symbol)

    the type of target. Can be `:application`, `:dynamic_library`, `framework` or `:static_library`.

  • name (String)

    the name of the target product.

  • platform (Symbol)

    the platform of the target. Can be `:ios` or `:osx`.

  • deployment_target (String)

    the deployment target for the platform.

  • product_group (PBXGroup)

    the product group, where to add to a file reference of the created target.

  • language (Symbol)

    the primary language of the target, can be `:objc` or `:swift`.

Returns:


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/xcodeproj/project/project_helper.rb', line 44

def self.new_target(project, type, name, platform, deployment_target, product_group, language)
  # Target
  target = project.new(PBXNativeTarget)
  project.targets << target
  target.name = name
  target.product_name = name
  target.product_type = Constants::PRODUCT_TYPE_UTI[type]
  target.build_configuration_list = configuration_list(project, platform, deployment_target, type, language)

  # Product
  product = product_group.new_product_ref_for_target(name, type)
  target.product_reference = product

  # Build phases
  build_phases_for_target_type(type).each { |phase| target.build_phases << project.new(phase) }

  # Frameworks
  unless type == :static_library
    framework_name = (platform == :osx) ? 'Cocoa' : 'Foundation'
    target.add_system_framework(framework_name)
  end

  target
end