Commit 6a9aabb5 authored by Fabio Pelosin's avatar Fabio Pelosin

[TargetInstaller] Refactor file structure

parent a9d61576
......@@ -31,8 +31,9 @@ module Pod
autoload :Analyzer, 'cocoapods/installer/analyzer'
autoload :FileReferencesInstaller, 'cocoapods/installer/file_references_installer'
autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
autoload :AggregateTargetInstaller, 'cocoapods/installer/target_installer'
autoload :PodTargetInstaller, 'cocoapods/installer/target_installer'
autoload :TargetInstaller, 'cocoapods/installer/target_installer'
autoload :AggregateTargetInstaller, 'cocoapods/installer/target_installer/aggregate_target_installer'
autoload :PodTargetInstaller, 'cocoapods/installer/target_installer/pod_target_installer'
autoload :UserProjectIntegrator, 'cocoapods/installer/user_project_integrator'
include Config::Mixin
......
......@@ -5,7 +5,7 @@ module Pod
# library target in Pods project. It also creates the support file needed
# by the target.
#
class AbstractTargetInstaller
class TargetInstaller
# @return [Sandbox] sandbox the sandbox where the support files should
# be generated.
......@@ -136,294 +136,6 @@ module Pod
#-----------------------------------------------------------------------#
end
#-------------------------------------------------------------------------#
class AggregateTargetInstaller < AbstractTargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
UI.message "- Installing target `#{library.name}` #{library.platform}" do
add_target
create_suport_files_group
create_xcconfig_file
create_target_environment_header
create_bridge_support_file
create_copy_resources_script
create_acknowledgements
create_dummy_source
end
end
#-----------------------------------------------------------------------#
private
# Generates the contents of the xcconfig file and saves it to disk.
#
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
# libraries like `EmbedReader`.
#
# @return [void]
#
def create_xcconfig_file
path = library.xcconfig_path
UI.message "- Generating xcconfig file at #{UI.path(path)}" do
gen = Generator::PodXCConfig.new(library)
gen.save_as(path)
library.xcconfig = gen.xcconfig
xcconfig_file_ref = add_file_to_support_group(path)
target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
end
end
end
# Generates a header which allows to inspect at compile time the installed
# pods and the installed specifications of a pod.
#
def create_target_environment_header
path = library.target_environment_header_path
UI.message "- Generating target environment header at #{UI.path(path)}" do
generator = Generator::TargetEnvironmentHeader.new(library.pod_targets.map { |l| l.specs }.flatten)
generator.save_as(path)
add_file_to_support_group(path)
end
end
# Generates the bridge support metadata if requested by the {Podfile}.
#
# @note The bridge support metadata is added to the resources of the
# library because it is needed for environments interpreted at
# runtime.
#
# @return [void]
#
def create_bridge_support_file
if target_definition.podfile.generate_bridge_support?
path = library.bridge_support_path
UI.message "- Generating BridgeSupport metadata at #{UI.path(path)}" do
headers = target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
generator = Generator::BridgeSupport.new(headers)
generator.save_as(path)
add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end
end
end
# Creates a script that copies the resources to the bundle of the client
# target.
#
# @note The bridge support file needs to be created before the prefix
# header, otherwise it will not be added to the resources script.
#
# @return [void]
#
def create_copy_resources_script
path = library.copy_resources_script_path
UI.message "- Generating copy resources script at #{UI.path(path)}" do
file_accessors = library.pod_targets.map(&:file_accessors).flatten
resources = file_accessors.map { |accessor| accessor.resources.flatten.map {|res| project.relativize(res)} }.flatten
resources << bridge_support_file if bridge_support_file
generator = Generator::CopyResourcesScript.new(resources, library.platform)
generator.save_as(path)
add_file_to_support_group(path)
end
end
# Generates the acknowledgement files (markdown and plist) for the target.
#
# @return [void]
#
def create_acknowledgements
basepath = library.acknowledgements_basepath
Generator::Acknowledgements.generators.each do |generator_class|
path = generator_class.path_from_basepath(basepath)
UI.message "- Generating acknowledgements at #{UI.path(path)}" do
file_accessors = library.pod_targets.map(&:file_accessors).flatten
generator = generator_class.new(file_accessors)
generator.save_as(path)
add_file_to_support_group(path)
end
end
end
# @return [Pathname] the path of the bridge support file relative to the
# sandbox.
#
# @return [Nil] if no bridge support file was generated.
#
attr_reader :bridge_support_file
#-----------------------------------------------------------------------#
end
#-------------------------------------------------------------------------#
class PodTargetInstaller < AbstractTargetInstaller
# Creates the target in the Pods project and the relative support files.
#
# @return [void]
#
def install!
UI.message "- Installing target `#{library.name}` #{library.platform}" do
add_target
add_files_to_build_phases
create_suport_files_group
create_xcconfig_file
create_prefix_header
create_dummy_source
end
end
#-----------------------------------------------------------------------#
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
UI.message "- Adding Build files" do
library.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.file_reference(sf) }
target.add_file_references(file_refs, flags)
file_accessor.spec_consumer.frameworks.each do |framework|
project.add_system_framework(framework, target)
end
end
end
end
# Generates the contents of the xcconfig file and saves it to disk.
#
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
# libraries like `EmbedReader`.
#
# @return [void]
#
def create_xcconfig_file
path = library.xcconfig_path
UI.message "- Generating public xcconfig file at #{UI.path(path)}" do
gen = Generator::PublicSpecXCConfig.new(library)
gen.save_as(path)
xcconfig_file_ref = add_file_to_support_group(path)
end
path = library.xcconfig_private_path
UI.message "- Generating private xcconfig file at #{UI.path(path)}" do
gen = Generator::PrivateSpecXCConfig.new(library)
gen.save_as(path)
xcconfig_file_ref = add_file_to_support_group(path)
target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
end
end
end
# Creates a prefix header file which imports `UIKit` or `Cocoa` according
# to the platform of the target. This file also include any prefix header
# content reported by the specification of the pods.
#
# @return [void]
#
def create_prefix_header
path = library.prefix_header_path
UI.message "- Generating prefix header at #{UI.path(path)}" do
generator = Generator::PrefixHeader.new(library.file_accessors, library.platform)
generator.imports << library.target_environment_header_path.basename
generator.save_as(path)
add_file_to_support_group(path)
target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
end
end
end
# @return [Specification::Consumer] the consumer for the specifications.
#
def spec_consumers
@spec_consumers ||= library.file_accessors.map(&:spec_consumer)
end
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
if target_definition.inhibits_warnings_for_pod?(consumer.spec.root.name)
flags << '-w -Xanalyzer -analyzer-disable-checker'
end
flags * " "
end
#-----------------------------------------------------------------------#
end
end
end
module Pod
class Installer
# 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]
#
def install!
UI.message "- Installing target `#{library.name}` #{library.platform}" do
add_target
create_suport_files_group
create_xcconfig_file
create_target_environment_header
create_bridge_support_file
create_copy_resources_script
create_acknowledgements
create_dummy_source
end
end
#-----------------------------------------------------------------------#
private
# Generates the contents of the xcconfig file and saves it to disk.
#
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
# libraries like `EmbedReader`.
#
# @return [void]
#
def create_xcconfig_file
path = library.xcconfig_path
UI.message "- Generating xcconfig file at #{UI.path(path)}" do
gen = Generator::PodXCConfig.new(library)
gen.save_as(path)
library.xcconfig = gen.xcconfig
xcconfig_file_ref = add_file_to_support_group(path)
target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
end
end
end
# Generates a header which allows to inspect at compile time the installed
# pods and the installed specifications of a pod.
#
def create_target_environment_header
path = library.target_environment_header_path
UI.message "- Generating target environment header at #{UI.path(path)}" do
generator = Generator::TargetEnvironmentHeader.new(library.pod_targets.map { |l| l.specs }.flatten)
generator.save_as(path)
add_file_to_support_group(path)
end
end
# Generates the bridge support metadata if requested by the {Podfile}.
#
# @note The bridge support metadata is added to the resources of the
# library because it is needed for environments interpreted at
# runtime.
#
# @return [void]
#
def create_bridge_support_file
if target_definition.podfile.generate_bridge_support?
path = library.bridge_support_path
UI.message "- Generating BridgeSupport metadata at #{UI.path(path)}" do
headers = target.headers_build_phase.files.map { |bf| sandbox.root + bf.file_ref.path }
generator = Generator::BridgeSupport.new(headers)
generator.save_as(path)
add_file_to_support_group(path)
@bridge_support_file = path.relative_path_from(sandbox.root)
end
end
end
# Creates a script that copies the resources to the bundle of the client
# target.
#
# @note The bridge support file needs to be created before the prefix
# header, otherwise it will not be added to the resources script.
#
# @return [void]
#
def create_copy_resources_script
path = library.copy_resources_script_path
UI.message "- Generating copy resources script at #{UI.path(path)}" do
file_accessors = library.pod_targets.map(&:file_accessors).flatten
resources = file_accessors.map { |accessor| accessor.resources.flatten.map {|res| project.relativize(res)} }.flatten
resources << bridge_support_file if bridge_support_file
generator = Generator::CopyResourcesScript.new(resources, library.platform)
generator.save_as(path)
add_file_to_support_group(path)
end
end
# Generates the acknowledgement files (markdown and plist) for the target.
#
# @return [void]
#
def create_acknowledgements
basepath = library.acknowledgements_basepath
Generator::Acknowledgements.generators.each do |generator_class|
path = generator_class.path_from_basepath(basepath)
UI.message "- Generating acknowledgements at #{UI.path(path)}" do
file_accessors = library.pod_targets.map(&:file_accessors).flatten
generator = generator_class.new(file_accessors)
generator.save_as(path)
add_file_to_support_group(path)
end
end
end
# @return [Pathname] the path of the bridge support file relative to the
# sandbox.
#
# @return [Nil] if no bridge support file was generated.
#
attr_reader :bridge_support_file
#-----------------------------------------------------------------------#
end
end
end
module Pod
class Installer
# 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!
UI.message "- Installing target `#{library.name}` #{library.platform}" do
add_target
add_files_to_build_phases
create_suport_files_group
create_xcconfig_file
create_prefix_header
create_dummy_source
end
end
#-----------------------------------------------------------------------#
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
UI.message "- Adding Build files" do
library.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.file_reference(sf) }
target.add_file_references(file_refs, flags)
file_accessor.spec_consumer.frameworks.each do |framework|
project.add_system_framework(framework, target)
end
end
end
end
# Generates the contents of the xcconfig file and saves it to disk.
#
# @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
# libraries like `EmbedReader`.
#
# @return [void]
#
def create_xcconfig_file
path = library.xcconfig_path
UI.message "- Generating public xcconfig file at #{UI.path(path)}" do
gen = Generator::PublicSpecXCConfig.new(library)
gen.save_as(path)
add_file_to_support_group(path)
end
path = library.xcconfig_private_path
UI.message "- Generating private xcconfig file at #{UI.path(path)}" do
gen = Generator::PrivateSpecXCConfig.new(library)
gen.save_as(path)
xcconfig_file_ref = add_file_to_support_group(path)
target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
end
end
end
# Creates a prefix header file which imports `UIKit` or `Cocoa` according
# to the platform of the target. This file also include any prefix header
# content reported by the specification of the pods.
#
# @return [void]
#
def create_prefix_header
path = library.prefix_header_path
UI.message "- Generating prefix header at #{UI.path(path)}" do
generator = Generator::PrefixHeader.new(library.file_accessors, library.platform)
generator.imports << library.target_environment_header_path.basename
generator.save_as(path)
add_file_to_support_group(path)
target.build_configurations.each do |c|
relative_path = path.relative_path_from(sandbox.root)
c.build_settings['GCC_PREFIX_HEADER'] = relative_path.to_s
end
end
end
# @return [Specification::Consumer] the consumer for the specifications.
#
def spec_consumers
@spec_consumers ||= library.file_accessors.map(&:spec_consumer)
end
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
if target_definition.inhibits_warnings_for_pod?(consumer.spec.root.name)
flags << '-w -Xanalyzer -analyzer-disable-checker'
end
flags * " "
end
#-----------------------------------------------------------------------#
end
end
end
require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
describe Installer::AggregateTargetInstaller do
describe "In General" do
end
end
end
require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
describe Installer::PodTargetInstaller do
describe "In General" do
end
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