xcodeproj 0.1.0 → 0.2.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.
- data/README.md +3 -9
- data/ext/xcodeproj/extconf.rb +1 -0
- data/ext/xcodeproj/xcodeproj_ext.c +81 -13
- data/lib/xcodeproj/config.rb +142 -10
- data/lib/xcodeproj/inflector.rb +1 -1
- data/lib/xcodeproj/project/association/has_many.rb +51 -0
- data/lib/xcodeproj/project/association/has_one.rb +39 -0
- data/lib/xcodeproj/project/association/reflection.rb +88 -0
- data/lib/xcodeproj/project/association.rb +54 -0
- data/lib/xcodeproj/project/object/build_phase.rb +89 -0
- data/lib/xcodeproj/project/object/configuration.rb +100 -0
- data/lib/xcodeproj/project/object/file_reference.rb +71 -0
- data/lib/xcodeproj/project/object/group.rb +102 -0
- data/lib/xcodeproj/project/object/native_target.rb +158 -0
- data/lib/xcodeproj/project/object.rb +207 -0
- data/lib/xcodeproj/project/object_list.rb +146 -0
- data/lib/xcodeproj/project.rb +154 -566
- data/lib/xcodeproj.rb +1 -1
- metadata +17 -5
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Xcodeproj
|
|
2
|
+
class Project
|
|
3
|
+
module Object
|
|
4
|
+
|
|
5
|
+
class PBXBuildFile < AbstractPBXObject
|
|
6
|
+
# [Hash] the list of build settings for this file
|
|
7
|
+
attribute :settings
|
|
8
|
+
|
|
9
|
+
has_one :file, :uuid => :file_ref
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class PBXBuildPhase < AbstractPBXObject
|
|
13
|
+
has_many :build_files, :uuids => :files, :uuids_as => :build_file_references
|
|
14
|
+
|
|
15
|
+
# [String] some kind of magic number which seems to always be '2147483647'
|
|
16
|
+
attribute :build_action_mask
|
|
17
|
+
|
|
18
|
+
# [String] wether or not this should only be processed before deployment
|
|
19
|
+
# (I guess). This cane be either '0', or '1'
|
|
20
|
+
attribute :run_only_for_deployment_postprocessing
|
|
21
|
+
|
|
22
|
+
def initialize(*)
|
|
23
|
+
super
|
|
24
|
+
self.build_file_references ||= []
|
|
25
|
+
# These are always the same, no idea what they are.
|
|
26
|
+
self.build_action_mask ||= "2147483647"
|
|
27
|
+
self.run_only_for_deployment_postprocessing ||= "0"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def files
|
|
31
|
+
PBXObjectList.new(PBXFileReference, @project) do |list|
|
|
32
|
+
list.let(:uuid_scope) { self.build_files.map(&:file_ref) }
|
|
33
|
+
list.let(:push) do |file|
|
|
34
|
+
self.build_files << file.build_files.new
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def <<(file)
|
|
40
|
+
files << file
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class PBXCopyFilesBuildPhase < PBXBuildPhase
|
|
45
|
+
# [String] the path where this file should be copied to
|
|
46
|
+
attribute :dst_path
|
|
47
|
+
|
|
48
|
+
# [String] a magic number which always seems to be "16"
|
|
49
|
+
attribute :dst_subfolder_spec
|
|
50
|
+
|
|
51
|
+
def initialize(*)
|
|
52
|
+
super
|
|
53
|
+
self.dst_path ||= '$(PRODUCT_NAME)'
|
|
54
|
+
self.dst_subfolder_spec ||= "16"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class PBXSourcesBuildPhase < PBXBuildPhase; end
|
|
59
|
+
class PBXFrameworksBuildPhase < PBXBuildPhase; end
|
|
60
|
+
|
|
61
|
+
# @todo Should `files`, `input_paths`, and `output_paths` be has_many
|
|
62
|
+
# associations with file references?
|
|
63
|
+
class PBXShellScriptBuildPhase < PBXBuildPhase
|
|
64
|
+
attribute :name
|
|
65
|
+
|
|
66
|
+
attribute :files
|
|
67
|
+
attribute :input_paths
|
|
68
|
+
attribute :output_paths
|
|
69
|
+
|
|
70
|
+
# [String] The path to the script interpreter. Defaults to `/bin/sh`.
|
|
71
|
+
attribute :shell_path
|
|
72
|
+
|
|
73
|
+
# [String] The actual script to perform.
|
|
74
|
+
attribute :shell_script
|
|
75
|
+
|
|
76
|
+
def initialize(*)
|
|
77
|
+
super
|
|
78
|
+
self.files ||= []
|
|
79
|
+
self.input_paths ||= []
|
|
80
|
+
self.output_paths ||= []
|
|
81
|
+
|
|
82
|
+
self.shell_path ||= '/bin/sh'
|
|
83
|
+
self.shell_script ||= ''
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
module Xcodeproj
|
|
2
|
+
class Project
|
|
3
|
+
module Object
|
|
4
|
+
|
|
5
|
+
class XCBuildConfiguration < AbstractPBXObject
|
|
6
|
+
COMMON_BUILD_SETTINGS = {
|
|
7
|
+
:all => {
|
|
8
|
+
'GCC_VERSION' => 'com.apple.compilers.llvm.clang.1_0',
|
|
9
|
+
'GCC_PRECOMPILE_PREFIX_HEADER' => 'YES',
|
|
10
|
+
'PRODUCT_NAME' => '$(TARGET_NAME)',
|
|
11
|
+
'SKIP_INSTALL' => 'YES',
|
|
12
|
+
'DSTROOT' => '/tmp/xcodeproj.dst',
|
|
13
|
+
'ALWAYS_SEARCH_USER_PATHS' => 'NO',
|
|
14
|
+
'GCC_C_LANGUAGE_STANDARD' => 'gnu99',
|
|
15
|
+
'INSTALL_PATH' => "$(BUILT_PRODUCTS_DIR)",
|
|
16
|
+
'GCC_WARN_ABOUT_MISSING_PROTOTYPES' => 'YES',
|
|
17
|
+
'GCC_WARN_ABOUT_RETURN_TYPE' => 'YES',
|
|
18
|
+
'GCC_WARN_UNUSED_VARIABLE' => 'YES',
|
|
19
|
+
'OTHER_LDFLAGS' => '',
|
|
20
|
+
'COPY_PHASE_STRIP' => 'YES',
|
|
21
|
+
}.freeze,
|
|
22
|
+
:debug => {
|
|
23
|
+
'GCC_DYNAMIC_NO_PIC' => 'NO',
|
|
24
|
+
'GCC_PREPROCESSOR_DEFINITIONS' => ["DEBUG=1", "$(inherited)"],
|
|
25
|
+
'GCC_SYMBOLS_PRIVATE_EXTERN' => 'NO',
|
|
26
|
+
'GCC_OPTIMIZATION_LEVEL' => '0',
|
|
27
|
+
'COPY_PHASE_STRIP' => 'NO',
|
|
28
|
+
}.freeze,
|
|
29
|
+
:ios => {
|
|
30
|
+
'ARCHS' => "$(ARCHS_STANDARD_32_BIT)",
|
|
31
|
+
'IPHONEOS_DEPLOYMENT_TARGET' => '4.3',
|
|
32
|
+
'PUBLIC_HEADERS_FOLDER_PATH' => "$(TARGET_NAME)",
|
|
33
|
+
'SDKROOT' => 'iphoneos',
|
|
34
|
+
}.freeze,
|
|
35
|
+
:osx => {
|
|
36
|
+
'ARCHS' => "$(ARCHS_STANDARD_64_BIT)",
|
|
37
|
+
'GCC_ENABLE_OBJC_EXCEPTIONS' => 'YES',
|
|
38
|
+
'GCC_WARN_64_TO_32_BIT_CONVERSION' => 'YES',
|
|
39
|
+
'GCC_VERSION' => 'com.apple.compilers.llvm.clang.1_0',
|
|
40
|
+
'MACOSX_DEPLOYMENT_TARGET' => '10.7',
|
|
41
|
+
'SDKROOT' => 'macosx',
|
|
42
|
+
}.freeze,
|
|
43
|
+
[:osx, :debug] => {
|
|
44
|
+
'ONLY_ACTIVE_ARCH' => 'YES',
|
|
45
|
+
}.freeze,
|
|
46
|
+
[:osx, :release] => {
|
|
47
|
+
'DEBUG_INFORMATION_FORMAT' => 'dwarf-with-dsym',
|
|
48
|
+
}.freeze,
|
|
49
|
+
[:ios, :release] => {
|
|
50
|
+
'VALIDATE_PRODUCT' => 'YES',
|
|
51
|
+
}.freeze,
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
def self.new_release(project)
|
|
55
|
+
new(project, nil,
|
|
56
|
+
'name' => 'Release',
|
|
57
|
+
'buildSettings' => COMMON_BUILD_SETTINGS[:all].dup
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.new_debug(project)
|
|
62
|
+
new(project, nil,
|
|
63
|
+
'name' => 'Debug',
|
|
64
|
+
'buildSettings' => COMMON_BUILD_SETTINGS[:all].merge(COMMON_BUILD_SETTINGS[:debug])
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# [Hash] the build settings used when building a target
|
|
69
|
+
attribute :build_settings
|
|
70
|
+
|
|
71
|
+
# TODO why do I need to specify the uuid here?
|
|
72
|
+
has_one :base_configuration, :uuid => :base_configuration_reference
|
|
73
|
+
|
|
74
|
+
def initialize(*)
|
|
75
|
+
super
|
|
76
|
+
self.build_settings ||= {}
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class XCConfigurationList < AbstractPBXObject
|
|
81
|
+
attribute :default_configuration_is_visible
|
|
82
|
+
attribute :default_configuration_name
|
|
83
|
+
|
|
84
|
+
has_many :build_configurations
|
|
85
|
+
|
|
86
|
+
def initialize(*)
|
|
87
|
+
super
|
|
88
|
+
self.build_configuration_references ||= []
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def build_settings(build_configuration_name)
|
|
92
|
+
if config = build_configurations.where(:name => build_configuration_name)
|
|
93
|
+
config.build_settings
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'xcodeproj/project/object/group'
|
|
2
|
+
|
|
3
|
+
module Xcodeproj
|
|
4
|
+
class Project
|
|
5
|
+
module Object
|
|
6
|
+
|
|
7
|
+
# @todo Add a list of all possible file types for `explicit_file_type`
|
|
8
|
+
# and `last_known_file_type`.
|
|
9
|
+
class PBXFileReference < AbstractGroupEntry
|
|
10
|
+
# [String] the path to the file relative to the source tree
|
|
11
|
+
attribute :path
|
|
12
|
+
|
|
13
|
+
# [String] the source tree to which the file is relative. It can be one
|
|
14
|
+
# of `SOURCE_ROOT` or `SDKROOT`
|
|
15
|
+
attribute :source_tree
|
|
16
|
+
|
|
17
|
+
# [String] the file type regardless of what Xcode might think it is
|
|
18
|
+
attribute :explicit_file_type
|
|
19
|
+
|
|
20
|
+
# [String] the file type guessed by Xcode
|
|
21
|
+
attribute :last_known_file_type
|
|
22
|
+
|
|
23
|
+
# [String] wether of not this file should be indexed. This can be
|
|
24
|
+
# either "0" or "1".
|
|
25
|
+
attribute :include_in_index
|
|
26
|
+
|
|
27
|
+
has_many :build_files, :inverse_of => :file
|
|
28
|
+
|
|
29
|
+
def self.new_static_library(project, product_name)
|
|
30
|
+
new(project, nil,
|
|
31
|
+
"includeInIndex" => "0",
|
|
32
|
+
"sourceTree" => "BUILT_PRODUCTS_DIR",
|
|
33
|
+
"path" => "lib#{product_name}.a"
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def initialize(*)
|
|
38
|
+
super
|
|
39
|
+
self.path = path if path # sets default name
|
|
40
|
+
self.source_tree ||= 'SOURCE_ROOT'
|
|
41
|
+
self.include_in_index ||= "1"
|
|
42
|
+
set_default_file_type!
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
alias_method :_path=, :path=
|
|
46
|
+
def path=(path)
|
|
47
|
+
self._path = path
|
|
48
|
+
self.name ||= pathname.basename.to_s
|
|
49
|
+
path
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def pathname
|
|
53
|
+
Pathname.new(path)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def set_default_file_type!
|
|
57
|
+
return if explicit_file_type || last_known_file_type
|
|
58
|
+
case path
|
|
59
|
+
when /\.a$/
|
|
60
|
+
self.explicit_file_type = 'archive.ar'
|
|
61
|
+
when /\.framework$/
|
|
62
|
+
self.last_known_file_type = 'wrapper.framework'
|
|
63
|
+
when /\.xcconfig$/
|
|
64
|
+
self.last_known_file_type = 'text.xcconfig'
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
module Xcodeproj
|
|
2
|
+
class Project
|
|
3
|
+
module Object
|
|
4
|
+
|
|
5
|
+
class AbstractGroupEntry < AbstractPBXObject
|
|
6
|
+
has_one :group, :inverse_of => :children
|
|
7
|
+
|
|
8
|
+
def initialize(project, uuid, attributes)
|
|
9
|
+
is_new = uuid.nil?
|
|
10
|
+
super
|
|
11
|
+
# If there's no root_object yet, then this is probably the main group.
|
|
12
|
+
if is_new && @project.root_object
|
|
13
|
+
@project.main_group.children << self
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def destroy
|
|
18
|
+
group.child_references.delete(uuid)
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Sorts groups before files and inside those sorts by name.
|
|
23
|
+
def <=>(other)
|
|
24
|
+
if self.is_a?(PBXGroup) && other.is_a?(PBXFileReference)
|
|
25
|
+
-1
|
|
26
|
+
elsif self.is_a?(PBXFileReference) && other.is_a?(PBXGroup)
|
|
27
|
+
1
|
|
28
|
+
else
|
|
29
|
+
self.name <=> other.name
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @todo The `source_tree` can probably be more than just `<group>`.
|
|
35
|
+
class PBXGroup < AbstractGroupEntry
|
|
36
|
+
# [String] the source tree to which this group is relative. It can be
|
|
37
|
+
# `<group>`.
|
|
38
|
+
attribute :source_tree
|
|
39
|
+
|
|
40
|
+
has_many :children, :class => AbstractGroupEntry do |child|
|
|
41
|
+
# Associating the AbstractGroupEntry instance to this group through
|
|
42
|
+
# the inverse association will also remove it from the group it was
|
|
43
|
+
# in.
|
|
44
|
+
child.group = self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def initialize(*)
|
|
48
|
+
super
|
|
49
|
+
self.source_tree ||= '<group>'
|
|
50
|
+
self.child_references ||= []
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def main_group?
|
|
54
|
+
@project.main_group.uuid == uuid
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def name
|
|
58
|
+
if name = super
|
|
59
|
+
name
|
|
60
|
+
elsif attributes.has_key?('path')
|
|
61
|
+
File.basename(attributes['path'])
|
|
62
|
+
elsif main_group?
|
|
63
|
+
'Main Group'
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def files
|
|
68
|
+
children.list_by_class(PBXFileReference)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def create_file(path)
|
|
72
|
+
files.new("path" => path)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def create_files(paths)
|
|
76
|
+
paths.map { |path| create_file(path) }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def source_files
|
|
80
|
+
children.list_by_class(PBXFileReference) do |list|
|
|
81
|
+
list.let(:uuid_scope) do
|
|
82
|
+
files.reject { |file| file.build_files.empty? }.map(&:uuid)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def groups
|
|
88
|
+
children.list_by_class(PBXGroup)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def create_group(name)
|
|
92
|
+
groups.new("name" => name)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def <<(child)
|
|
96
|
+
children << child
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
module Xcodeproj
|
|
2
|
+
class Project
|
|
3
|
+
module Object
|
|
4
|
+
|
|
5
|
+
class PBXNativeTarget < AbstractPBXObject
|
|
6
|
+
STATIC_LIBRARY = 'com.apple.product-type.library.static'
|
|
7
|
+
|
|
8
|
+
# [String] the name of the build product
|
|
9
|
+
attribute :product_name
|
|
10
|
+
|
|
11
|
+
# [String] the build product type identifier
|
|
12
|
+
attribute :product_type
|
|
13
|
+
|
|
14
|
+
has_many :build_phases
|
|
15
|
+
has_many :dependencies # TODO :class => ?
|
|
16
|
+
has_many :build_rules # TODO :class => ?
|
|
17
|
+
has_one :build_configuration_list, :class => XCConfigurationList
|
|
18
|
+
has_one :product, :uuid => :product_reference
|
|
19
|
+
|
|
20
|
+
def self.new_static_library(project, platform, name)
|
|
21
|
+
project.add_system_framework(platform == :ios ? 'Foundation' : 'Cocoa')
|
|
22
|
+
|
|
23
|
+
target = new(project, nil, 'productType' => STATIC_LIBRARY, 'productName' => name)
|
|
24
|
+
target.product.path = "lib#{name}.a"
|
|
25
|
+
|
|
26
|
+
target.build_configurations.each do |config|
|
|
27
|
+
config.build_settings.merge!(XCBuildConfiguration::COMMON_BUILD_SETTINGS[platform])
|
|
28
|
+
|
|
29
|
+
# E.g. [:ios, :release]
|
|
30
|
+
extra_settings_key = [platform, config.name.downcase.to_sym]
|
|
31
|
+
if extra_settings = XCBuildConfiguration::COMMON_BUILD_SETTINGS[extra_settings_key]
|
|
32
|
+
config.build_settings.merge!(extra_settings)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
target
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# You need to specify a product. For a static library you can use
|
|
40
|
+
# PBXFileReference.new_static_library.
|
|
41
|
+
def initialize(project, *)
|
|
42
|
+
super
|
|
43
|
+
self.name ||= product_name
|
|
44
|
+
self.build_rule_references ||= []
|
|
45
|
+
self.dependency_references ||= []
|
|
46
|
+
|
|
47
|
+
unless build_phase_references
|
|
48
|
+
self.build_phase_references = []
|
|
49
|
+
|
|
50
|
+
source_build_phases.new
|
|
51
|
+
copy_files_build_phases.new
|
|
52
|
+
#shell_script_build_phases.new
|
|
53
|
+
|
|
54
|
+
phase = frameworks_build_phases.new
|
|
55
|
+
if frameworks_group = @project.groups.where(:name => 'Frameworks')
|
|
56
|
+
frameworks_group.files.each { |framework| phase << framework }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
unless build_configuration_list
|
|
61
|
+
self.build_configuration_list = project.objects.add(XCConfigurationList, {
|
|
62
|
+
'defaultConfigurationIsVisible' => '0',
|
|
63
|
+
'defaultConfigurationName' => 'Release',
|
|
64
|
+
})
|
|
65
|
+
# TODO or should this happen in buildConfigurationList?
|
|
66
|
+
build_configuration_list.build_configurations.new_debug
|
|
67
|
+
build_configuration_list.build_configurations.new_release
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
unless product
|
|
71
|
+
self.product = @project.files.new_static_library(product_name)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
alias_method :_product=, :product=
|
|
76
|
+
def product=(product)
|
|
77
|
+
self._product = product
|
|
78
|
+
@project.products << product
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def build_configurations
|
|
82
|
+
build_configuration_list.build_configurations
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def build_settings(build_configuration_name)
|
|
86
|
+
build_configuration_list.build_settings(build_configuration_name)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def source_build_phases
|
|
90
|
+
build_phases.list_by_class(PBXSourcesBuildPhase)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def copy_files_build_phases
|
|
94
|
+
build_phases.list_by_class(PBXCopyFilesBuildPhase)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def frameworks_build_phases
|
|
98
|
+
build_phases.list_by_class(PBXFrameworksBuildPhase)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def shell_script_build_phases
|
|
102
|
+
build_phases.list_by_class(PBXShellScriptBuildPhase)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Adds source files to the target.
|
|
106
|
+
#
|
|
107
|
+
# @note
|
|
108
|
+
# It finds an existing file reference or creates a new one.
|
|
109
|
+
#
|
|
110
|
+
# @param source_file_descriptions [Array<SourceFileDescription>] The
|
|
111
|
+
# description of the source files to add.
|
|
112
|
+
#
|
|
113
|
+
# @return [Array<PBXFileReference>]
|
|
114
|
+
#
|
|
115
|
+
def add_source_files(source_file_descriptions)
|
|
116
|
+
# Cache the files for performance.
|
|
117
|
+
files = @project.files.to_a
|
|
118
|
+
new_files = []
|
|
119
|
+
source_file_descriptions.each do |source_file_description|
|
|
120
|
+
path = source_file_description.path
|
|
121
|
+
copy_header_phase = source_file_description.copy_header_phase
|
|
122
|
+
compiler_flags = source_file_description.compiler_flags
|
|
123
|
+
|
|
124
|
+
file = (files + new_files).find { |file| file.path == path.to_s } || @project.files.new('path' => path.to_s)
|
|
125
|
+
build_file = file.build_files.new
|
|
126
|
+
if path.extname == '.h'
|
|
127
|
+
build_file.settings = { 'ATTRIBUTES' => ["Public"] }
|
|
128
|
+
# Working around a bug in Xcode 4.2 betas, remove this once the Xcode bug is fixed:
|
|
129
|
+
# https://github.com/alloy/cocoapods/issues/13
|
|
130
|
+
#phase = copy_header_phase || headers_build_phases.first
|
|
131
|
+
phase = copy_header_phase || copy_files_build_phases.first
|
|
132
|
+
phase.build_files << build_file
|
|
133
|
+
else
|
|
134
|
+
build_file.settings = { 'COMPILER_FLAGS' => compiler_flags } if compiler_flags && !compiler_flags.empty?
|
|
135
|
+
source_build_phases.first.build_files << build_file
|
|
136
|
+
end
|
|
137
|
+
new_files << file
|
|
138
|
+
end
|
|
139
|
+
new_files
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Struct representing the description needed to add a source file to
|
|
143
|
+
# the target.
|
|
144
|
+
#
|
|
145
|
+
# @!attribute path
|
|
146
|
+
# @return [Pathname] The path of the file.
|
|
147
|
+
#
|
|
148
|
+
# @!attribute compiler_flags
|
|
149
|
+
# @return [String] Any compiler flag.
|
|
150
|
+
#
|
|
151
|
+
# @!attribute copy_header_phase
|
|
152
|
+
# @return [PBXCopyFilesBuildPhase].
|
|
153
|
+
#
|
|
154
|
+
SourceFileDescription = Struct.new(:path, :compiler_flags, :copy_header_phase)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|