Commit 12b5bedc authored by Fabio Pelosin's avatar Fabio Pelosin

[PodsProjectGenerator] Major improvements

parent 6d3c2c45
......@@ -56,12 +56,9 @@ module Pod
@native_target.add_build_configuration(bc_name, type)
end
target.target = @native_target
end
# @return [PBXNativeTarget] the target generated by the installation
# process.
#
......
......@@ -2,21 +2,21 @@ module Pod
class Installer
class PodsProjectGenerator
# Creates the targets which aggregate the Pods libraries in the Pods
# project and the relative support files.
#
class AggregateTargetInstaller < TargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
# Creates the targets which aggregate the Pods libraries in the Pods
# project and the relative support files.
#
def install!
UI.message "- Installing target `#{target.name}` #{target.platform}" do
add_target
class AggregateTargetInstaller < TargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
UI.message "- Installing target `#{target.name}` #{target.platform}" do
add_target
end
end
end
end
end
end
end
......@@ -2,136 +2,136 @@ module Pod
class Installer
class PodsProjectGenerator
# Creates the target for the Pods libraries in the Pods project and the
# relative support files.
#
class PodTargetInstaller < TargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
add_target
add_files_to_build_phases
add_resources_bundle_targets
link_to_system_frameworks
end
private
#-----------------------------------------------------------------------#
# Creates the target for the Pods libraries in the Pods project and the
# relative support files.
#
class PodTargetInstaller < TargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
add_target
add_files_to_build_phases
add_resources_bundle_targets
link_to_system_frameworks
end
# Adds the build files of the pods to the target and adds a reference to
# the frameworks of the Pods.
#
# @note The Frameworks are used only for presentation purposes as the
# xcconfig is the authoritative source about their information.
#
# @return [void]
#
def add_files_to_build_phases
target.file_accessors.each do |file_accessor|
consumer = file_accessor.spec_consumer
flags = compiler_flags_for_consumer(consumer)
source_files = file_accessor.source_files
file_refs = source_files.map { |sf| project.reference_for_path(sf) }
target.target.add_file_references(file_refs, flags)
private
#-----------------------------------------------------------------------#
# Adds the build files of the pods to the target and adds a reference to
# the frameworks of the Pods.
#
# @note The Frameworks are used only for presentation purposes as the
# xcconfig is the authoritative source about their information.
#
# @return [void]
#
def add_files_to_build_phases
target.file_accessors.each do |file_accessor|
consumer = file_accessor.spec_consumer
flags = compiler_flags_for_consumer(consumer)
source_files = file_accessor.source_files
file_refs = source_files.map { |sf| project.reference_for_path(sf) }
target.target.add_file_references(file_refs, flags)
end
end
end
# Adds the resources of the Pods to the Pods project.
#
# @note The source files are grouped by Pod and in turn by subspec
# (recursively) in the resources group.
#
# @return [void]
#
def add_resources_bundle_targets
target.file_accessors.each do |file_accessor|
file_accessor.resource_bundles.each do |bundle_name, paths|
file_references = paths.map { |sf| project.reference_for_path(sf) }
bundle_target = project.new_resources_bundle(bundle_name, file_accessor.spec_consumer.platform_name)
bundle_target.add_resources(file_references)
target.user_build_configurations.each do |bc_name, type|
bundle_target.add_build_configuration(bc_name, type)
# Adds the resources of the Pods to the Pods project.
#
# @note The source files are grouped by Pod and in turn by subspec
# (recursively) in the resources group.
#
# @return [void]
#
def add_resources_bundle_targets
target.file_accessors.each do |file_accessor|
file_accessor.resource_bundles.each do |bundle_name, paths|
file_references = paths.map { |sf| project.reference_for_path(sf) }
bundle_target = project.new_resources_bundle(bundle_name, file_accessor.spec_consumer.platform_name)
bundle_target.add_resources(file_references)
target.user_build_configurations.each do |bc_name, type|
bundle_target.add_build_configuration(bc_name, type)
end
target.add_dependency(bundle_target)
end
target.add_dependency(bundle_target)
end
end
end
# Add a file reference to the system frameworks if needed and links the
# target to them.
#
# This is done only for informative purposes as the xcconfigs are the
# authoritative source of the build settings.
#
# @return [void]
#
def link_to_system_frameworks
target.specs.each do |spec|
spec.consumer(target.platform).frameworks.each do |framework|
project.add_system_framework(framework, target.target)
# Add a file reference to the system frameworks if needed and links the
# target to them.
#
# This is done only for informative purposes as the xcconfigs are the
# authoritative source of the build settings.
#
# @return [void]
#
def link_to_system_frameworks
target.specs.each do |spec|
spec.consumer(target.platform).frameworks.each do |framework|
project.add_system_framework(framework, target.target)
end
end
end
end
# TODO
#
ENABLE_OBJECT_USE_OBJC_FROM = {
:ios => Version.new('6'),
:osx => Version.new('10.8')
}
# Returns the compiler flags for the source files of the given specification.
#
# The following behavior is regarding the `OS_OBJECT_USE_OBJC` flag. When
# set to `0`, it will allow code to use `dispatch_release()` on >= iOS 6.0
# and OS X 10.8.
#
# * New libraries that do *not* require ARC don’t need to care about this
# issue at all.
#
# * New libraries that *do* require ARC _and_ have a deployment target of
# >= iOS 6.0 or OS X 10.8:
#
# These no longer use `dispatch_release()` and should *not* have the
# `OS_OBJECT_USE_OBJC` flag set to `0`.
#
# **Note:** this means that these libraries *have* to specify the
# deployment target in order to function well.
#
# * New libraries that *do* require ARC, but have a deployment target of
# < iOS 6.0 or OS X 10.8:
#
# These contain `dispatch_release()` calls and as such need the
# `OS_OBJECT_USE_OBJC` flag set to `1`.
#
# **Note:** libraries that do *not* specify a platform version are
# assumed to have a deployment target of < iOS 6.0 or OS X 10.8.
#
# For more information, see: http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
#
# @param [Specification::Consumer] consumer
# The consumer for the specification for which the compiler flags
# are needed.
#
# @return [String] The compiler flags.
#
def compiler_flags_for_consumer(consumer)
flags = consumer.compiler_flags.dup
if consumer.requires_arc
flags << '-fobjc-arc'
platform_name = consumer.platform_name
spec_deployment_target = consumer.spec.deployment_target(platform_name)
if spec_deployment_target.nil? || Version.new(spec_deployment_target) < ENABLE_OBJECT_USE_OBJC_FROM[platform_name]
# TODO
#
ENABLE_OBJECT_USE_OBJC_FROM = {
:ios => Version.new('6'),
:osx => Version.new('10.8')
}
# Returns the compiler flags for the source files of the given specification.
#
# The following behavior is regarding the `OS_OBJECT_USE_OBJC` flag. When
# set to `0`, it will allow code to use `dispatch_release()` on >= iOS 6.0
# and OS X 10.8.
#
# * New libraries that do *not* require ARC don’t need to care about this
# issue at all.
#
# * New libraries that *do* require ARC _and_ have a deployment target of
# >= iOS 6.0 or OS X 10.8:
#
# These no longer use `dispatch_release()` and should *not* have the
# `OS_OBJECT_USE_OBJC` flag set to `0`.
#
# **Note:** this means that these libraries *have* to specify the
# deployment target in order to function well.
#
# * New libraries that *do* require ARC, but have a deployment target of
# < iOS 6.0 or OS X 10.8:
#
# These contain `dispatch_release()` calls and as such need the
# `OS_OBJECT_USE_OBJC` flag set to `1`.
#
# **Note:** libraries that do *not* specify a platform version are
# assumed to have a deployment target of < iOS 6.0 or OS X 10.8.
#
# For more information, see: http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
#
# @param [Specification::Consumer] consumer
# The consumer for the specification for which the compiler flags
# are needed.
#
# @return [String] The compiler flags.
#
def compiler_flags_for_consumer(consumer)
flags = consumer.compiler_flags.dup
if consumer.requires_arc
flags << '-fobjc-arc'
platform_name = consumer.platform_name
spec_deployment_target = consumer.spec.deployment_target(platform_name)
if spec_deployment_target.nil? || Version.new(spec_deployment_target) < ENABLE_OBJECT_USE_OBJC_FROM[platform_name]
flags << '-DOS_OBJECT_USE_OBJC=0'
end
end
......
......@@ -78,6 +78,21 @@ module Pod
Lockfile.from_file(manifest_path) if manifest_path.exist?
end
# Returns whether the version of CocoaPods used to generate the sandbox is
# is major than the given version.
#
# @param [String]
#
# @return [Bool]
#
def version_at_least?(version)
if manifest
manifest.cocoapods_version >= Version.new(version)
else
false
end
end
# @return [Installer::Analyzer::SpecsState] The state of the sandbox
# (added, deleted, changed and unchanged pods) as computed by the
# analyzer.
......
......@@ -35,6 +35,10 @@ module Pod
label.upcase.gsub(/[^A-Z]/, '_') + '_'
end
def skip_installation?
false
end
# @return [String] A string suitable for debugging.
#
def inspect
......
......@@ -15,6 +15,10 @@ module Pod
@file_accessors = []
end
def skip_installation?
target_definition.empty?
end
# @return [String] the label for the target.
#
def label
......
......@@ -4,6 +4,10 @@ module Pod
class Installer
describe PodsProjectGenerator do
before do
config.sandbox.stubs(:cocoapods_version).returns(Version.new(Pod::VERSION))
end
#-----------------------------------------------------------------------#
describe "In general" do
......@@ -167,7 +171,30 @@ module Pod
#-----------------------------------------------------------------------#
describe "#sync_target_dependencies" do
describe "#add_missing_aggregate_targets_libraries" do
before do
project = Pod::Project.new(config.sandbox.project_path)
@aggregate_native_target = project.new_target(:static_library, 'Pods', :ios)
@pod_native_target = project.new_target(:static_library, 'Pods-BananaLib', :ios)
pod_target = PodTarget.new([], nil, config.sandbox)
pod_target.target = @pod_native_target
aggregate_target = AggregateTarget.new(nil, config.sandbox)
aggregate_target.pod_targets = [pod_target]
aggregate_target.target = @aggregate_native_target
@sut = PodsProjectGenerator.new(config.sandbox, [aggregate_target])
end
it "links the aggregate targets to the pod targets" do
@sut.send(:add_missing_aggregate_targets_libraries)
@aggregate_native_target.frameworks_build_phase.files.map(&:file_ref).should.include?(@pod_native_target.product_reference)
end
end
#-----------------------------------------------------------------------#
describe "#add_missing_target_dependencies" do
before do
project = Pod::Project.new(config.sandbox.project_path)
......@@ -188,14 +215,14 @@ module Pod
it "sets the pod targets as dependencies of the aggregate target" do
@sut.send(:sync_target_dependencies)
@sut.send(:add_missing_target_dependencies)
dependencies = @aggregate_target.target.dependencies
dependencies.map { |d| d.target.name}.should == ["Pods-BananaLib", "Pods-monkey"]
end
it "sets the dependencies of the pod targets" do
@pod_target_1.stubs(:dependencies).returns(['monkey'])
@sut.send(:sync_target_dependencies)
@sut.send(:add_missing_target_dependencies)
dependencies = @pod_target_1.target.dependencies
dependencies.map { |d| d.target.name}.should == ["Pods-monkey"]
end
......@@ -204,29 +231,6 @@ module Pod
#-----------------------------------------------------------------------#
describe "#sync_aggregate_targets_libraries" do
before do
project = Pod::Project.new(config.sandbox.project_path)
@aggregate_native_target = project.new_target(:static_library, 'Pods', :ios)
@pod_native_target = project.new_target(:static_library, 'Pods-BananaLib', :ios)
pod_target = PodTarget.new([], nil, config.sandbox)
pod_target.target = @pod_native_target
aggregate_target = AggregateTarget.new(nil, config.sandbox)
aggregate_target.pod_targets = [pod_target]
aggregate_target.target = @aggregate_native_target
@sut = PodsProjectGenerator.new(config.sandbox, [aggregate_target])
end
it "links the aggregate targets to the pod targets" do
@sut.send(:sync_aggregate_targets_libraries)
@aggregate_native_target.frameworks_build_phase.files.map(&:file_ref).should.include?(@pod_native_target.product_reference)
end
end
#-----------------------------------------------------------------------#
end
end
end
......@@ -19,6 +19,20 @@ module Pod
@sandbox.manifest.should == nil
end
describe "#version_at_least?" do
it "returns whether the version of CocoaPods used to generate the sandbox is major to the given one" do
manifest = stub(:cocoapods_version => Version.new('1.0'))
@sandbox.stubs(:manifest).returns(manifest)
@sandbox.version_at_least?('1.0.0').should.be.true
end
it "returns false if the manifest is not available" do
@sandbox.version_at_least?('0.0.1').should.be.false
end
end
it "returns the project" do
@sandbox.project.should == nil
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