Commit 3ff30dc6 authored by Marius Rackwitz's avatar Marius Rackwitz

[XCConfig] Collapse public and private pod xcconfig

parent 3424bef1
......@@ -6,8 +6,7 @@ module Pod
#
module XCConfig
autoload :AggregateXCConfig, 'cocoapods/generator/xcconfig/aggregate_xcconfig'
autoload :PublicPodXCConfig, 'cocoapods/generator/xcconfig/public_pod_xcconfig'
autoload :PrivatePodXCConfig, 'cocoapods/generator/xcconfig/private_pod_xcconfig'
autoload :PodXCConfig, 'cocoapods/generator/xcconfig/pod_xcconfig'
autoload :XCConfigHelper, 'cocoapods/generator/xcconfig/xcconfig_helper'
end
end
......
......@@ -3,28 +3,21 @@ module Pod
module XCConfig
# Generates the private xcconfigs for the pod targets.
#
# The private xcconfig file for a Pod target merges the configuration
# values of the public namespaced xcconfig with the default private
# configuration values required by CocoaPods.
# The xcconfig file for a Pod target merges the pod target
# configuration values with the default configuration values
# required by CocoaPods.
#
class PrivatePodXCConfig
class PodXCConfig
# @return [Target] the target represented by this xcconfig.
#
attr_reader :target
# @return [Xcodeproj::Config] The public xcconfig which this one will
# use.
#
attr_reader :public_xcconfig
# Initialize a new instance
#
# @param [Target] target @see target
# @param [Xcodeproj::Config] public_xcconfig @see public_xcconfig
#
def initialize(target, public_xcconfig)
def initialize(target)
@target = target
@public_xcconfig = public_xcconfig
end
# @return [Xcodeproj::Config] The generated xcconfig.
......@@ -71,60 +64,12 @@ module Pod
config.merge!(build_settings)
end
xcconfig_hash = add_xcconfig_namespaced_keys(public_xcconfig.to_hash, config, target.xcconfig_prefix)
@xcconfig = Xcodeproj::Config.new(xcconfig_hash)
@xcconfig = Xcodeproj::Config.new(config)
XCConfigHelper.add_settings_for_file_accessors_of_target(target, @xcconfig)
XCConfigHelper.add_target_specific_settings(target, @xcconfig)
@xcconfig.includes = [target.name]
@xcconfig
end
private
#-----------------------------------------------------------------------#
# !@group Private Helpers
# Returns the hash representation of an xcconfig which inherit from the
# namespaced keys of a given one.
#
# @param [Hash] source_config
# The xcconfig whose keys need to be inherited.
#
# @param [Hash] destination_config
# The config which should inherit the source config keys.
#
# @return [Hash] The inheriting xcconfig.
#
def add_xcconfig_namespaced_keys(source_config, destination_config, prefix)
result = destination_config.dup
source_config.each do |key, _value|
prefixed_key = prefix + conditional_less_key(key)
current_value = destination_config[key]
if current_value
result[key] = "#{current_value} ${#{prefixed_key}}"
else
result[key] = "${#{prefixed_key}}"
end
end
result
end
# Strips the [*]-syntax from the given xcconfig key.
#
# @param [String] key
# The key to strip.
#
# @return [String] The stripped key.
#
def conditional_less_key(key)
brackets_index = key.index('[')
if brackets_index
key[0...brackets_index]
else
key
end
end
#-----------------------------------------------------------------------#
end
end
......
module Pod
module Generator
module XCConfig
# Generates the public xcconfigs for the pod targets.
#
# The public xcconfig file for a Pod is completely namespaced to prevent
# configuration value collision with the build settings of other Pods. This
# xcconfig includes the standard podspec defined values including
# libraries, frameworks, weak frameworks and xcconfig overrides.
#
class PublicPodXCConfig
# @return [Target] the target represented by this xcconfig.
#
attr_reader :target
# Initialize a new instance
#
# @param [Target] target @see target
#
def initialize(target)
@target = target
end
# @return [Xcodeproj::Config] The generated xcconfig.
#
attr_reader :xcconfig
# 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)
generate.save_as(path, target.xcconfig_prefix)
end
# Generates the xcconfig for the target.
#
# @return [Xcodeproj::Config]
#
def generate
@xcconfig = Xcodeproj::Config.new
XCConfigHelper.add_settings_for_file_accessors_of_target(target, @xcconfig)
@xcconfig
end
#-----------------------------------------------------------------------#
end
end
end
end
......@@ -163,13 +163,8 @@ module Pod
#
def create_xcconfig_file
path = target.xcconfig_path
public_gen = Generator::XCConfig::PublicPodXCConfig.new(target)
public_gen.save_as(path)
add_file_to_support_group(path)
path = target.xcconfig_private_path
private_gen = Generator::XCConfig::PrivatePodXCConfig.new(target, public_gen.xcconfig)
private_gen.save_as(path)
xcconfig_gen = Generator::XCConfig::PodXCConfig.new(target)
xcconfig_gen.save_as(path)
xcconfig_file_ref = add_file_to_support_group(path)
native_target.build_configurations.each do |c|
......
......@@ -75,12 +75,6 @@ module Pod
requires_frameworks? ? :framework : :static_library
end
# @return [String] the XCConfig namespaced prefix.
#
def xcconfig_prefix
label.upcase.gsub(/[^A-Z]/, '_') + '_'
end
# @return [String] A string suitable for debugging.
#
def inspect
......@@ -140,12 +134,6 @@ module Pod
end
end
# @return [Pathname] the absolute path of the private xcconfig file.
#
def xcconfig_private_path
support_files_dir + "#{label}-Private.xcconfig"
end
# @return [Pathname] the absolute path of the header file which contains
# the exported foundation constants with framework version
# information and all headers, which should been exported in the
......
......@@ -3,15 +3,25 @@ require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
module Generator
module XCConfig
describe PrivatePodXCConfig do
describe PodXCConfig do
describe 'in general' do
before do
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@pod_target = fixture_pod_target(@spec)
@consumer = @pod_target.spec_consumers.first
@podfile = @pod_target.podfile
public_xcconfig = Xcodeproj::Config.new('OTHER_LDFLAGS' => '-framework SystemConfiguration')
@generator = PrivatePodXCConfig.new(@pod_target, public_xcconfig)
@generator = PodXCConfig.new(@pod_target)
@spec.xcconfig = { 'OTHER_LDFLAGS' => '-no_compact_unwind' }
@spec.frameworks = ['QuartzCore']
@spec.weak_frameworks = ['iAd']
@spec.libraries = ['xml2']
file_accessors = [Sandbox::FileAccessor.new(fixture('banana-lib'), @consumer)]
# vendored_framework_paths = [config.sandbox.root + 'BananaLib/BananaLib.framework']
# Sandbox::FileAccessor.any_instance.stubs(:vendored_frameworks).returns(vendored_framework_paths)
@pod_target.stubs(:file_accessors).returns(file_accessors)
@xcconfig = @generator.generate
end
......@@ -19,6 +29,30 @@ module Pod
@xcconfig.class.should == Xcodeproj::Config
end
it 'includes the xcconfig of the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-no_compact_unwind')
end
it 'includes the libraries for the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-l"xml2"')
end
it 'includes the frameworks of the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-framework "QuartzCore"')
end
it 'includes the weak-frameworks of the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-weak_framework "iAd"')
end
it 'includes the developer frameworks search paths when SenTestingKit is detected' do
@spec.xcconfig = { 'OTHER_LDFLAGS' => '-no_compact_unwind' }
@spec.frameworks = ['SenTestingKit']
xcconfig = @generator.generate
framework_search_paths = xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS']
framework_search_paths.should.include('$(SDKROOT)/Developer')
end
it 'does not configure the project to load all members that implement Objective-c classes or categories from the static library' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.not.include '-ObjC'
end
......@@ -51,10 +85,6 @@ module Pod
@xcconfig.to_hash['GCC_PREPROCESSOR_DEFINITIONS'].should == expected
end
it 'adds the pod namespaced configuration items' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include("${#{@pod_target.xcconfig_prefix}OTHER_LDFLAGS}")
end
it 'sets the relative path of the pods root for spec libraries to ${SRCROOT}' do
@xcconfig.to_hash['PODS_ROOT'].should == '${SRCROOT}'
end
......@@ -70,55 +100,6 @@ module Pod
generated.class.should == Xcodeproj::Config
end
end
#-------------------------------------------------------------------------#
describe 'Private Helpers' do
before do
@config = PrivatePodXCConfig.new(stub, stub)
end
#----------------------------------------#
describe '#add_xcconfig_namespaced_keys' do
it 'appends to the values of the keys of the destination the value of the keys of the source' do
source_config = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/MyPod' }
destination_config = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/BuildHeaders' }
result = @config.send(:add_xcconfig_namespaced_keys, source_config, destination_config, 'PREFIX_')
result.should == { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/BuildHeaders ${PREFIX_HEADER_SEARCH_PATHS}' }
end
it 'uses the key of the destination xcconfig if not present in the source' do
source_config = {}
destination_config = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/BuildHeaders' }
result = @config.send(:add_xcconfig_namespaced_keys, source_config, destination_config, 'PREFIX_')
result.should == { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/BuildHeaders' }
end
it 'preserves any value of the source not present in the destination' do
source_config = { 'EXCLUDED_SOURCE_FILE_NAMES' => 'ZBarReaderViewImpl_Simulator.m' }
destination_config = {}
result = @config.send(:add_xcconfig_namespaced_keys, source_config, destination_config, 'PREFIX_')
result.should == { 'EXCLUDED_SOURCE_FILE_NAMES' => '${PREFIX_EXCLUDED_SOURCE_FILE_NAMES}' }
end
end
#----------------------------------------#
describe '#conditional_less_key' do
it 'returns the key without the xcconfig conditional syntax if present' do
result = @config.send(:conditional_less_key, 'EXCLUDED_SOURCE_FILE_NAMES[sdk=iphoneos*][arch=*]')
result.should == 'EXCLUDED_SOURCE_FILE_NAMES'
end
it 'returns the key as it is if no conditional syntax is present' do
result = @config.send(:conditional_less_key, 'EXCLUDED_SOURCE_FILE_NAMES')
result.should == 'EXCLUDED_SOURCE_FILE_NAMES'
end
end
end
#-------------------------------------------------------------------------#
end
end
end
......
require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
module Generator
module XCConfig
describe PublicPodXCConfig do
before do
@spec = fixture_spec('banana-lib/BananaLib.podspec')
@pod_target = fixture_pod_target(@spec)
@generator = PublicPodXCConfig.new(@pod_target)
@spec.xcconfig = { 'OTHER_LDFLAGS' => '-no_compact_unwind' }
@spec.frameworks = ['QuartzCore']
@spec.weak_frameworks = ['iAd']
@spec.libraries = ['xml2']
# vendored_framework_paths = [config.sandbox.root + 'BananaLib/BananaLib.framework']
# Sandbox::FileAccessor.any_instance.stubs(:vendored_frameworks).returns(vendored_framework_paths)
@xcconfig = @generator.generate
end
it 'generates the xcconfig' do
@xcconfig.class.should == Xcodeproj::Config
end
it 'includes the xcconfig of the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-no_compact_unwind')
end
it 'includes the libraries for the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-l"xml2"')
end
it 'includes the frameworks of the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-framework "QuartzCore"')
end
it 'includes the weak-frameworks of the specifications' do
@xcconfig.to_hash['OTHER_LDFLAGS'].should.include('-weak_framework "iAd"')
end
it 'includes the developer frameworks search paths when SenTestingKit is detected' do
@spec.xcconfig = { 'OTHER_LDFLAGS' => '-no_compact_unwind' }
@spec.frameworks = ['SenTestingKit']
xcconfig = @generator.generate
framework_search_paths = xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS']
framework_search_paths.should.include('$(SDKROOT)/Developer')
end
it "doesn't include the developer frameworks if already present" do
@spec.xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '"$(SDKROOT)/Developer/Library/Frameworks" "$(DEVELOPER_LIBRARY_DIR)/Frameworks"' }
@spec.frameworks = ['SenTestingKit']
xcconfig = @generator.generate
framework_search_paths = xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].split(' ')
framework_search_paths.select { |path| path == '"$(SDKROOT)/Developer/Library/Frameworks"' }.count.should == 1
framework_search_paths.select { |path| path == '"$(DEVELOPER_LIBRARY_DIR)/Frameworks"' }.count.should == 1
end
it 'includes the build settings of the frameworks bundles of the spec' do
config.sandbox.stubs(:root).returns(fixture(''))
xcconfig = @generator.generate
xcconfig.to_hash['FRAMEWORK_SEARCH_PATHS'].should.include?('"$(PODS_ROOT)/banana-lib"')
end
it 'includes the build settings of the libraries shipped with the spec' do
config.sandbox.stubs(:root).returns(fixture(''))
xcconfig = @generator.generate
xcconfig.to_hash['LIBRARY_SEARCH_PATHS'].should.include?('"$(PODS_ROOT)/banana-lib"')
end
#-----------------------------------------------------------------------#
before do
@path = temporary_directory + 'sample.xcconfig'
@generator.save_as(@path)
end
it 'saves the xcconfig' do
generated = Xcodeproj::Config.new(@path)
generated.class.should == Xcodeproj::Config
end
it 'writes the xcconfig with a prefix computed from the target definition and root spec' do
generated = Xcodeproj::Config.new(@path)
generated.to_hash.each { |k, _v| k.should.start_with(@pod_target.xcconfig_prefix) }
end
end
end
end
end
......@@ -100,7 +100,6 @@ module Pod
@installer.install!
group = @project['Pods/BananaLib/Support Files']
group.children.map(&:display_name).sort.should == [
'Pods-BananaLib-Private.xcconfig',
'Pods-BananaLib-dummy.m',
'Pods-BananaLib-prefix.pch',
'Pods-BananaLib.xcconfig',
......@@ -127,7 +126,7 @@ module Pod
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'Pods-BananaLib-banana_bundle' }
file = config.sandbox.root + @pod_target.xcconfig_private_path
file = config.sandbox.root + @pod_target.xcconfig_path
bundle_target.build_configurations.each do |bc|
bc.base_configuration_reference.real_path.should == file
end
......@@ -142,7 +141,6 @@ module Pod
@project.support_files_group
group = @project['Pods/BananaLib/Support Files']
group.children.map(&:display_name).sort.should == [
'BananaLib-Private.xcconfig',
'BananaLib-dummy.m',
'BananaLib-prefix.pch',
'BananaLib.xcconfig',
......@@ -169,7 +167,7 @@ module Pod
@installer.install!
bundle_target = @project.targets.find { |t| t.name == 'BananaLib-banana_bundle' }
file = config.sandbox.root + @pod_target.xcconfig_private_path
file = config.sandbox.root + @pod_target.xcconfig_path
bundle_target.build_configurations.each do |bc|
bc.base_configuration_reference.real_path.should == file
end
......@@ -180,7 +178,7 @@ module Pod
it 'creates the xcconfig file' do
@installer.install!
file = config.sandbox.root + @pod_target.xcconfig_private_path
file = config.sandbox.root + @pod_target.xcconfig_path
xcconfig = Xcodeproj::Config.new(file)
xcconfig.to_hash['PODS_ROOT'].should == '${SRCROOT}'
end
......
......@@ -159,9 +159,6 @@ module Pod
@pod_target.xcconfig_path.to_s.should.include?(
'Pods/Target Support Files/BananaLib/BananaLib.xcconfig',
)
@pod_target.xcconfig_private_path.to_s.should.include(
'Pods/Target Support Files/BananaLib/BananaLib-Private.xcconfig',
)
end
it 'returns the path for the CONFIGURATION_BUILD_DIR build setting' do
......
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