xcoder 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -221,51 +221,78 @@ It is important to note that Xcode gets cranky when the Xcode project file is ch
221
221
 
222
222
  ### Add the source and header file to the project
223
223
 
224
- # Copy the physical source files into the project path `Vendor/Reachability`
225
- FileUtils.cp_r "examples/Reachability/Vendor", "spec/TestProject"
226
-
227
- source_files = [ { 'name' => 'Reachability.m', 'path' => 'Vendor/Reachability/Reachability.m' },
228
- { 'name' => 'Reachability.h', 'path' => 'Vendor/Reachability/Reachability.h' } ]
224
+ ```ruby
225
+ # Copy the physical source files into the project path `Vendor/Reachability`
226
+ FileUtils.cp_r "examples/Reachability/Vendor", "spec/TestProject"
229
227
 
228
+ source_files = [ 'Vendor/Reachability/Reachability.m' , 'Vendor/Reachability/Reachability.h' ]
230
229
 
231
- # Create and traverse to the group Reachability within the Vendor folder
232
- project.group('Vendor/Reachability') do
233
- # Create files for each source file defined above
234
- source_files.each |source| create_file source }
235
- end
236
-
230
+ # Create and traverse to the group Reachability within the Vendor folder
231
+ project.group('Vendor/Reachability') do
232
+ # Create files for each source file defined above
233
+ source_files.each |source| create_file source }
234
+ end
235
+ ```
237
236
 
238
237
  Within the project file the groups in the path are created or found and then file references are added for the two specified source files. Xcoder only updates the logical project file, it does not copy physical files, that is done by the FileUtils.
239
238
 
240
239
 
241
- ### Adding source file to the sources build phase
242
-
243
- source_file = project.file('Vendor/Reachability/Reachability.m')
240
+ ### Adding source file to the sources build phase of a target
244
241
 
245
- # Select the main target of the project and add the source file to the build phase.
242
+ ```ruby
243
+ source_file = project.file('Vendor/Reachability/Reachability.m')
246
244
 
247
- project.target('TestProject').sources_build_phase do
248
- add_build_file source_file
249
- end
245
+ project.target('TestProject').sources_build_phase do
246
+ add_build_file source_file
247
+ end
248
+ ```
250
249
 
251
250
  Adding source files does not automatically include it in any of the built targets. That is done after you add the source file to the `sources_build_phase`. First we find the source file reference, select our target and then add it as a build file.
252
251
 
253
- ### Adding a System Framework
252
+ ### Adding a System Framework to the project and built in a target
254
253
 
255
- cfnetwork_framework = project.frameworks_group.create_system_framework 'CFNetwork'
254
+ ```ruby
255
+ cfnetwork_framework = project.frameworks_group.create_system_framework 'CFNetwork'
256
+
257
+ project.target('TestProject').framework_build_phase do
258
+ add_build_file cfnetwork_framework
259
+ end
260
+ ```
256
261
 
257
- project.target('TestProject').framework_build_phase do
258
- add_build_file cfnetwork_framework
259
- end
260
-
261
262
  The **CFNetwork.framework** is added to the `Frameworks` group of the project and then added to the frameworks build phase.
262
263
 
263
- ### Saving your changes!
264
+ ### Add additional build phases to a target
264
265
 
266
+ ```ruby
267
+ target.create_build_phases :copy_headers, :run_script
268
+ ```
269
+
270
+ ### Configure the Release build settings of a target
271
+
272
+ ```ruby
273
+ release_config = target.config 'Release'
274
+ release_config.set 'ALWAYS_SEARCH_USER_PATHS', false
275
+
276
+ target.config 'Release' do |config|
277
+ config.always_search_user_paths = false
278
+ config.architectures = [ "$(ARCHS_STANDARD_32_BIT)", 'armv6' ]
279
+ config.copy_phase_strip = true
280
+ config.dead_code_stripping = false
281
+ config.debug_information_format = "dwarf-with-dsym"
282
+ config.c_language_standard = 'gnu99'
283
+ end
284
+ ```
285
+
286
+ Configuration settings can be accessed through `get`, `set`, and `append` with their [Xcode Build Names](https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW110) or through convenience methods generated for most of the build settings (`property_name`, `property_name=`, `append_to_property_name`). The entire list of property names can be found in the [configuration](/rayh/xcoder/blob/master/lib/xcode/configuration.rb).
287
+
288
+
289
+ ### Saving your changes!
265
290
 
266
- project.save!
291
+ ```ruby
292
+ project.save!
293
+ ```
267
294
 
268
- The saved file output is ugly compared to what you may normally see when you view a Xcode project file. Luckily, Xcode will fix the format of the file if you make any small changes to the project that require it to save.
295
+ The saved file output is slightly different than what you normally see when you view a Xcode project file. Luckily, Xcode will fix the format of the file if you make any small changes to the project that requires it to save.
269
296
 
270
297
  ### More Examples
271
298
 
@@ -3,7 +3,7 @@ module Xcode
3
3
  module BuildPhase
4
4
 
5
5
  #
6
- # @return [BuildPhase] the framework specific build phase of the target.
6
+ # @return [BuildPhase] properties for a link frameworks build phase
7
7
  #
8
8
  # @example
9
9
  #
@@ -26,7 +26,7 @@ module Xcode
26
26
  end
27
27
 
28
28
  #
29
- # @return [BuildPhase] the sources specific build phase of the target.
29
+ # @return [BuildPhase] properties for a compile sources build phase
30
30
  #
31
31
  def self.sources
32
32
  { 'isa' => 'PBXSourcesBuildPhase',
@@ -36,7 +36,7 @@ module Xcode
36
36
  end
37
37
 
38
38
  #
39
- # @return [BuildPhase] the resources specific build phase of the target.
39
+ # @return [BuildPhase] properties for a resources build phase
40
40
  #
41
41
  def self.resources
42
42
  { 'isa' => 'PBXResourcesBuildPhase',
@@ -45,6 +45,30 @@ module Xcode
45
45
  'runOnlyForDeploymentPostprocessing' => '0' }
46
46
  end
47
47
 
48
+ #
49
+ # @return [BuildPhase] properties for a run shell script build phase
50
+ #
51
+ def self.run_script
52
+ { 'isa' => 'PBXShellScriptBuildPhase',
53
+ 'buildActionMask' => '2147483647',
54
+ 'files' => [],
55
+ 'inputPaths' => [],
56
+ 'outputPaths' => [],
57
+ 'shellPath' => '/bin/sh',
58
+ 'shellScript' => '',
59
+ 'runOnlyForDeploymentPostprocessing' => '0' }
60
+ end
61
+
62
+ #
63
+ # @return [BuildPhase] properties for a copy headers build phase
64
+ #
65
+ def self.copy_headers
66
+ { 'isa' => 'PBXHeadersBuildPhase',
67
+ 'buildActionMask' => '2147483647',
68
+ 'files' => [],
69
+ 'runOnlyForDeploymentPostprocessing' => '0' }
70
+ end
71
+
48
72
  #
49
73
  # Return the BuildFile given the file name.
50
74
  #
@@ -116,19 +140,49 @@ module Xcode
116
140
  end
117
141
 
118
142
  #
119
- # Add the specified file to the Build Phase.
120
- #
121
- #
143
+ # Add the specified file to the Build Phase that will have specific compiler
144
+ # flags to disable ARC.
122
145
  #
123
146
  # @param [FileReference] file the FileReference Resource to add to the build
124
- # phase.
125
- # @param [Hash] settings additional build settings that are specifically applied
126
- # to this individual file.
147
+ # phase.
127
148
  #
128
149
  def add_build_file_without_arc(file)
129
150
  add_build_file file, { 'COMPILER_FLAGS' => "-fno-objc-arc" }
130
151
  end
131
152
 
153
+ #
154
+ # Add the specific file to the Build Phase with the privacy settings used
155
+ # for header files that are added to the build headers phase.
156
+ #
157
+ # @example Add a source header file as public
158
+ #
159
+ # spec_file = project.group('Specs/Controller').create_file('FirstControllerSpec.h')
160
+ # project.target('Specs').headers_build_phase.add_build_file_with_public_privacy
161
+ #
162
+ # @param [FileReference] file the FileReference Resource to add to the build
163
+ # phase.
164
+ #
165
+ def add_build_file_with_public_privacy(file)
166
+ add_build_file file, { "ATTRIBUTES" => [ 'Public' ] }
167
+ end
168
+
169
+ #
170
+ # Add the specific file to the Build Phase with the privacy settings used
171
+ # for header files that are added to the build headers phase.
172
+ #
173
+ # @example Add a source header file as private
174
+ #
175
+ # spec_file = project.group('Specs/Controller').create_file('FirstControllerSpec.h')
176
+ # project.target('Specs').headers_build_phase.add_build_file_with_private_privacy
177
+ #
178
+ # @param [FileReference] file the FileReference Resource to add to the build
179
+ # phase.
180
+ #
181
+ def add_build_file_with_private_privacy(file)
182
+ add_build_file file, { "ATTRIBUTES" => [ 'Private' ] }
183
+ end
184
+
185
+
132
186
  end
133
187
 
134
188
  end
data/lib/xcode/builder.rb CHANGED
@@ -70,7 +70,6 @@ module Xcode
70
70
  testflight = Xcode::Testflight.new(api_token, team_token)
71
71
  yield(testflight) if block_given?
72
72
  testflight.upload(ipa_path, dsym_zip_path)
73
- self
74
73
  end
75
74
 
76
75
  def clean
@@ -5,6 +5,7 @@ require 'xcode/configurations/string_property'
5
5
  require 'xcode/configurations/boolean_property'
6
6
  require 'xcode/configurations/array_property'
7
7
  require 'xcode/configurations/key_value_array_property'
8
+ require 'xcode/configurations/enumeration_property'
8
9
 
9
10
  module Xcode
10
11
 
@@ -250,6 +251,65 @@ module Xcode
250
251
  # Build Setting - "OTHER_LDFLAGS"
251
252
  # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW76
252
253
  property :other_linker_flags, "OTHER_LDFLAGS", SpaceDelimitedString
254
+
255
+ # @attribute
256
+ # Build Setting - "DEAD_CODE_STRIPPING"
257
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_216
258
+ property :dead_code_stripping, "DEAD_CODE_STRIPPING", BooleanProperty
259
+
260
+ # @attribute
261
+ # Build Setting - "DEBUG_INFORMATION_FORMAT"
262
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_54
263
+ property :debug_information_format, "DEBUG_INFORMATION_FORMAT",
264
+ EnumerationProperty.new('stabs','dwarf','dwarf-with-dsym')
265
+
266
+
267
+ # @attribute
268
+ # Build Setting - "GCC_ENABLE_OBJC_EXCEPTIONS"
269
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW109
270
+ property :enable_objc_exceptions, "GCC_ENABLE_OBJC_EXCEPTIONS", BooleanProperty
271
+
272
+ # @attribute
273
+ # Build Setting - "GCC_GENERATE_DEBUGGING_SYMBOLS"
274
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html
275
+ property :generate_debugging_symbols, "GCC_GENERATE_DEBUGGING_SYMBOLS", BooleanProperty
276
+
277
+ # @attribute
278
+ # Build Setting - "GCC_WARN_64_TO_32_BIT_CONVERSION"
279
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html
280
+ property :warn_64_to_32_bit_conversion, "GCC_WARN_64_TO_32_BIT_CONVERSION", BooleanProperty
281
+
282
+ # @attribute
283
+ # Build Setting - "GCC_WARN_ABOUT_MISSING_PROTOTYPES"
284
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html
285
+ property :warn_about_missing_protoypes, "GCC_WARN_ABOUT_MISSING_PROTOTYPES", BooleanProperty
286
+
287
+ # @attribute
288
+ # Build Setting - "LINK_WITH_STANDARD_LIBRARIES"
289
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_227
290
+ property :link_with_standard_libraries, "LINK_WITH_STANDARD_LIBRARIES", BooleanProperty
291
+
292
+ # @attribute
293
+ # Build Setting - "INSTALL_PATH"
294
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_82
295
+ property :install_path, "INSTALL_PATH", StringProperty
296
+
297
+ # @attribute
298
+ # Build Setting - "MACH_O_TYPE"
299
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_39
300
+ property :mach_o_type, "MACH_O_TYPE",
301
+ EnumerationProperty.new('mh_executable', 'mh_bundle', 'mh_object', 'mh_dylib', 'staticlib')
302
+
303
+ # @attribute
304
+ # Build Setting - "MACOSX_DEPLOYMENT_TARGET"
305
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_188
306
+ property :macosx_deployment_target, "MACOSX_DEPLOYMENT_TARGET",
307
+ EnumerationProperty.new('10.7','10.6','10.5','10.4','10.3','10.2','10.1')
308
+
309
+ # @attribute
310
+ # Build Setting - "VALID_ARCHS"
311
+ # @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-DontLinkElementID_43
312
+ property :valid_architectures, "VALID_ARCHS", SpaceDelimitedString
253
313
 
254
314
  #
255
315
  # Opens the info plist associated with the configuration and allows you to
@@ -0,0 +1,27 @@
1
+
2
+ module Xcode
3
+ class EnumerationProperty
4
+
5
+ attr_reader :enumeration
6
+
7
+ def initialize(*args)
8
+ @enumeration = args.flatten.compact
9
+ end
10
+
11
+ def open(value)
12
+ warn "Configuration property contains a value '#{value}' not within the enumeration." unless enumeration.include?(value)
13
+ value
14
+ end
15
+
16
+ def save(value)
17
+ raise "Configuration property value specified '#{value}' not within the enumeration." unless enumeration.include?(value)
18
+ value
19
+ end
20
+
21
+ def append(original,value)
22
+ warn "Overriding configuration property '#{original}' with new value '#{value}'" unless original == value
23
+ save(value)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,41 @@
1
+
2
+ module Xcode
3
+
4
+ #
5
+ # Within a Target Dependency there is a ContainerItemProxy object which likely
6
+ # holds the reference to the project (important if there are multiple projects)
7
+ # and the target within that project.
8
+ #
9
+ # @see TargetDependency#create_dependency_on
10
+ # @see Target#add_dependency
11
+ #
12
+ module ContainerItemProxy
13
+
14
+ #
15
+ # Generate default properties for a Container Item Proxy
16
+ #
17
+ # @see TargetDependency
18
+ #
19
+ # /* Begin PBXContainerItemProxy section */
20
+ # 98A30E0314CDF2D800DF81EF /* PBXContainerItemProxy */ = {
21
+ # isa = PBXContainerItemProxy;
22
+ # containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
23
+ # proxyType = 1;
24
+ # remoteGlobalIDString = 98A1E39414CDED2C00D4AB9D; /* Target in the Project */
25
+ # remoteInfo = "Facebook Framework";
26
+ # };
27
+ # /* End PBXContainerItemProxy section */
28
+ #
29
+ def self.default(project_identifier,target_identifier,target_name)
30
+ { 'isa' => 'PBXContainerItemProxy',
31
+ 'containerPortal' => project_identifier,
32
+ 'proxyType' => 1,
33
+ 'remoteGlobalIDString' => target_identifier,
34
+ # @todo It is unclear if the remoteInfo name is necessary and it is currently
35
+ # unclear to me how this value is set. At the moment it simply set with
36
+ # the target name supplied.
37
+ 'remoteInfo' => target_name }
38
+ end
39
+
40
+ end
41
+ end
@@ -17,7 +17,7 @@ class Hash
17
17
  #
18
18
  def to_xcplist
19
19
  plist_of_items = map do |k,v|
20
- "\"#{k}\" = #{v.to_xcplist};"
20
+ "#{k.to_xcplist} = #{v.to_xcplist};"
21
21
  end.join("\n")
22
22
 
23
23
  %{{
data/lib/xcode/project.rb CHANGED
@@ -36,6 +36,10 @@ module Xcode
36
36
  # functionality.
37
37
  attr_reader :registry
38
38
 
39
+ # @return [ProjectReference] the project object that is contained in the
40
+ # project file that contains additional information
41
+ attr_reader :project
42
+
39
43
  #
40
44
  # Initialized with a specific path and sdk.
41
45
  #
@@ -78,10 +82,19 @@ module Xcode
78
82
  @registry.archive_version
79
83
  end
80
84
 
85
+ #
86
+ # @return [Array<Configuration>] a list of configurations global to the project
87
+ #
81
88
  def global_configs
82
89
  @project.configs
83
90
  end
84
91
 
92
+ #
93
+ # @param [String,Symbol] name of the configuration for the project
94
+ #
95
+ # @return [Configuration] the project level configuration with the given name;
96
+ # raise an exception if no configuration exists with that name.
97
+ #
85
98
  def global_config(name)
86
99
  @project.config(name)
87
100
  end
@@ -256,20 +269,18 @@ module Xcode
256
269
  # generate all the additional build phases, configurations, and files
257
270
  # that create a project.
258
271
  #
259
- # @todo generate a create target with sensible defaults, similar to how
260
- # it is done through Xcode itself.
272
+ # Available targts:
261
273
  #
262
- # @todo based on the specified type of target, default build phases and
263
- # configuration should be created for the target similar to what is
264
- # supported in xcode. Currently even now the :ios target does not
265
- # generate the deafult build_phases for you and requires you to make those.
274
+ # * native
275
+ # * aggregate
266
276
  #
267
277
  # @param [String] name the name to provide to the target. This will also
268
278
  # be the value that other defaults will be based on.
279
+ # @param [String,Symbol] type the type of build target to create.
269
280
  #
270
281
  # @return [Target] the target created.
271
282
  #
272
- def create_target(name,type=:ios)
283
+ def create_target(name,type=:native)
273
284
 
274
285
  target = @registry.add_object Target.send(type)
275
286
  @project.properties['targets'] << target.identifier
@@ -11,6 +11,8 @@ require 'xcode/configuration_owner'
11
11
  require 'xcode/target'
12
12
  require 'xcode/variant_group'
13
13
  require 'xcode/project_reference'
14
+ require 'xcode/target_dependency'
15
+ require 'xcode/container_item_proxy'
14
16
 
15
17
  module Xcode
16
18
 
@@ -70,12 +72,16 @@ module Xcode
70
72
  'XCBuildConfiguration' => Configuration,
71
73
  'PBXFileReference' => FileReference,
72
74
  'PBXGroup' => Group,
73
- 'PBXNativeTarget' => [Target, ConfigurationOwner],
74
- 'PBXLegacyTarget' => [Target, ConfigurationOwner],
75
- 'PBXAggregateTarget' => Target,
75
+ 'PBXNativeTarget' => [Target, ConfigurationOwner ],
76
+ 'PBXLegacyTarget' => [Target, ConfigurationOwner ],
77
+ 'PBXAggregateTarget' => [ Target, ConfigurationOwner ],
76
78
  'PBXFrameworksBuildPhase' => BuildPhase,
77
79
  'PBXSourcesBuildPhase' => BuildPhase,
78
80
  'PBXResourcesBuildPhase' => BuildPhase,
81
+ 'PBXHeadersBuildPhase' => BuildPhase,
82
+ 'PBXShellScriptBuildPhase' => BuildPhase,
83
+ 'PBXTargetDependency' => TargetDependency,
84
+ 'PBXContainerItemProxy' => ContainerItemProxy,
79
85
  'PBXBuildFile' => BuildFile,
80
86
  'PBXVariantGroup' => VariantGroup,
81
87
  'XCConfigurationList' => ConfigurationList,
data/lib/xcode/target.rb CHANGED
@@ -7,37 +7,39 @@ module Xcode
7
7
  # be to generate the application, generate a universal framework, or execute
8
8
  # tests.
9
9
  #
10
+ # Creating a target is usually done within a Project. There a specific target
11
+ # type can be specified.
10
12
  #
11
- # @example Target as Hash
12
- #
13
- # E21D8AA914E0F817002E56AA /* newtarget */ = {
14
- # isa = PBXNativeTarget;
15
- # buildConfigurationList = E21D8ABD14E0F817002E56AA /* Build configuration list for PBXNativeTarget "newtarget" */;
16
- # buildPhases = (
17
- # E21D8AA614E0F817002E56AA /* Sources */,
18
- # E21D8AA714E0F817002E56AA /* Frameworks */,
19
- # E21D8AA814E0F817002E56AA /* Resources */,
20
- # );
21
- # buildRules = (
22
- # );
23
- # dependencies = (
24
- # );
25
- # name = newtarget;
26
- # productName = newtarget;
27
- # productReference = E21D8AAA14E0F817002E56AA /* newtarget.app */;
28
- # productType = "com.apple.product-type.application";
29
- # };
30
- #
31
- # @todo provide more targets, based on the properties hash generated from Xcode
13
+ # @see Project#create_target
32
14
  #
33
15
  module Target
34
16
 
35
17
  #
36
- # This is a generic properties hash for an ios target
37
- # @todo this target should create by default the sources, frameworks, and
38
- # resources build phases.
18
+ # This is a generic properties hash for a native target
19
+ #
20
+ # @example Native Target Properties
21
+ #
22
+ # E21D8AA914E0F817002E56AA /* newtarget */ = {
23
+ # isa = PBXNativeTarget;
24
+ # buildConfigurationList = E21D8ABD14E0F817002E56AA /* Build configuration list for PBXNativeTarget "newtarget" */;
25
+ # buildPhases = (
26
+ # E21D8AA614E0F817002E56AA /* Sources */,
27
+ # E21D8AA714E0F817002E56AA /* Frameworks */,
28
+ # E21D8AA814E0F817002E56AA /* Resources */,
29
+ # );
30
+ # buildRules = (
31
+ # );
32
+ # dependencies = (
33
+ # );
34
+ # name = newtarget;
35
+ # productName = newtarget;
36
+ # productReference = E21D8AAA14E0F817002E56AA /* newtarget.app */;
37
+ # productType = "com.apple.product-type.application";
38
+ # };
39
39
  #
40
- def self.ios
40
+ # @return [Hash] the properties default to a native target
41
+ #
42
+ def self.native
41
43
  { 'isa' => 'PBXNativeTarget',
42
44
  'buildConfigurationList' => nil,
43
45
  'buildPhases' => [],
@@ -48,6 +50,47 @@ module Xcode
48
50
  'productReference' => '',
49
51
  'productType' => 'com.apple.product-type.application' }
50
52
  end
53
+
54
+ #
55
+ # This is a generic properties hash for an a bundle target. It shares numerous
56
+ # similarities with the native target, it simply has a bundle product type.
57
+ #
58
+ # @return [Hash] the properties default to a bundle target
59
+ #
60
+ def self.bundle
61
+ self.native.merge('productType' => 'com.apple.product-type.bundle')
62
+ end
63
+
64
+ #
65
+ # This is a generic properties hash for an aggregate target.
66
+ #
67
+ # @example Aggregate Target properties
68
+ #
69
+ # /* Begin PBXAggregateTarget section */
70
+ # 98E1216814CDEF42009CE4EE /* Facebook Universal Framework */ = {
71
+ # isa = PBXAggregateTarget;
72
+ # buildConfigurationList = 98E1216914CDEF42009CE4EE /* Build configuration list for PBXAggregateTarget "Facebook Universal Framework" */;
73
+ # buildPhases = (
74
+ # 98E1216E14CDEF4C009CE4EE /* ShellScript */,
75
+ # );
76
+ # dependencies = (
77
+ # 98A30E0414CDF2D800DF81EF /* PBXTargetDependency */,
78
+ # );
79
+ # name = "Facebook Universal Framework";
80
+ # productName = Facebook;
81
+ # };
82
+ # /* End PBXAggregateTarget section */
83
+ #
84
+ # @return [Hash] the properties defalut to a aggregate target
85
+ #
86
+ def self.aggregate
87
+ { 'isa' => 'PBXAggregateTarget',
88
+ 'buildConfigurationList' => nil,
89
+ 'buildPhases' => [],
90
+ 'dependencies' => [],
91
+ 'name' => '',
92
+ 'productName' => '' }
93
+ end
51
94
 
52
95
  # @return [Project] the reference to the project for which these targets reside.
53
96
  attr_accessor :project
@@ -73,15 +116,40 @@ module Xcode
73
116
  build_phase 'PBXResourcesBuildPhase', &block
74
117
  end
75
118
 
119
+ #
120
+ # @return [BuildPhase] the run script specific build phase of the target.
121
+ #
122
+ def run_script_build_phase(&block)
123
+ build_phase 'PBXShellScriptBuildPhase', &block
124
+ end
125
+
126
+ #
127
+ # @return [BuildPhase] the copy headers specific build phase of the target.
128
+ #
129
+ def copy_headers_build_phase(&block)
130
+ build_phase 'PBXHeadersBuildPhase', &block
131
+ end
132
+
76
133
  def build_phase(type,&block)
77
134
  found_build_phase = build_phases.find {|phase| phase.isa == type }
78
135
  found_build_phase.instance_eval(&block) if block_given?
79
136
  found_build_phase
80
137
  end
138
+
81
139
  #
82
- # @example building the three main phases for a target.
140
+ # Create a build phase with the given name. Available build phases:
141
+ #
142
+ # * sources
143
+ # * resources
144
+ # * framework
145
+ # * run_script
146
+ # * copy_headers
147
+ #
148
+ # @example Creating the sources build phase
83
149
  #
84
150
  # target.create_build_phase :sources
151
+ #
152
+ # @example Creating the resources build phase (with optional block)
85
153
  #
86
154
  # target.create_build_phase :resources do |phase|
87
155
  # # each phase that is created.
@@ -125,6 +193,20 @@ module Xcode
125
193
 
126
194
  end
127
195
 
196
+ #
197
+ # @param [Target] target the target that the current target is dependent on
198
+ # for compilation.
199
+ #
200
+ def add_dependency(target)
201
+
202
+ target_dependency = TargetDependency.default
203
+ target_dependency = @registry.add_object target_dependency
204
+ target_dependency.create_dependency_on target
205
+
206
+ target_dependency
207
+
208
+ end
209
+
128
210
  #
129
211
  # Create a product reference file and add it to the product. This is by
130
212
  # default added to the 'Products' group.
@@ -0,0 +1,56 @@
1
+ require 'xcode/container_item_proxy'
2
+
3
+ module Xcode
4
+
5
+ #
6
+ # Targets, usually Aggregate targets, have dependencies on other targets. This
7
+ # object manages that relationship. While the class-level default properties
8
+ # method will return the properties necessary for a target it does not configure
9
+ # it correctly until the method #create_dependency_on is called with the particular
10
+ # target.
11
+ #
12
+ # @see Target#add_dependency
13
+ #
14
+ module TargetDependency
15
+
16
+ #
17
+ # Generate default properties for a Target Dependency
18
+ #
19
+ # /* Begin PBXTargetDependency section */
20
+ # 98A30E0414CDF2D800DF81EF /* PBXTargetDependency */ = {
21
+ # isa = PBXTargetDependency;
22
+ # target = 98A1E39414CDED2C00D4AB9D /* Facebook */;
23
+ # targetProxy = 98A30E0314CDF2D800DF81EF /* PBXContainerItemProxy */;
24
+ # };
25
+ # /* End PBXTargetDependency section */
26
+ #
27
+ # @return [Hash] the properties default to a target dependency; however they
28
+ # are all nil and this properties list is incomplete until the property
29
+ # values are setup through #create_dependency_on
30
+ #
31
+ def self.default
32
+ { 'isa' => 'PBXTargetDependency',
33
+ 'target' => nil,
34
+ 'targetProxy' => nil }
35
+ end
36
+
37
+
38
+ #
39
+ # Establish the Target that this Target Dependency is dependent.
40
+ #
41
+ # @param [Target] target the target this dependency is based on
42
+ #
43
+ def create_dependency_on(target)
44
+
45
+ @properties['target'] = target.identifier
46
+
47
+ container_item_proxy = ContainerItemProxy.default target.project.project.identifier, target.identifier, target.name
48
+ container_item_proxy = @registry.add_object(container_item_proxy)
49
+
50
+ @properties['targetProxy'] = container_item_proxy.identifier
51
+
52
+ save!
53
+ end
54
+
55
+ end
56
+ end
@@ -50,6 +50,9 @@ module Xcode
50
50
 
51
51
  json = JSON.parse(response.join(''))
52
52
  puts " + Done, got: #{json.inspect}"
53
+
54
+ yield(json) if block_given?
55
+
53
56
  json
54
57
  end
55
58
  end
data/lib/xcode/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Xcode
2
- VERSION = "0.1.9"
2
+ VERSION = "0.1.10"
3
3
  end
@@ -65,6 +65,25 @@ describe Xcode::BuildPhase do
65
65
  subject.file('ArcLessSource.m').settings.should == { 'COMPILER_FLAGS' => "-fno-objc-arc" }
66
66
  end
67
67
  end
68
+
69
+ describe "#add_build_file_with_public_privacy" do
70
+ it "should add the specified file to the build phase with the correct parameters" do
71
+ source_file = project.groups.create_file 'publicheader.h'
72
+ subject.add_build_file_with_public_privacy source_file
73
+ subject.build_file('publicheader.h').should_not be_nil
74
+ subject.file('publicheader.h').settings.should == { 'ATTRIBUTES' => "Public" }
75
+ end
76
+ end
77
+
78
+ describe "#add_build_file_with_private_privacy" do
79
+ it "should add the specified file to the build phase with the correct parameters" do
80
+ source_file = project.groups.create_file 'privateheader.h'
81
+ subject.add_build_file_with_private_privacy source_file
82
+ subject.build_file('privateheader.h').should_not be_nil
83
+ subject.file('privateheader.h').settings.should == { 'ATTRIBUTES' => "Private" }
84
+ end
85
+ end
86
+
68
87
  end
69
88
 
70
89
 
@@ -77,7 +77,7 @@ describe Xcode::Configuration do
77
77
  subject.set 'OTHER_LDFLAGS', '-NONE -FOR'
78
78
  subject.append 'OTHER_LDFLAGS', '-FOR'
79
79
  subject.append 'OTHER_LDFLAGS', [ '-FOR' , '-ME' ]
80
- settings['OTHER_LDFLAGS'].should == "-FOR -ME"
80
+ settings['OTHER_LDFLAGS'].should == "-NONE -FOR -ME"
81
81
  end
82
82
  end
83
83
 
@@ -306,7 +306,31 @@ describe Xcode::Configuration do
306
306
  end
307
307
  end
308
308
  end
309
-
309
+
310
+ describe "debug_information_format" do
311
+
312
+ before(:each) do
313
+ subject.build_settings['DEBUG_INFORMATION_FORMAT'] = 'stabs'
314
+ end
315
+
316
+ it "should be able to correctly get the property" do
317
+ subject.debug_information_format.should == 'stabs'
318
+ end
319
+
320
+ it "should be able to correctly set the property" do
321
+ subject.debug_information_format = 'dwarf'
322
+ end
323
+
324
+ it "should raise an error when attempting to set a value not in the enumeration" do
325
+ expect { subject.debug_information_format = 'unknown' }.to raise_error
326
+ end
327
+
328
+ it "should set the new value when appending a value" do
329
+ subject.append_to_debug_information_format 'dwarf'
330
+ end
331
+
332
+ end
333
+
310
334
 
311
335
  let(:all_properties) do
312
336
  string_properties +
@@ -0,0 +1,65 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe "Universal Framework", :integration => true do
4
+
5
+ let(:project) { Xcode.project 'TestProject' }
6
+
7
+ it "should install without error" do
8
+
9
+ project.create_target 'Library', :bundle do |target|
10
+
11
+ target.create_build_phase :sources do |source|
12
+ source.add_build_file project.file('TestProject/AppDelegate.m')
13
+ end
14
+
15
+ target.create_build_phase :copy_headers do |headers|
16
+ headers.add_build_file_with_public_privacy project.file('TestProject/AppDelegate.h')
17
+ headers.add_build_file project.file('TestProject/Supporting Files/TestProject-Prefix.pch')
18
+ end
19
+
20
+ target.create_configurations :release do |config|
21
+ config.always_search_user_paths = false
22
+ config.architectures = [ "$(ARCHS_STANDARD_32_BIT)", 'armv6' ]
23
+ config.copy_phase_strip = true
24
+ config.dead_code_stripping = false
25
+ config.debug_information_format = "dwarf-with-dsym"
26
+ config.c_language_standard = 'gnu99'
27
+ config.enable_objc_exceptions = true
28
+ config.generate_debugging_symbols = false
29
+ config.precompile_prefix_headers = false
30
+ config.gcc_version = 'com.apple.compilers.llvm.clang.1_0'
31
+ config.warn_64_to_32_bit_conversion = true
32
+ config.warn_about_missing_prototypes = true
33
+ config.install_path = "$(LOCAL_LIBRARY_DIR)/Bundles"
34
+ config.link_with_standard_libraries = false
35
+ config.mach_o_type = 'mh_object'
36
+ config.macosx_deployment_target = '10.7'
37
+ config.product_name = '$(TARGET_NAME)'
38
+ config.sdkroot = 'iphoneos'
39
+ config.valid_architectures = '$(ARCHS_STANDARD_32_BIT)'
40
+ config.wrapper_extension = 'framework'
41
+ config.info_plist_location = ""
42
+ config.prefix_header = ""
43
+ config.save!
44
+ end
45
+
46
+ end
47
+
48
+ project.create_target('Universal Library',:aggregate) do |target|
49
+
50
+ target.product_name = 'Univeral Library'
51
+
52
+ target.add_dependency project.target('Library')
53
+
54
+ target.create_configurations :release
55
+
56
+ target.create_build_phase :run_script do |script|
57
+ script.shell_script = "# Sets the target folders and the final framework product.\nFMK_NAME=Library\nFMK_VERSION=A\n\n# Install dir will be the final output to the framework.\n# The following line create it in the root folder of the current project.\nINSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework\n\n# Working dir will be deleted after the framework creation.\nWRK_DIR=build\nDEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework\nSIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework\n\n# Building both architectures.\nxcodebuild -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphoneos\nxcodebuild -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphonesimulator\n\n# Cleaning the oldest.\nif [ -d \"${INSTALL_DIR}\" ]\nthen\nrm -rf \"${INSTALL_DIR}\"\nfi\n\n# Creates and renews the final product folder.\nmkdir -p \"${INSTALL_DIR}\"\nmkdir -p \"${INSTALL_DIR}/Versions\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources\"\nmkdir -p \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers\"\n\n# Creates the internal links.\n# It MUST uses relative path, otherwise will not work when the folder is copied/moved.\nln -s \"${FMK_VERSION}\" \"${INSTALL_DIR}/Versions/Current\"\nln -s \"Versions/Current/Headers\" \"${INSTALL_DIR}/Headers\"\nln -s \"Versions/Current/Resources\" \"${INSTALL_DIR}/Resources\"\nln -s \"Versions/Current/${FMK_NAME}\" \"${INSTALL_DIR}/${FMK_NAME}\"\n\n# Copies the headers and resources files to the final product folder.\ncp -R \"${DEVICE_DIR}/Headers/\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Headers/\"\ncp -R \"${DEVICE_DIR}/\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/\"\n\n# Removes the binary and header from the resources folder.\nrm -r \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/Headers\" \"${INSTALL_DIR}/Versions/${FMK_VERSION}/Resources/${FMK_NAME}\"\n\n# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.\nlipo -create \"${DEVICE_DIR}/${FMK_NAME}\" \"${SIMULATOR_DIR}/${FMK_NAME}\" -output \"${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}\"\n\nrm -r \"${WRK_DIR}\""
58
+ end
59
+
60
+ end
61
+
62
+ project.save!
63
+ end
64
+
65
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-25 00:00:00.000000000Z
13
+ date: 2012-03-30 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
17
- requirement: &70245902880760 !ruby/object:Gem::Requirement
17
+ requirement: &70315163014440 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70245902880760
25
+ version_requirements: *70315163014440
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: plist
28
- requirement: &70245902896700 !ruby/object:Gem::Requirement
28
+ requirement: &70315157801340 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70245902896700
36
+ version_requirements: *70315157801340
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: nokogiri
39
- requirement: &70245902896280 !ruby/object:Gem::Requirement
39
+ requirement: &70315157800920 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70245902896280
47
+ version_requirements: *70315157800920
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: builder
50
- requirement: &70245902895860 !ruby/object:Gem::Requirement
50
+ requirement: &70315157800500 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70245902895860
58
+ version_requirements: *70315157800500
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: rest-client
61
- requirement: &70245902895440 !ruby/object:Gem::Requirement
61
+ requirement: &70315157800080 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,7 +66,7 @@ dependencies:
66
66
  version: '0'
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *70245902895440
69
+ version_requirements: *70315157800080
70
70
  description: Provides a ruby based object-model for parsing project structures and
71
71
  invoking builds
72
72
  email:
@@ -93,10 +93,12 @@ files:
93
93
  - lib/xcode/configuration_owner.rb
94
94
  - lib/xcode/configurations/array_property.rb
95
95
  - lib/xcode/configurations/boolean_property.rb
96
+ - lib/xcode/configurations/enumeration_property.rb
96
97
  - lib/xcode/configurations/key_value_array_property.rb
97
98
  - lib/xcode/configurations/space_delimited_string_property.rb
98
99
  - lib/xcode/configurations/string_property.rb
99
100
  - lib/xcode/configurations/targeted_device_family_property.rb
101
+ - lib/xcode/container_item_proxy.rb
100
102
  - lib/xcode/core_ext/array.rb
101
103
  - lib/xcode/core_ext/boolean.rb
102
104
  - lib/xcode/core_ext/fixnum.rb
@@ -116,6 +118,7 @@ files:
116
118
  - lib/xcode/shell.rb
117
119
  - lib/xcode/simple_identifier_generator.rb
118
120
  - lib/xcode/target.rb
121
+ - lib/xcode/target_dependency.rb
119
122
  - lib/xcode/test/formatters/junit_formatter.rb
120
123
  - lib/xcode/test/formatters/stdout_formatter.rb
121
124
  - lib/xcode/test/ocunit_report_parser.rb
@@ -158,6 +161,7 @@ files:
158
161
  - spec/integration/cedar_install_spec.rb
159
162
  - spec/integration/pull_to_refresh_install_spec.rb
160
163
  - spec/integration/reachability_install_spec.rb
164
+ - spec/integration/universal_framework_spec.rb
161
165
  - spec/keychain_spec.rb
162
166
  - spec/project_spec.rb
163
167
  - spec/provisioning_profile_spec.rb
@@ -222,6 +226,7 @@ test_files:
222
226
  - spec/integration/cedar_install_spec.rb
223
227
  - spec/integration/pull_to_refresh_install_spec.rb
224
228
  - spec/integration/reachability_install_spec.rb
229
+ - spec/integration/universal_framework_spec.rb
225
230
  - spec/keychain_spec.rb
226
231
  - spec/project_spec.rb
227
232
  - spec/provisioning_profile_spec.rb