cocoapods 1.0.1 → 1.1.0.beta.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +107 -0
  3. data/lib/cocoapods/command.rb +1 -0
  4. data/lib/cocoapods/command/repo/push.rb +26 -5
  5. data/lib/cocoapods/command/setup.rb +2 -1
  6. data/lib/cocoapods/downloader.rb +20 -0
  7. data/lib/cocoapods/downloader/cache.rb +1 -0
  8. data/lib/cocoapods/gem_version.rb +1 -1
  9. data/lib/cocoapods/generator/acknowledgements/plist.rb +1 -0
  10. data/lib/cocoapods/generator/xcconfig/aggregate_xcconfig.rb +9 -2
  11. data/lib/cocoapods/generator/xcconfig/xcconfig_helper.rb +5 -4
  12. data/lib/cocoapods/installer.rb +41 -205
  13. data/lib/cocoapods/installer/analyzer.rb +65 -1
  14. data/lib/cocoapods/installer/analyzer/pod_variant.rb +9 -3
  15. data/lib/cocoapods/installer/analyzer/target_inspector.rb +24 -0
  16. data/lib/cocoapods/installer/user_project_integrator/target_integrator.rb +23 -6
  17. data/lib/cocoapods/installer/xcode.rb +7 -0
  18. data/lib/cocoapods/installer/xcode/pods_project_generator.rb +265 -0
  19. data/lib/cocoapods/installer/xcode/pods_project_generator/aggregate_target_installer.rb +202 -0
  20. data/lib/cocoapods/installer/xcode/pods_project_generator/file_references_installer.rb +314 -0
  21. data/lib/cocoapods/installer/xcode/pods_project_generator/pod_target_installer.rb +397 -0
  22. data/lib/cocoapods/installer/xcode/pods_project_generator/target_installer.rb +214 -0
  23. data/lib/cocoapods/resolver.rb +1 -2
  24. data/lib/cocoapods/target/aggregate_target.rb +19 -0
  25. data/lib/cocoapods/target/pod_target.rb +15 -2
  26. data/lib/cocoapods/user_interface.rb +6 -1
  27. data/lib/cocoapods/user_interface/error_report.rb +7 -0
  28. data/lib/cocoapods/user_interface/inspector_reporter.rb +109 -0
  29. data/lib/cocoapods/validator.rb +15 -7
  30. metadata +42 -19
  31. data/lib/cocoapods/installer/file_references_installer.rb +0 -310
  32. data/lib/cocoapods/installer/target_installer.rb +0 -210
  33. data/lib/cocoapods/installer/target_installer/aggregate_target_installer.rb +0 -191
  34. data/lib/cocoapods/installer/target_installer/pod_target_installer.rb +0 -389
@@ -0,0 +1,397 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Creates the target for the Pods libraries in the Pods project and the
6
+ # relative support files.
7
+ #
8
+ class PodTargetInstaller < TargetInstaller
9
+ # Creates the target in the Pods project and the relative support files.
10
+ #
11
+ # @return [void]
12
+ #
13
+ def install!
14
+ unless target.should_build?
15
+ add_resources_bundle_targets
16
+ return
17
+ end
18
+
19
+ UI.message "- Installing target `#{target.name}` #{target.platform}" do
20
+ add_target
21
+ create_support_files_dir
22
+ add_resources_bundle_targets
23
+ add_files_to_build_phases
24
+ create_xcconfig_file
25
+ if target.requires_frameworks?
26
+ create_info_plist_file
27
+ create_module_map
28
+ create_umbrella_header do |generator|
29
+ generator.imports += if header_mappings_dir
30
+ target.file_accessors.flat_map(&:public_headers).map do |pathname|
31
+ pathname.relative_path_from(header_mappings_dir)
32
+ end
33
+ else
34
+ target.file_accessors.flat_map(&:public_headers).map(&:basename)
35
+ end
36
+ end
37
+ create_build_phase_to_symlink_header_folders
38
+ end
39
+ create_prefix_header
40
+ create_dummy_source
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ # Remove the default headers folder path settings for static library pod
47
+ # targets.
48
+ #
49
+ # @return [Hash{String => String}]
50
+ #
51
+ def custom_build_settings
52
+ settings = super
53
+ unless target.requires_frameworks?
54
+ settings['PRIVATE_HEADERS_FOLDER_PATH'] = ''
55
+ settings['PUBLIC_HEADERS_FOLDER_PATH'] = ''
56
+ end
57
+ settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = ''
58
+ if target.swift_version
59
+ settings['SWIFT_VERSION'] = target.swift_version
60
+ end
61
+ settings
62
+ end
63
+
64
+ #-----------------------------------------------------------------------#
65
+
66
+ SOURCE_FILE_EXTENSIONS = Sandbox::FileAccessor::SOURCE_FILE_EXTENSIONS
67
+
68
+ # Adds the build files of the pods to the target and adds a reference to
69
+ # the frameworks of the Pods.
70
+ #
71
+ # @note The Frameworks are used only for presentation purposes as the
72
+ # xcconfig is the authoritative source about their information.
73
+ #
74
+ # @note Core Data model directories (.xcdatamodeld) defined in the `resources`
75
+ # property are currently added to the `Copy Resources` build phase like
76
+ # all other resources. The Xcode UI adds these to the `Compile Sources`
77
+ # build phase, but they will compile correctly either way.
78
+ #
79
+ # @return [void]
80
+ #
81
+ def add_files_to_build_phases
82
+ target.file_accessors.each do |file_accessor|
83
+ consumer = file_accessor.spec_consumer
84
+
85
+ headers = file_accessor.headers
86
+ public_headers = file_accessor.public_headers
87
+ private_headers = file_accessor.private_headers
88
+ other_source_files = file_accessor.source_files.reject { |sf| SOURCE_FILE_EXTENSIONS.include?(sf.extname) }
89
+
90
+ {
91
+ true => file_accessor.arc_source_files,
92
+ false => file_accessor.non_arc_source_files,
93
+ }.each do |arc, files|
94
+ files = files - headers - other_source_files
95
+ flags = compiler_flags_for_consumer(consumer, arc)
96
+ regular_file_refs = files.map { |sf| project.reference_for_path(sf) }
97
+ native_target.add_file_references(regular_file_refs, flags)
98
+ end
99
+
100
+ header_file_refs = headers.map { |sf| project.reference_for_path(sf) }
101
+ native_target.add_file_references(header_file_refs) do |build_file|
102
+ add_header(build_file, public_headers, private_headers)
103
+ end
104
+
105
+ other_file_refs = other_source_files.map { |sf| project.reference_for_path(sf) }
106
+ native_target.add_file_references(other_file_refs, nil)
107
+
108
+ next unless target.requires_frameworks?
109
+
110
+ resource_refs = file_accessor.resources.flatten.map do |res|
111
+ project.reference_for_path(res)
112
+ end
113
+
114
+ # Some nested files are not directly present in the Xcode project, such as the contents
115
+ # of an .xcdatamodeld directory. These files will return nil file references.
116
+ resource_refs.compact!
117
+
118
+ native_target.add_resources(resource_refs)
119
+ end
120
+ end
121
+
122
+ # Adds the resources of the Pods to the Pods project.
123
+ #
124
+ # @note The source files are grouped by Pod and in turn by subspec
125
+ # (recursively) in the resources group.
126
+ #
127
+ # @note Core Data model directories (.xcdatamodeld) are currently added to the
128
+ # `Copy Resources` build phase like all other resources. The Xcode UI adds
129
+ # these to the `Compile Sources` build phase, but they will compile
130
+ # correctly either way.
131
+ #
132
+ # @return [void]
133
+ #
134
+ def add_resources_bundle_targets
135
+ target.file_accessors.each do |file_accessor|
136
+ file_accessor.resource_bundles.each do |bundle_name, paths|
137
+ file_references = paths.map do |path|
138
+ ref = project.reference_for_path(path)
139
+
140
+ # Some nested files are not directly present in the Xcode project, such as the contents
141
+ # of an .xcdatamodeld directory. These files are implicitly included by including their
142
+ # parent directory.
143
+ next if ref.nil?
144
+
145
+ # For variant groups, the variant group itself is added, not its members.
146
+ next ref.parent if ref.parent.is_a?(Xcodeproj::Project::Object::PBXVariantGroup)
147
+
148
+ ref
149
+ end
150
+ file_references = file_references.uniq.compact
151
+
152
+ label = target.resources_bundle_target_label(bundle_name)
153
+ bundle_target = project.new_resources_bundle(label, file_accessor.spec_consumer.platform_name)
154
+ bundle_target.product_reference.tap do |bundle_product|
155
+ bundle_file_name = "#{bundle_name}.bundle"
156
+ bundle_product.name = bundle_file_name
157
+ bundle_product.path = bundle_file_name
158
+ end
159
+ bundle_target.add_resources(file_references)
160
+
161
+ target.user_build_configurations.each do |bc_name, type|
162
+ bundle_target.add_build_configuration(bc_name, type)
163
+ end
164
+ bundle_target.deployment_target = deployment_target
165
+
166
+ target.resource_bundle_targets << bundle_target
167
+
168
+ if target.should_build?
169
+ native_target.add_dependency(bundle_target)
170
+ if target.requires_frameworks?
171
+ native_target.add_resources([bundle_target.product_reference])
172
+ end
173
+ end
174
+
175
+ # Create Info.plist file for bundle
176
+ path = target.info_plist_path
177
+ path.dirname.mkdir unless path.dirname.exist?
178
+ info_plist_path = path.dirname + "ResourceBundle-#{bundle_name}-#{path.basename}"
179
+ generator = Generator::InfoPlistFile.new(target, :bundle_package_type => :bndl)
180
+ generator.save_as(info_plist_path)
181
+ add_file_to_support_group(info_plist_path)
182
+
183
+ bundle_target.build_configurations.each do |c|
184
+ c.build_settings['PRODUCT_NAME'] = bundle_name
185
+ relative_info_plist_path = info_plist_path.relative_path_from(sandbox.root)
186
+ c.build_settings['INFOPLIST_FILE'] = relative_info_plist_path.to_s
187
+ c.build_settings['CONFIGURATION_BUILD_DIR'] = target.configuration_build_dir('$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)')
188
+
189
+ # Set the correct device family for this bundle, based on the platform
190
+ device_family_by_platform = {
191
+ :ios => '1,2',
192
+ :tvos => '3',
193
+ :watchos => '1,2' # The device family for watchOS is 4, but Xcode creates watchkit-compatible bundles as 1,2
194
+ }
195
+
196
+ if family = device_family_by_platform[target.platform.name]
197
+ c.build_settings['TARGETED_DEVICE_FAMILY'] = family
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ # Generates the contents of the xcconfig file and saves it to disk.
205
+ #
206
+ # @return [void]
207
+ #
208
+ def create_xcconfig_file
209
+ path = target.xcconfig_path
210
+ xcconfig_gen = Generator::XCConfig::PodXCConfig.new(target)
211
+ xcconfig_gen.save_as(path)
212
+ xcconfig_file_ref = add_file_to_support_group(path)
213
+
214
+ native_target.build_configurations.each do |c|
215
+ c.base_configuration_reference = xcconfig_file_ref
216
+ end
217
+
218
+ # also apply the private config to resource targets
219
+ target.resource_bundle_targets.each do |rsrc_target|
220
+ rsrc_target.build_configurations.each do |rsrc_bc|
221
+ rsrc_bc.base_configuration_reference = xcconfig_file_ref
222
+ end
223
+ end
224
+ end
225
+
226
+ # Creates a build phase which links the versioned header folders
227
+ # of the OS X into the framework bundle's root root directory.
228
+ # This is only necessary because the way how headers are copied
229
+ # via custom copy file build phases in combination with
230
+ # header_mappings_dir interferes with xcodebuild's expectations
231
+ # about the existence of private or public headers.
232
+ #
233
+ # @return [void]
234
+ #
235
+ def create_build_phase_to_symlink_header_folders
236
+ return unless target.platform.name == :osx && header_mappings_dir
237
+
238
+ build_phase = native_target.new_shell_script_build_phase('Create Symlinks to Header Folders')
239
+ build_phase.shell_script = <<-eos.strip_heredoc
240
+ cd "$CONFIGURATION_BUILD_DIR/$WRAPPER_NAME"
241
+ ln -fs ${PUBLIC_HEADERS_FOLDER_PATH\#$WRAPPER_NAME/} ${PUBLIC_HEADERS_FOLDER_PATH\#\$CONTENTS_FOLDER_PATH/}
242
+ ln -fs ${PRIVATE_HEADERS_FOLDER_PATH\#\$WRAPPER_NAME/} ${PRIVATE_HEADERS_FOLDER_PATH\#\$CONTENTS_FOLDER_PATH/}
243
+ eos
244
+ end
245
+
246
+ # Creates a prefix header file which imports `UIKit` or `Cocoa` according
247
+ # to the platform of the target. This file also include any prefix header
248
+ # content reported by the specification of the pods.
249
+ #
250
+ # @return [void]
251
+ #
252
+ def create_prefix_header
253
+ path = target.prefix_header_path
254
+ generator = Generator::PrefixHeader.new(target.file_accessors, target.platform)
255
+ generator.save_as(path)
256
+ add_file_to_support_group(path)
257
+
258
+ native_target.build_configurations.each do |c|
259
+ relative_path = path.relative_path_from(project.path.dirname)
260
+ c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
261
+ end
262
+ end
263
+
264
+ ENABLE_OBJECT_USE_OBJC_FROM = {
265
+ :ios => Version.new('6'),
266
+ :osx => Version.new('10.8'),
267
+ :watchos => Version.new('2.0'),
268
+ :tvos => Version.new('9.0'),
269
+ }
270
+
271
+ # Returns the compiler flags for the source files of the given specification.
272
+ #
273
+ # The following behavior is regarding the `OS_OBJECT_USE_OBJC` flag. When
274
+ # set to `0`, it will allow code to use `dispatch_release()` on >= iOS 6.0
275
+ # and OS X 10.8.
276
+ #
277
+ # * New libraries that do *not* require ARC don’t need to care about this
278
+ # issue at all.
279
+ #
280
+ # * New libraries that *do* require ARC _and_ have a deployment target of
281
+ # >= iOS 6.0 or OS X 10.8:
282
+ #
283
+ # These no longer use `dispatch_release()` and should *not* have the
284
+ # `OS_OBJECT_USE_OBJC` flag set to `0`.
285
+ #
286
+ # **Note:** this means that these libraries *have* to specify the
287
+ # deployment target in order to function well.
288
+ #
289
+ # * New libraries that *do* require ARC, but have a deployment target of
290
+ # < iOS 6.0 or OS X 10.8:
291
+ #
292
+ # These contain `dispatch_release()` calls and as such need the
293
+ # `OS_OBJECT_USE_OBJC` flag set to `1`.
294
+ #
295
+ # **Note:** libraries that do *not* specify a platform version are
296
+ # assumed to have a deployment target of < iOS 6.0 or OS X 10.8.
297
+ #
298
+ # For more information, see: http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
299
+ #
300
+ # @param [Specification::Consumer] consumer
301
+ # The consumer for the specification for which the compiler flags
302
+ # are needed.
303
+ #
304
+ # @return [String] The compiler flags.
305
+ #
306
+ def compiler_flags_for_consumer(consumer, arc)
307
+ flags = consumer.compiler_flags.dup
308
+ if !arc
309
+ flags << '-fno-objc-arc'
310
+ else
311
+ platform_name = consumer.platform_name
312
+ spec_deployment_target = consumer.spec.deployment_target(platform_name)
313
+ if spec_deployment_target.nil? || Version.new(spec_deployment_target) < ENABLE_OBJECT_USE_OBJC_FROM[platform_name]
314
+ flags << '-DOS_OBJECT_USE_OBJC=0'
315
+ end
316
+ end
317
+ if target.inhibit_warnings?
318
+ flags << '-w -Xanalyzer -analyzer-disable-all-checks'
319
+ end
320
+ flags * ' '
321
+ end
322
+
323
+ # Adds a reference to the given file in the support group of this target.
324
+ #
325
+ # @param [Pathname] path
326
+ # The path of the file to which the reference should be added.
327
+ #
328
+ # @return [PBXFileReference] the file reference of the added file.
329
+ #
330
+ def add_file_to_support_group(path)
331
+ pod_name = target.pod_name
332
+ dir = target.support_files_dir
333
+ group = project.pod_support_files_group(pod_name, dir)
334
+ group.new_file(path)
335
+ end
336
+
337
+ def create_module_map
338
+ return super unless custom_module_map
339
+ path = target.module_map_path
340
+ UI.message "- Copying module map file to #{UI.path(path)}" do
341
+ FileUtils.cp(custom_module_map, path)
342
+ add_file_to_support_group(path)
343
+
344
+ native_target.build_configurations.each do |c|
345
+ relative_path = path.relative_path_from(sandbox.root)
346
+ c.build_settings['MODULEMAP_FILE'] = relative_path.to_s
347
+ end
348
+ end
349
+ end
350
+
351
+ def create_umbrella_header
352
+ return super unless custom_module_map
353
+ end
354
+
355
+ def custom_module_map
356
+ @custom_module_map ||= target.file_accessors.first.module_map
357
+ end
358
+
359
+ def header_mappings_dir
360
+ return @header_mappings_dir if defined?(@header_mappings_dir)
361
+ file_accessor = target.file_accessors.first
362
+ @header_mappings_dir = if dir = file_accessor.spec_consumer.header_mappings_dir
363
+ file_accessor.path_list.root + dir
364
+ end
365
+ end
366
+
367
+ def add_header(build_file, public_headers, private_headers)
368
+ file_ref = build_file.file_ref
369
+ acl = if public_headers.include?(file_ref.real_path)
370
+ 'Public'
371
+ elsif private_headers.include?(file_ref.real_path)
372
+ 'Private'
373
+ else
374
+ 'Project'
375
+ end
376
+
377
+ if target.requires_frameworks? && header_mappings_dir && acl != 'Project'
378
+ relative_path = file_ref.real_path.relative_path_from(header_mappings_dir)
379
+ sub_dir = relative_path.dirname
380
+ copy_phase_name = "Copy #{sub_dir} #{acl} Headers"
381
+ copy_phase = native_target.copy_files_build_phases.find { |bp| bp.name == copy_phase_name } ||
382
+ native_target.new_copy_files_build_phase(copy_phase_name)
383
+ copy_phase.symbol_dst_subfolder_spec = :products_directory
384
+ copy_phase.dst_path = "$(#{acl.upcase}_HEADERS_FOLDER_PATH)/#{sub_dir}"
385
+ copy_phase.add_file_reference(file_ref, true)
386
+ else
387
+ build_file.settings ||= {}
388
+ build_file.settings['ATTRIBUTES'] = [acl]
389
+ end
390
+ end
391
+
392
+ #-----------------------------------------------------------------------#
393
+ end
394
+ end
395
+ end
396
+ end
397
+ end
@@ -0,0 +1,214 @@
1
+ module Pod
2
+ class Installer
3
+ class Xcode
4
+ class PodsProjectGenerator
5
+ # Controller class responsible of creating and configuring the static
6
+ # library target in Pods project. It also creates the support file needed
7
+ # by the target.
8
+ #
9
+ class TargetInstaller
10
+ # @return [Sandbox] sandbox the sandbox where the support files should
11
+ # be generated.
12
+ #
13
+ attr_reader :sandbox
14
+
15
+ # @return [Target] The library whose target needs to be generated.
16
+ #
17
+ attr_reader :target
18
+
19
+ # @param [Project] project @see project
20
+ # @param [Target] target @see target
21
+ #
22
+ def initialize(sandbox, target)
23
+ @sandbox = sandbox
24
+ @target = target
25
+ end
26
+
27
+ private
28
+
29
+ #-----------------------------------------------------------------------#
30
+
31
+ # @!group Installation steps
32
+
33
+ # Adds the target for the library to the Pods project with the
34
+ # appropriate build configurations.
35
+ #
36
+ # @note The `PODS_HEADERS_SEARCH_PATHS` overrides the xcconfig.
37
+ #
38
+ # @return [void]
39
+ #
40
+ def add_target
41
+ product_type = target.product_type
42
+ name = target.label
43
+ platform = target.platform.name
44
+ language = target.uses_swift? ? :swift : :objc
45
+ @native_target = project.new_target(product_type, name, platform, deployment_target, nil, language)
46
+
47
+ product_name = target.product_name
48
+ product = @native_target.product_reference
49
+ product.name = product_name
50
+
51
+ target.user_build_configurations.each do |bc_name, type|
52
+ @native_target.add_build_configuration(bc_name, type)
53
+ end
54
+
55
+ @native_target.build_configurations.each do |configuration|
56
+ configuration.build_settings.merge!(custom_build_settings)
57
+ end
58
+
59
+ target.native_target = @native_target
60
+ end
61
+
62
+ # @return [String] The deployment target.
63
+ #
64
+ def deployment_target
65
+ target.platform.deployment_target.to_s
66
+ end
67
+
68
+ # Returns the customized build settings which are overridden in the build
69
+ # settings of the user target.
70
+ #
71
+ # @return [Hash{String => String}]
72
+ #
73
+ def custom_build_settings
74
+ settings = {}
75
+
76
+ unless target.archs.empty?
77
+ settings['ARCHS'] = target.archs
78
+ end
79
+
80
+ if target.requires_frameworks?
81
+ settings['PRODUCT_NAME'] = target.product_module_name
82
+ else
83
+ settings.merge!('OTHER_LDFLAGS' => '', 'OTHER_LIBTOOLFLAGS' => '')
84
+ end
85
+
86
+ settings
87
+ end
88
+
89
+ # Creates the directory where to store the support files of the target.
90
+ #
91
+ def create_support_files_dir
92
+ target.support_files_dir.mkdir
93
+ end
94
+
95
+ # Creates the Info.plist file which sets public framework attributes
96
+ #
97
+ # @return [void]
98
+ #
99
+ def create_info_plist_file
100
+ path = target.info_plist_path
101
+ UI.message "- Generating Info.plist file at #{UI.path(path)}" do
102
+ generator = Generator::InfoPlistFile.new(target)
103
+ generator.save_as(path)
104
+ add_file_to_support_group(path)
105
+
106
+ native_target.build_configurations.each do |c|
107
+ relative_path = path.relative_path_from(sandbox.root)
108
+ c.build_settings['INFOPLIST_FILE'] = relative_path.to_s
109
+ end
110
+ end
111
+ end
112
+
113
+ # Creates the module map file which ensures that the umbrella header is
114
+ # recognized with a customized path
115
+ #
116
+ # @yield_param [Generator::ModuleMap]
117
+ # yielded once to configure the private headers
118
+ #
119
+ # @return [void]
120
+ #
121
+ def create_module_map
122
+ path = target.module_map_path
123
+ UI.message "- Generating module map file at #{UI.path(path)}" do
124
+ generator = Generator::ModuleMap.new(target)
125
+ yield generator if block_given?
126
+ generator.save_as(path)
127
+ add_file_to_support_group(path)
128
+
129
+ native_target.build_configurations.each do |c|
130
+ relative_path = path.relative_path_from(sandbox.root)
131
+ c.build_settings['MODULEMAP_FILE'] = relative_path.to_s
132
+ end
133
+ end
134
+ end
135
+
136
+ # Generates a header which ensures that all header files are exported
137
+ # in the module map
138
+ #
139
+ # @yield_param [Generator::UmbrellaHeader]
140
+ # yielded once to configure the imports
141
+ #
142
+ def create_umbrella_header
143
+ path = target.umbrella_header_path
144
+ UI.message "- Generating umbrella header at #{UI.path(path)}" do
145
+ generator = Generator::UmbrellaHeader.new(target)
146
+ yield generator if block_given?
147
+ generator.save_as(path)
148
+
149
+ # Add the file to the support group and the native target,
150
+ # so it will been added to the header build phase
151
+ file_ref = add_file_to_support_group(path)
152
+ native_target.add_file_references([file_ref])
153
+
154
+ # Make the umbrella header public
155
+ build_file = native_target.headers_build_phase.build_file(file_ref)
156
+ build_file.settings ||= {}
157
+ build_file.settings['ATTRIBUTES'] = ['Public']
158
+ end
159
+ end
160
+
161
+ # Generates a dummy source file for each target so libraries that contain
162
+ # only categories build.
163
+ #
164
+ # @return [void]
165
+ #
166
+ def create_dummy_source
167
+ path = target.dummy_source_path
168
+ generator = Generator::DummySource.new(target.label)
169
+ generator.save_as(path)
170
+ file_reference = add_file_to_support_group(path)
171
+ native_target.source_build_phase.add_file_reference(file_reference)
172
+ end
173
+
174
+ # @return [PBXNativeTarget] the target generated by the installation
175
+ # process.
176
+ #
177
+ # @note Generated by the {#add_target} step.
178
+ #
179
+ attr_reader :native_target
180
+
181
+ private
182
+
183
+ #-----------------------------------------------------------------------#
184
+
185
+ # @!group Private helpers.
186
+
187
+ # @return [Project] the Pods project of the sandbox.
188
+ #
189
+ def project
190
+ sandbox.project
191
+ end
192
+
193
+ # @return [PBXGroup] the group where the file references to the support
194
+ # files should be stored.
195
+ #
196
+ attr_reader :support_files_group
197
+
198
+ # Adds a reference to the given file in the support group of this target.
199
+ #
200
+ # @param [Pathname] path
201
+ # The path of the file to which the reference should be added.
202
+ #
203
+ # @return [PBXFileReference] the file reference of the added file.
204
+ #
205
+ def add_file_to_support_group(path)
206
+ support_files_group.new_file(path)
207
+ end
208
+
209
+ #-----------------------------------------------------------------------#
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end