Commit 70909db3 authored by Fabio Pelosin's avatar Fabio Pelosin

[TargetInstaller] Extracted XCConfig generation to Generator::XCConfing.

parent 6736afe4
...@@ -46,6 +46,7 @@ module Pod ...@@ -46,6 +46,7 @@ module Pod
autoload :Markdown, 'cocoapods/generator/acknowledgements/markdown' autoload :Markdown, 'cocoapods/generator/acknowledgements/markdown'
autoload :DummySource, 'cocoapods/generator/dummy_source' autoload :DummySource, 'cocoapods/generator/dummy_source'
autoload :PrefixHeader, 'cocoapods/generator/prefix_header' autoload :PrefixHeader, 'cocoapods/generator/prefix_header'
autoload :XCConfig, 'cocoapods/generator/xcconfig'
end end
require 'cocoapods/file_list' require 'cocoapods/file_list'
......
module Pod
module Generator
# Generates an xcconfig file for each target of the Pods project. The
# configuration file should be used by the user target as well.
#
class XCConfig
# @return [Sandbox] the sandbox where the Pods project is installed.
#
attr_reader :sandbox
# @return [Array<LocalPod>] the list of LocalPods for the library.
#
attr_reader :pods
# @return [String] the relative path of the Pods root respect the user
# project that should be integrated by this library.
#
attr_reader :relative_pods_root
# @param [Platform] platform @see platform
#
# @param [Array<LocalPod>] @see pods
#
def initialize(sandbox, pods, relative_pods_root)
@sandbox = sandbox
@pods = pods
@relative_pods_root = relative_pods_root
end
# @return [Bool] whether the Podfile specifies to add the `-fobjc-arc`
# flag for compatibility.
#
attr_accessor :set_arc_compatibility_flag
#-----------------------------------------------------------------------#
# Generates the xcconfig for the library.
#
# @return [Xcodeproj::Config]
#
def generate
ld_flags = '-ObjC'
if set_arc_compatibility_flag && pods.any? { |pod| pod.requires_arc? }
ld_flags << ' -fobjc-arc'
end
@xcconfig = Xcodeproj::Config.new({
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'HEADER_SEARCH_PATHS' => '${PODS_HEADERS_SEARCH_PATHS}',
'PODS_ROOT' => relative_pods_root,
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quote(sandbox.build_headers.search_paths),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(sandbox.public_headers.search_paths),
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_PUBLIC_HEADERS_SEARCH_PATHS}'
})
pods.each { |pod| @xcconfig.merge!(pod.xcconfig) }
@xcconfig
end
# @return [Xcodeproj::Config] The generated xcconfig.
#
attr_reader :xcconfig
# @return [Hash] The settings of the xcconfig that the Pods project
# needs to override.
#
def self.pods_project_settings
{ 'PODS_ROOT' => '${SRCROOT}',
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_BUILD_HEADERS_SEARCH_PATHS}' }
end
# Generates and saves the xcconfig to the given path.
#
# @param [Pathname] path
# the path where the prefix header should be stored.
#
# @return [void]
#
def save_as(path)
path.open('w') { |file| file.write(generate) }
end
#-----------------------------------------------------------------------#
# @!group Private helpers.
private
# @return [String] the default linker flags. `-ObjC` is always included
# while `-fobjc-arc` is included only if requested in the
# Podfile.
#
def default_ld_flags
flags = %w[ -ObjC ]
requires_arc = pods.any? { |pod| pod.requires_arc? }
if requires_arc && set_arc_compatibility_flag
flags << '-fobjc-arc'
end
flags.join(" ")
end
# Converts an array of strings to a single string where the each string
# is surrounded by double quotes and separated by a space. Used to
# represent strings in a xcconfig file.
#
# @param [Array<String>] strings
# a list of strings.
#
# @return [String] the resulting string.
#
def quote(strings)
strings.map { |s| %W|"#{s}"| }.join(" ")
end
end
end
end
...@@ -17,16 +17,19 @@ module Pod ...@@ -17,16 +17,19 @@ module Pod
def project def project
return @project if @project return @project if @project
@project = Pod::Project.new @project = Pod::Project.new(sandbox)
@project.user_build_configurations = @podfile.user_build_configurations # TODO
# @project.user_build_configurations = @podfile.user_build_configurations
pods.each { |p| p.add_file_references_to_project(@project) } pods.each { |p| p.add_file_references_to_project(@project) }
pods.each { |p| p.link_headers } pods.each { |p| p.link_headers }
@project.add_podfile(config.project_podfile)
@project @project
end end
def target_installers def target_installers
@target_installers ||= @podfile.target_definitions.values.map do |definition| @target_installers ||= @podfile.target_definitions.values.map do |definition|
TargetInstaller.new(@podfile, project, definition) unless definition.empty? pods_for_target = pods_by_target[definition]
TargetInstaller.new(project, definition, pods_for_target) unless definition.empty?
end.compact end.compact
end end
......
...@@ -47,7 +47,7 @@ module Pod ...@@ -47,7 +47,7 @@ module Pod
create_copy_resources_script create_copy_resources_script
end end
# TODO This has to be removed, but this means the specs have to be # TODO: This has to be removed, but this means the specs have to be
# updated if they need a reference to the prefix header. # updated if they need a reference to the prefix header.
# #
def prefix_header_filename def prefix_header_filename
...@@ -97,13 +97,16 @@ module Pod ...@@ -97,13 +97,16 @@ module Pod
# @return [void] # @return [void]
# #
def configure_target def configure_target
set = {} set = {
set['OTHER_LDFLAGS'] = '' 'GCC_PREFIX_HEADER' => library.prefix_header_name
set['GCC_PREFIX_HEADER'] = library.prefix_header_name }
set['PODS_ROOT'] = '${SRCROOT}' if @target_definition.inhibit_all_warnings?
set['PODS_HEADERS_SEARCH_PATHS'] = '${PODS_BUILD_HEADERS_SEARCH_PATHS}' set['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
set['GCC_WARN_INHIBIT_ALL_WARNINGS'] = end
@target_definition.inhibit_all_warnings? ? 'YES' : 'NO'
Generator::XCConfig.pods_project_settings.each do |key, value|
set[key] = value
end
@target.build_configurations.each do |c| @target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref c.base_configuration_reference = xcconfig_file_ref
...@@ -120,18 +123,10 @@ module Pod ...@@ -120,18 +123,10 @@ module Pod
# #
def create_xcconfig_file def create_xcconfig_file
UI.message "- Generating xcconfig file at #{UI.path(library.xcconfig_path)}" do UI.message "- Generating xcconfig file at #{UI.path(library.xcconfig_path)}" do
xcconfig = Xcodeproj::Config.new({ gen = Generator::XCConfig.new(sandbox, pods, library.relative_pods_root)
'ALWAYS_SEARCH_USER_PATHS' => 'YES', gen.set_arc_compatibility_flag = target_definition.podfile.set_arc_compatibility_flag?
'OTHER_LDFLAGS' => default_ld_flags, gen.save_as(library.xcconfig_path)
'HEADER_SEARCH_PATHS' => '${PODS_HEADERS_SEARCH_PATHS}', library.xcconfig = gen.xcconfig
'PODS_ROOT' => library.relative_pods_root,
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quote(sandbox.build_headers.search_paths),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(sandbox.public_headers.search_paths),
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_PUBLIC_HEADERS_SEARCH_PATHS}'
})
pods.each { |pod| xcconfig.merge!(pod.xcconfig) }
xcconfig.save_as(library.xcconfig_path)
library.xcconfig = xcconfig
end end
end end
...@@ -150,9 +145,11 @@ module Pod ...@@ -150,9 +145,11 @@ module Pod
# Generates the bridge support metadata if requested by the {Podfile}. # Generates the bridge support metadata if requested by the {Podfile}.
# #
# @return [void] # @note the bridge support metadata is added to the resources of the
# library because it is needed for environments interpreted at
# runtime.
# #
# TODO: Why is this added to the copy resources script? # @return [void]
# #
def create_bridge_support_file def create_bridge_support_file
if target_definition.podfile.generate_bridge_support? if target_definition.podfile.generate_bridge_support?
...@@ -223,37 +220,9 @@ module Pod ...@@ -223,37 +220,9 @@ module Pod
# #
# @return [CopyResourcesScript] # @return [CopyResourcesScript]
# #
# TODO: This should be replaced by an Xcode copy resources build phase.
#
def copy_resources_script def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new @copy_resources_script ||= Generator::CopyResourcesScript.new
end end
# Converts an array of strings to a single string where the each string
# is surrounded by double quotes and separated by a space. Used to
# represent strings in a xcconfig file.
#
# @param [Array<String>] strings
# a list of strings.
#
# @return [String] the resulting string.
#
def quote(strings)
strings.map { |s| %W|"#{s}"| }.join(" ")
end
# @return [String] the default linker flags. `-ObjC` is always included
# while `-fobjc-arc` is included only if requested in the
# Podfile.
#
def default_ld_flags
flags = %w[ -ObjC ]
requires_arc = pods.any? { |pod| pod.requires_arc? }
if requires_arc && target_definition.podfile.set_arc_compatibility_flag?
flags << '-fobjc-arc'
end
flags.join(" ")
end
end end
end end
end end
......
...@@ -91,7 +91,7 @@ module Pod ...@@ -91,7 +91,7 @@ module Pod
# @return [PBXFileReference] # @return [PBXFileReference]
# #
def add_podfile(podfile_path) def add_podfile(podfile_path)
podfile_path = Pathname.new(podfile_path.to_s) podfile_path = Pathname.new(podfile_path)
podfile_ref = new_file(podfile_path.relative_path_from(path.dirname)) podfile_ref = new_file(podfile_path.relative_path_from(path.dirname))
podfile_ref.xc_language_specification_identifier = 'xcode.lang.ruby' podfile_ref.xc_language_specification_identifier = 'xcode.lang.ruby'
podfile_ref podfile_ref
......
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
describe Generator::XCConfig do
before do
specification = fixture_spec('banana-lib/BananaLib.podspec')
@pod = Pod::LocalPod.new(specification, config.sandbox, :ios)
@generator = Generator::XCConfig.new(config.sandbox, [@pod], './Pods')
end
it "returns the sandbox" do
@generator.sandbox.class.should == Sandbox
end
it "returns the pods" do
@generator.pods.should == [@pod]
end
it "returns the path of the pods root relative to the user project" do
@generator.relative_pods_root.should == './Pods'
end
#-----------------------------------------------------------------------#
before do
@xcconfig = @generator.generate
end
it "generates the xcconfig" do
@xcconfig.class.should == Xcodeproj::Config
end
it 'adds the sandbox header search paths to the xcconfig, with quotes' do
@xcconfig.to_hash['PODS_BUILD_HEADERS_SEARCH_PATHS'].should.include("\"#{config.sandbox.build_headers.search_paths.join('" "')}\"")
end
it 'does not add the -fobjc-arc to OTHER_LDFLAGS by default as Xcode 4.3.2 does not support it' do
@xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.not.include("-fobjc-arc")
end
it 'adds the -fobjc-arc to OTHER_LDFLAGS if any pods require arc (to support non-ARC projects on iOS 4.0)' do
@generator.set_arc_compatibility_flag = true
@pod.top_specification.stubs(:requires_arc).returns(true)
@xcconfig = @generator.generate
@xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.include("-fobjc-arc")
end
#-----------------------------------------------------------------------#
it 'returns the settings that the pods project needs to override' do
Generator::XCConfig.pods_project_settings.should.not.be.nil
end
it 'overrides the relative path of the pods root in the Pods project' do
Generator::XCConfig.pods_project_settings['PODS_ROOT'].should == '${SRCROOT}'
end
it 'overrides the headers search path of the pods project to the build headers folder' do
expected = '${PODS_BUILD_HEADERS_SEARCH_PATHS}'
Generator::XCConfig.pods_project_settings['PODS_HEADERS_SEARCH_PATHS'].should == expected
end
#-----------------------------------------------------------------------#
extend SpecHelper::TemporaryDirectory
it "saves the xcconfig" do
path = temporary_directory + 'sample.xcconfig'
@generator.save_as(path)
generated = Xcodeproj::Config.new(path)
generated.class.should == Xcodeproj::Config
end
end
end
...@@ -74,33 +74,25 @@ describe TargetInstaller = Pod::Installer::TargetInstaller do ...@@ -74,33 +74,25 @@ describe TargetInstaller = Pod::Installer::TargetInstaller do
#--------------------------------------# #--------------------------------------#
it "adds the user's build configurations to the target" do it "adds the settings of the xcconfig that need to be overridden to the target" do
@project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
do_install! do_install!
@project.targets.first.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test } build_configuration = @project.targets.first.build_configurations
build_settings = build_configuration.first.build_settings
Pod::Generator::XCConfig.pods_project_settings.each do |key, value|
build_settings[key].should == value
end end
it 'adds the sandbox header search paths to the xcconfig, with quotes' do
do_install!
@installer.library.xcconfig.to_hash['PODS_BUILD_HEADERS_SEARCH_PATHS'].should.include("\"#{config.sandbox.build_headers.search_paths.join('" "')}\"")
end end
it 'does not add the -fobjc-arc to OTHER_LDFLAGS by default as Xcode 4.3.2 does not support it' do it "adds the user's build configurations to the target" do
do_install! @project.user_build_configurations = { 'Debug' => :debug, 'Release' => :release, 'AppStore' => :release, 'Test' => :debug }
@installer.library.xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.not.include("-fobjc-arc")
end
it 'adds the -fobjc-arc to OTHER_LDFLAGS if any pods require arc (to support non-ARC projects on iOS 4.0)' do
Pod::Podfile.any_instance.stubs(:set_arc_compatibility_flag? => true)
@pod.top_specification.stubs(:requires_arc).returns(true)
do_install! do_install!
@installer.library.xcconfig.to_hash['OTHER_LDFLAGS'].split(" ").should.include("-fobjc-arc") @project.targets.first.build_configurations.map(&:name).sort.should == %w{ AppStore Debug Release Test }
end end
it "does not enable the GCC_WARN_INHIBIT_ALL_WARNINGS flag by default" do it "does not enable the GCC_WARN_INHIBIT_ALL_WARNINGS flag by default" do
do_install! do_install!
@installer.target.build_configurations.each do |config| @installer.target.build_configurations.each do |config|
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should == 'NO' config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'].should.be.nil
end end
end end
......
require File.expand_path('../../spec_helper', __FILE__) require File.expand_path('../../spec_helper', __FILE__)
# it 'tells each pod to link its headers' do
# @pods[0].expects(:link_headers)
# do_install!
# end
module Pod module Pod
describe Installer do describe Installer do
before do before do
...@@ -21,7 +27,7 @@ module Pod ...@@ -21,7 +27,7 @@ module Pod
resolver = Resolver.new(podfile, nil, @sandbox) resolver = Resolver.new(podfile, nil, @sandbox)
@installer = Installer.new(resolver) @installer = Installer.new(resolver)
target_installer = @installer.target_installers.first target_installer = @installer.target_installers.first
target_installer.generate_xcconfig([], @sandbox) target_installer.install
@xcconfig = target_installer.xcconfig.to_hash @xcconfig = target_installer.xcconfig.to_hash
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment