Commit 01fc9441 authored by Jeremy Slater's avatar Jeremy Slater

Split targets and supporting classes into single purpose classes

Target class converted to PodTarget and SpecTarget representing Pod 
integration targets and podspec targets.
TargetInstaller converted to PodTargetInstaller and 
SpecTargetInstaller to handle variations in installing Pod targets 
and spec targets.
XCConfig generator converted to PodXCConfig, PublicSpecXCCconfig and 
PrivateSpecXCConfig classes to handle generating the different 
xcconfig files.
Requires Xcodeproj file changes to support namespaced xcconfig files.
parent b9dfaa9d
...@@ -44,7 +44,8 @@ module Pod ...@@ -44,7 +44,8 @@ module Pod
autoload :ExternalSources, 'cocoapods/external_sources' autoload :ExternalSources, 'cocoapods/external_sources'
autoload :Installer, 'cocoapods/installer' autoload :Installer, 'cocoapods/installer'
autoload :SourcesManager, 'cocoapods/sources_manager' autoload :SourcesManager, 'cocoapods/sources_manager'
autoload :Target, 'cocoapods/target' autoload :PodTarget, 'cocoapods/target'
autoload :SpecTarget, 'cocoapods/target'
autoload :Project, 'cocoapods/project' autoload :Project, 'cocoapods/project'
autoload :Resolver, 'cocoapods/resolver' autoload :Resolver, 'cocoapods/resolver'
autoload :Sandbox, 'cocoapods/sandbox' autoload :Sandbox, 'cocoapods/sandbox'
...@@ -60,7 +61,9 @@ module Pod ...@@ -60,7 +61,9 @@ module Pod
autoload :Plist, 'cocoapods/generator/acknowledgements/plist' autoload :Plist, 'cocoapods/generator/acknowledgements/plist'
autoload :PrefixHeader, 'cocoapods/generator/prefix_header' autoload :PrefixHeader, 'cocoapods/generator/prefix_header'
autoload :TargetEnvironmentHeader, 'cocoapods/generator/target_environment_header' autoload :TargetEnvironmentHeader, 'cocoapods/generator/target_environment_header'
autoload :XCConfig, 'cocoapods/generator/xcconfig' autoload :PodXCConfig, 'cocoapods/generator/xcconfig'
autoload :PublicSpecXCConfig, 'cocoapods/generator/xcconfig'
autoload :PrivateSpecXCConfig, 'cocoapods/generator/xcconfig'
end end
module Hooks module Hooks
......
...@@ -5,105 +5,20 @@ module Pod ...@@ -5,105 +5,20 @@ module Pod
# for each Pod and for each Pod target definition. The aggregates the # for each Pod and for each Pod target definition. The aggregates the
# configurations of the Pods and define target specific settings. # configurations of the Pods and define target specific settings.
# #
class XCConfig class AbstractXCConfig
# @return [Target] the library or target represented by this xcconfig. # @return [Target] the library or target represented by this xcconfig.
# #
attr_reader :library attr_reader :library
# @return [Sandbox] the sandbox where the Pods project is installed.
#
attr_reader :sandbox attr_reader :sandbox
# @return [Array<Specification::Consumer>] the consumers for the
# specifications of the library which needs the xcconfig.
#
attr_reader :spec_consumers
# @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 [Target] library @see library # @param [Target] library @see library
# @param [Array<Specification::Consumer>] spec_consumers @see spec_consumers
# @param [String] relative_pods_root @see relative_pods_root
# #
def initialize(library, spec_consumers, relative_pods_root) def initialize(library)
@library = library @library = library
@sandbox = library.sandbox @sandbox = library.sandbox
@spec_consumers = spec_consumers
@relative_pods_root = relative_pods_root
end 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.
#
# @note The xcconfig file for a spec derived target includes namespaced
# configuration values, the private build headers and headermap
# disabled. The xcconfig file for the Pods integration target
# then includes the spec xcconfig and incorporates the namespaced
# configuration values like preprocessor overrides or frameworks
# to link with.
#
# @return [Xcodeproj::Config]
#
def generate
ld_flags = '-ObjC'
if set_arc_compatibility_flag && spec_consumers.any? { |consumer| consumer.requires_arc }
ld_flags << ' -fobjc-arc'
end
if library.spec
config = {
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'PODS_ROOT' => '${SRCROOT}',
'HEADER_SEARCH_PATHS' => quote(library.build_headers.search_paths) + ' ' + quote(sandbox.public_headers.search_paths),
'GCC_PREPROCESSOR_DEFINITIONS' => 'COCOAPODS=1',
# 'USE_HEADERMAP' => 'NO'
}
consumer_xcconfig(library.consumer).to_hash.each do |k, v|
prefixed_key = library.xcconfig_prefix + k
config[k] = "#{config[k]} ${#{prefixed_key}}"
config[prefixed_key] = v
end
else
config = {
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'HEADER_SEARCH_PATHS' => '${PODS_HEADERS_SEARCH_PATHS}',
'PODS_ROOT' => relative_pods_root,
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_PUBLIC_HEADERS_SEARCH_PATHS}',
'PODS_BUILD_HEADERS_SEARCH_PATHS' => '',
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(sandbox.public_headers.search_paths),
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
}
library.libraries.each do |lib|
consumer_xcconfig(lib.consumer).to_hash.each do |k, v|
prefixed_key = lib.xcconfig_prefix + k
config[k] = "#{config[k]} ${#{prefixed_key}}"
end
end
end
@xcconfig = Xcodeproj::Config.new(config)
@xcconfig.includes = library.libraries.map(&:name) unless library.spec
@xcconfig
end
# @return [Xcodeproj::Config] The generated xcconfig.
#
attr_reader :xcconfig
# Generates and saves the xcconfig to the given path. # Generates and saves the xcconfig to the given path.
# #
# @param [Pathname] path # @param [Pathname] path
...@@ -112,7 +27,7 @@ module Pod ...@@ -112,7 +27,7 @@ module Pod
# @return [void] # @return [void]
# #
def save_as(path) def save_as(path)
path.open('w') { |file| file.write(generate) } generate.save_as(path)
end end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
...@@ -121,19 +36,6 @@ module Pod ...@@ -121,19 +36,6 @@ module Pod
private 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 # 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 # is surrounded by double quotes and separated by a space. Used to
# represent strings in a xcconfig file. # represent strings in a xcconfig file.
...@@ -159,8 +61,7 @@ module Pod ...@@ -159,8 +61,7 @@ module Pod
# @return [Xcodeproj::Config] # @return [Xcodeproj::Config]
# #
def consumer_xcconfig(consumer) def consumer_xcconfig(consumer)
xcconfig = Xcodeproj::Config.new() xcconfig = Xcodeproj::Config.new(consumer.xcconfig)
xcconfig.merge!(consumer.xcconfig)
xcconfig.libraries.merge(consumer.libraries) xcconfig.libraries.merge(consumer.libraries)
xcconfig.frameworks.merge(consumer.frameworks) xcconfig.frameworks.merge(consumer.frameworks)
xcconfig.weak_frameworks.merge(consumer.weak_frameworks) xcconfig.weak_frameworks.merge(consumer.weak_frameworks)
...@@ -206,6 +107,122 @@ module Pod ...@@ -206,6 +107,122 @@ module Pod
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
end end
#-------------------------------------------------------------------------#
class PodXCConfig < AbstractXCConfig
# Generates the xcconfig for the Pod integration target.
#
# @note The xcconfig file for a Pods integration target includes the
# namespaced xcconfig files for each spec target dependency.
# Each namespaced configuration value is merged into the Pod
# xcconfig file.
#
# @return [Xcodeproj::Config]
#
def generate
ld_flags = '-ObjC'
if library.target_definition.podfile.set_arc_compatibility_flag?
ld_flags << ' -fobjc-arc'
end
config = {
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'HEADER_SEARCH_PATHS' => quote(sandbox.public_headers.search_paths),
'PODS_ROOT' => library.relative_pods_root,
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
}
library.libraries.each do |lib|
consumer_xcconfig(lib.consumer).to_hash.each do |k, v|
prefixed_key = lib.xcconfig_prefix + k
config[k] = "#{config[k]} ${#{prefixed_key}}"
end
end
xcconfig = Xcodeproj::Config.new(config)
xcconfig.includes = library.libraries.map(&:name)
xcconfig
end
end
#-------------------------------------------------------------------------#
class PublicSpecXCConfig < AbstractXCConfig
# Generates and saves the xcconfig to the given path.
#
# @param [Pathname] path
# the path where the prefix header should be stored.
#
# @note The public xcconfig file for a spec target is completely
# namespaced to prevent configuration value collision with other
# spec configurations.
#
# @return [void]
#
def save_as(path)
generate.save_as(path, library.xcconfig_prefix)
end
# Generates the xcconfig for the library.
#
# @note The xcconfig file for a public spec target includes the
# standard podspec defined values including libraries,
# frameworks, weak frameworks and xcconfig overrides.
#
# @return [Xcodeproj::Config]
#
def generate
consumer_xcconfig(library.consumer)
end
end
#-------------------------------------------------------------------------#
class PrivateSpecXCConfig < AbstractXCConfig
# Generates the xcconfig for the library.
#
# @note The private xcconfig file for a spec target includes the public
# namespaced xcconfig file and merges the configuration values
# with the default private configuration values.
#
# @return [Xcodeproj::Config]
#
def generate
ld_flags = '-ObjC'
if library.consumer.requires_arc?
ld_flags << ' -fobjc-arc'
end
config = {
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'PODS_ROOT' => '${SRCROOT}',
'HEADER_SEARCH_PATHS' => quote(library.build_headers.search_paths) + ' ' + quote(sandbox.public_headers.search_paths),
'GCC_PREPROCESSOR_DEFINITIONS' => 'COCOAPODS=1',
# 'USE_HEADERMAP' => 'NO'
}
consumer_xcconfig(library.consumer).to_hash.each do |k, v|
prefixed_key = library.xcconfig_prefix + k
config[k] = "#{config[k]} ${#{prefixed_key}}"
end
xcconfig = Xcodeproj::Config.new(config)
xcconfig.includes = [library.name]
xcconfig
end
end
#-------------------------------------------------------------------------#
end end
end end
...@@ -31,7 +31,8 @@ module Pod ...@@ -31,7 +31,8 @@ module Pod
autoload :Analyzer, 'cocoapods/installer/analyzer' autoload :Analyzer, 'cocoapods/installer/analyzer'
autoload :FileReferencesInstaller, 'cocoapods/installer/file_references_installer' autoload :FileReferencesInstaller, 'cocoapods/installer/file_references_installer'
autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer' autoload :PodSourceInstaller, 'cocoapods/installer/pod_source_installer'
autoload :TargetInstaller, 'cocoapods/installer/target_installer' autoload :PodTargetInstaller, 'cocoapods/installer/target_installer'
autoload :SpecTargetInstaller, 'cocoapods/installer/target_installer'
autoload :UserProjectIntegrator, 'cocoapods/installer/user_project_integrator' autoload :UserProjectIntegrator, 'cocoapods/installer/user_project_integrator'
include Config::Mixin include Config::Mixin
...@@ -135,7 +136,7 @@ module Pod ...@@ -135,7 +136,7 @@ module Pod
# #
attr_reader :names_of_pods_to_install attr_reader :names_of_pods_to_install
# @return [Array<Target>] The Podfile targets containing library # @return [Array<PodTarget>] The Podfile targets containing library
# dependencies. # dependencies.
# #
attr_reader :targets attr_reader :targets
...@@ -315,7 +316,13 @@ module Pod ...@@ -315,7 +316,13 @@ module Pod
UI.message"- Installing libraries" do UI.message"- Installing libraries" do
libraries.sort_by(&:name).each do |library| libraries.sort_by(&:name).each do |library|
next if library.target_definition.empty? next if library.target_definition.empty?
target_installer = TargetInstaller.new(sandbox, library) target_installer = SpecTargetInstaller.new(sandbox, library)
target_installer.install!
end
targets.sort_by(&:name).each do |target|
next if target.target_definition.empty?
target_installer = PodTargetInstaller.new(sandbox, target)
target_installer.install! target_installer.install!
end end
end end
...@@ -381,7 +388,7 @@ module Pod ...@@ -381,7 +388,7 @@ module Pod
# information in the lockfile. # information in the lockfile.
# #
def integrate_user_project def integrate_user_project
UI.section "Integrating client #{'project'.pluralize(libraries.map(&:user_project_path).uniq.count) }" do UI.section "Integrating client #{'project'.pluralize(targets.map(&:user_project_path).uniq.count) }" do
installation_root = config.installation_root installation_root = config.installation_root
integrator = UserProjectIntegrator.new(podfile, sandbox, installation_root, targets) integrator = UserProjectIntegrator.new(podfile, sandbox, installation_root, targets)
integrator.integrate! integrator.integrate!
...@@ -567,7 +574,7 @@ module Pod ...@@ -567,7 +574,7 @@ module Pod
# process. # process.
# #
def libraries def libraries
targets + targets.map(&:libraries).flatten targets.map(&:libraries).flatten
end end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
......
...@@ -164,12 +164,9 @@ module Pod ...@@ -164,12 +164,9 @@ module Pod
def generate_targets def generate_targets
targets = [] targets = []
result.specs_by_target.each do |target_definition, specs| result.specs_by_target.each do |target_definition, specs|
target = Target.new(target_definition, sandbox) target = PodTarget.new(target_definition, sandbox)
targets << target targets << target
target.support_files_root = sandbox.library_support_files_dir(target.name)
target.platform = target_definition.platform
if config.integrate_targets? if config.integrate_targets?
project_path = compute_user_project_path(target_definition) project_path = compute_user_project_path(target_definition)
user_project = Xcodeproj::Project.new(project_path) user_project = Xcodeproj::Project.new(project_path)
...@@ -186,22 +183,9 @@ module Pod ...@@ -186,22 +183,9 @@ module Pod
end end
specs.each do |spec| specs.each do |spec|
lib_target = Podfile::TargetDefinition.from_hash(target_definition.to_hash, target_definition.parent) spec_target = SpecTarget.new(spec, target_definition, sandbox)
if target_definition.name == 'Pods' spec_target.user_build_configurations = target.user_build_configurations
lib_target.name = spec.name.gsub('/', '-') target.libraries << spec_target
else
lib_target.name = "#{target_definition.name}-#{spec.name.gsub('/', '-')}"
end
lib = Target.new(lib_target, sandbox)
lib.spec = spec
lib.support_files_root = target.support_files_root
lib.platform = target.platform
lib.user_project_path = target.user_project_path
lib.client_root = target.client_root
lib.user_build_configurations = target.user_build_configurations
target.libraries << lib
end end
end end
targets targets
......
...@@ -5,7 +5,7 @@ module Pod ...@@ -5,7 +5,7 @@ module Pod
# library target in Pods project. It also creates the support file needed # library target in Pods project. It also creates the support file needed
# by the target. # by the target.
# #
class TargetInstaller class AbstractTargetInstaller
# @return [Sandbox] sandbox the sandbox where the support files should # @return [Sandbox] sandbox the sandbox where the support files should
# be generated. # be generated.
...@@ -24,26 +24,6 @@ module Pod ...@@ -24,26 +24,6 @@ module Pod
@library = library @library = library
end end
# 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_target_environment_header
create_prefix_header
create_bridge_support_file
create_copy_resources_script
create_acknowledgements
create_dummy_source
end
end
#-----------------------------------------------------------------------# #-----------------------------------------------------------------------#
private private
...@@ -85,45 +65,102 @@ module Pod ...@@ -85,45 +65,102 @@ module Pod
target.build_configurations << build_config target.build_configurations << build_config
end end
end end
library.target = @target
end end
# Adds the build files of the pods to the target and adds a reference to # Creates the group that holds the references to the support files
# the frameworks of the Pods. # generated by this installer.
#
# @note The Frameworks are used only for presentation purposes as the
# xcconfig is the authoritative source about their information.
# #
# @return [void] # @return [void]
# #
def add_files_to_build_phases def create_suport_files_group
UI.message "- Adding Build files" do @support_files_group = project.support_files_group.new_group(library.name)
library.file_accessors.each do |file_accessor| end
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 # Generates a dummy source file for each target so libraries that contain
end # only categories build.
#
# @return [void]
#
def create_dummy_source
path = library.dummy_source_path
UI.message "- Generating dummy source file at #{UI.path(path)}" do
generator = Generator::DummySource.new(library.label)
generator.save_as(path)
file_reference = add_file_to_support_group(path)
target.source_build_phase.add_file_reference(file_reference)
end end
end end
# Creates the group that holds the references to the support files #-----------------------------------------------------------------------#
# generated by this installer.
# @return [PBXNativeTarget] the target generated by the installation
# process.
#
# @note Generated by the {#add_target} step.
#
attr_reader :target
# @!group Private helpers.
# @return [Project] the Pods project of the sandbox.
#
def project
sandbox.project
end
# @return [TargetDefinition] the target definition of the library.
#
def target_definition
library.target_definition
end
# @return [PBXGroup] the group where the file references to the support
# files should be stored.
#
attr_reader :support_files_group
# Adds a reference to the given file in the support group of this target.
#
# @param [Pathname] path
# The path of the file to which the reference should be added.
#
# @return [PBXFileReference] the file reference of the added file.
#
def add_file_to_support_group(path)
relative_path = path.relative_path_from(sandbox.root)
support_files_group.new_file(relative_path)
end
#-----------------------------------------------------------------------#
end
#-------------------------------------------------------------------------#
class PodTargetInstaller < AbstractTargetInstaller
# Creates the target in the Pods project and the relative support files.
# #
# @return [void] # @return [void]
# #
def create_suport_files_group def install!
name = target_definition.label UI.message "- Installing target `#{library.name}` #{library.platform}" do
@support_files_group = project.support_files_group.new_group(name) 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 end
#--------------------------------------# #-----------------------------------------------------------------------#
private
# Generates the contents of the xcconfig file and saves it to disk. # Generates the contents of the xcconfig file and saves it to disk.
# #
...@@ -135,10 +172,8 @@ module Pod ...@@ -135,10 +172,8 @@ module Pod
def create_xcconfig_file def create_xcconfig_file
path = library.xcconfig_path path = library.xcconfig_path
UI.message "- Generating xcconfig file at #{UI.path(path)}" do UI.message "- Generating xcconfig file at #{UI.path(path)}" do
gen = Generator::XCConfig.new(library, spec_consumers, library.relative_pods_root) gen = Generator::PodXCConfig.new(library)
gen.set_arc_compatibility_flag = target_definition.podfile.set_arc_compatibility_flag?
gen.save_as(path) gen.save_as(path)
library.xcconfig = gen.xcconfig
xcconfig_file_ref = add_file_to_support_group(path) xcconfig_file_ref = add_file_to_support_group(path)
target.build_configurations.each do |c| target.build_configurations.each do |c|
...@@ -159,27 +194,6 @@ module Pod ...@@ -159,27 +194,6 @@ module Pod
end 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
# Generates the bridge support metadata if requested by the {Podfile}. # Generates the bridge support metadata if requested by the {Podfile}.
# #
# @note The bridge support metadata is added to the resources of the # @note The bridge support metadata is added to the resources of the
...@@ -212,20 +226,12 @@ module Pod ...@@ -212,20 +226,12 @@ module Pod
def create_copy_resources_script def create_copy_resources_script
path = library.copy_resources_script_path path = library.copy_resources_script_path
UI.message "- Generating copy resources script at #{UI.path(path)}" do UI.message "- Generating copy resources script at #{UI.path(path)}" do
if library.spec file_accessors = library.libraries.map(&:file_accessors).flatten
resources = library.file_accessors.map { |accessor| accessor.resources.flatten.map {|res| project.relativize(res)} }.flatten resources = file_accessors.map { |accessor| accessor.resources.flatten.map {|res| project.relativize(res)} }.flatten
resources << bridge_support_file if bridge_support_file resources << bridge_support_file if bridge_support_file
generator = Generator::CopyResourcesScript.new(resources, library.platform) generator = Generator::CopyResourcesScript.new(resources, library.platform)
generator.save_as(path) generator.save_as(path)
add_file_to_support_group(path) add_file_to_support_group(path)
else
path.open('w') do |script|
library.libraries.each do |lib|
script.puts %{"#{lib.copy_resources_script_relative_path}"\n}
end
end
system("chmod +x '#{path}'")
end
end end
end end
...@@ -238,25 +244,41 @@ module Pod ...@@ -238,25 +244,41 @@ module Pod
Generator::Acknowledgements.generators.each do |generator_class| Generator::Acknowledgements.generators.each do |generator_class|
path = generator_class.path_from_basepath(basepath) path = generator_class.path_from_basepath(basepath)
UI.message "- Generating acknowledgements at #{UI.path(path)}" do UI.message "- Generating acknowledgements at #{UI.path(path)}" do
generator = generator_class.new(library.file_accessors) file_accessors = library.libraries.map(&:file_accessors).flatten
generator = generator_class.new(file_accessors)
generator.save_as(path) generator.save_as(path)
add_file_to_support_group(path) add_file_to_support_group(path)
end end
end end
end end
# Generates a dummy source file for each target so libraries that contain # @return [Pathname] the path of the bridge support file relative to the
# only categories build. # sandbox.
#
# @return [Nil] if no bridge support file was generated.
#
attr_reader :bridge_support_file
#-----------------------------------------------------------------------#
end
#-------------------------------------------------------------------------#
class SpecTargetInstaller < AbstractTargetInstaller
# Creates the target in the Pods project and the relative support files.
# #
# @return [void] # @return [void]
# #
def create_dummy_source def install!
path = library.dummy_source_path UI.message "- Installing target `#{library.name}` #{library.platform}" do
UI.message "- Generating dummy source file at #{UI.path(path)}" do add_target
generator = Generator::DummySource.new(library.label) add_files_to_build_phases
generator.save_as(path) create_suport_files_group
file_reference = add_file_to_support_group(path) create_xcconfig_file
target.source_build_phase.add_file_reference(file_reference) create_prefix_header
create_dummy_source
end end
end end
...@@ -264,25 +286,76 @@ module Pod ...@@ -264,25 +286,76 @@ module Pod
private private
# @return [PBXNativeTarget] the target generated by the installation # Adds the build files of the pods to the target and adds a reference to
# process. # the frameworks of the Pods.
# #
# @note Generated by the {#add_target} step. # @note The Frameworks are used only for presentation purposes as the
# xcconfig is the authoritative source about their information.
# #
attr_reader :target # @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)
# @!group Private helpers. file_accessor.spec_consumer.frameworks.each do |framework|
project.add_system_framework(framework, target)
end
end
end
end
# @return [Project] the Pods project of the sandbox. # Generates the contents of the xcconfig file and saves it to disk.
# #
def project # @note The `ALWAYS_SEARCH_USER_PATHS` flag is enabled to support
sandbox.project # 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 end
# @return [TargetDefinition] the target definition of the library. # 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.
# #
def target_definition # @return [void]
library.target_definition #
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 end
# @return [Specification::Consumer] the consumer for the specifications. # @return [Specification::Consumer] the consumer for the specifications.
...@@ -291,30 +364,6 @@ module Pod ...@@ -291,30 +364,6 @@ module Pod
@spec_consumers ||= library.file_accessors.map(&:spec_consumer) @spec_consumers ||= library.file_accessors.map(&:spec_consumer)
end end
# @return [PBXGroup] the group where the file references to the support
# files should be stored.
#
attr_reader :support_files_group
# @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
# Adds a reference to the given file in the support group of this target.
#
# @param [Pathname] path
# The path of the file to which the reference should be added.
#
# @return [PBXFileReference] the file reference of the added file.
#
def add_file_to_support_group(path)
relative_path = path.relative_path_from(sandbox.root)
support_files_group.new_file(relative_path)
end
ENABLE_OBJECT_USE_OBJC_FROM = { ENABLE_OBJECT_USE_OBJC_FROM = {
:ios => Version.new('6'), :ios => Version.new('6'),
:osx => Version.new('10.8') :osx => Version.new('10.8')
......
...@@ -6,7 +6,7 @@ module Pod ...@@ -6,7 +6,7 @@ module Pod
# working with a target in the Podfile and it's dependent libraries. # working with a target in the Podfile and it's dependent libraries.
# This class is used to represent both the targets and their libraries. # This class is used to represent both the targets and their libraries.
# #
class Target class AbstractTarget
# @return [PBXNativeTarget] the target definition of the Podfile that # @return [PBXNativeTarget] the target definition of the Podfile that
# generated this target. # generated this target.
...@@ -17,27 +17,6 @@ module Pod ...@@ -17,27 +17,6 @@ module Pod
# #
attr_reader :sandbox attr_reader :sandbox
# @return [HeadersStore] the header directory for the library.
#
attr_reader :build_headers
# @param [TargetDefinition] target_definition @see target_definition
# @param [Sandbox] sandbox @see sandbox
#
def initialize(target_definition, sandbox)
@target_definition = target_definition
@sandbox = sandbox
@build_headers = Sandbox::HeadersStore.new(sandbox, "BuildHeaders")
@libraries = []
@file_accessors = []
end
# @return [String] the label for the library.
#
def label
target_definition.label.to_s
end
# @return [String] the name of the library. # @return [String] the name of the library.
# #
def name def name
...@@ -66,33 +45,11 @@ module Pod ...@@ -66,33 +45,11 @@ module Pod
# @!group Information storage # @!group Information storage
# @return [Pathname] the folder where to store the support files of this # @return [Platform] the platform for this library.
# library.
#
attr_accessor :support_files_root
# @return [Pathname] the folder where the client is stored used for
# computing the relative paths. If integrating it should be the
# folder where the user project is stored, otherwise it should
# be the installation root.
#
attr_accessor :client_root
# @return [Pathname] the path of the user project that this library will
# integrate as identified by the analyzer.
#
# @note The project instance is not stored to prevent editing different
# instances.
#
attr_accessor :user_project_path
# @return [String] the list of the UUIDs of the user targets that will be
# integrated by this library as identified by the analizer.
#
# @note The target instances are not stored to prevent editing different
# instances.
# #
attr_accessor :user_target_uuids def platform
@platform ||= target_definition.platform
end
# @return [Hash{String=>Symbol}] A hash representing the user build # @return [Hash{String=>Symbol}] A hash representing the user build
# configurations where each key corresponds to the name of a # configurations where each key corresponds to the name of a
...@@ -100,57 +57,34 @@ module Pod ...@@ -100,57 +57,34 @@ module Pod
# #
attr_accessor :user_build_configurations attr_accessor :user_build_configurations
# @return [Platform] the platform for this library.
#
attr_accessor :platform
# @return [PBXNativeTarget] the target generated in the Pods project for
# this library.
#
attr_accessor :target
# @return [Xcodeproj::Config] the configuration file of the library
#
# @note The configuration is generated by the {TargetInstaller} and
# used by {UserProjectIntegrator} to check for any overridden
# values.
#
attr_accessor :xcconfig
# @return [Specification] the specification for this library.
#
attr_accessor :spec
# @return [Array<Sandbox::FileAccessor>] the file accessors for the
# specifications of this library.
#
attr_accessor :file_accessors
# @return [Array<Target>] the dependencies for this target (or library).
#
attr_accessor :libraries
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
# @!group Support files # @!group Support files
# @return [Pathname] the folder where to store the support files of this
# library.
#
def support_files_root
@sandbox.library_support_files_dir(name)
end
# @return [Pathname] the absolute path of the xcconfig file. # @return [Pathname] the absolute path of the xcconfig file.
# #
def xcconfig_path def xcconfig_path
support_files_root + "#{label}.xcconfig" support_files_root + "#{label}.xcconfig"
end end
# @return [Pathname] the absolute path of the copy resources script. # @return [Pathname] the absolute path of the private xcconfig file.
# #
def copy_resources_script_path def xcconfig_private_path
support_files_root + "#{label}-resources.sh" support_files_root + "#{label}-Private.xcconfig"
end end
# @return [Pathname] the absolute path of the header file which contains # @return [Pathname] the absolute path of the header file which contains
# the information about the installed pods. # the information about the installed pods.
# #
def target_environment_header_path def target_environment_header_path
support_files_root + "#{label}-environment.h" support_files_root + "#{target_definition.label.to_s}-environment.h"
end end
# @return [Pathname] the absolute path of the prefix header file. # @return [Pathname] the absolute path of the prefix header file.
...@@ -165,6 +99,61 @@ module Pod ...@@ -165,6 +99,61 @@ module Pod
support_files_root + "#{label}.bridgesupport" support_files_root + "#{label}.bridgesupport"
end end
# @return [Pathname] the path of the dummy source generated by CocoaPods
#
def dummy_source_path
support_files_root + "#{label}-dummy.m"
end
end
#---------------------------------------------------------------------------#
class PodTarget < AbstractTarget
# @param [TargetDefinition] target_definition @see target_definition
# @param [Sandbox] sandbox @see sandbox
#
def initialize(target_definition, sandbox)
@target_definition = target_definition
@sandbox = sandbox
@libraries = []
@file_accessors = []
end
# @return [String] the label for the library.
#
def label
target_definition.label.to_s
end
# @return [Pathname] the folder where the client is stored used for
# computing the relative paths. If integrating it should be the
# folder where the user project is stored, otherwise it should
# be the installation root.
#
attr_accessor :client_root
# @return [Pathname] the path of the user project that this library will
# integrate as identified by the analyzer.
#
# @note The project instance is not stored to prevent editing different
# instances.
#
attr_accessor :user_project_path
# @return [String] the list of the UUIDs of the user targets that will be
# integrated by this library as identified by the analizer.
#
# @note The target instances are not stored to prevent editing different
# instances.
#
attr_accessor :user_target_uuids
# @return [Array<SpecTarget>] the dependencies for this target (or library).
#
attr_accessor :libraries
# @return [Pathname] the absolute path of acknowledgements file. # @return [Pathname] the absolute path of acknowledgements file.
# #
# @note The acknowledgements generators add the extension according to # @note The acknowledgements generators add the extension according to
...@@ -174,14 +163,12 @@ module Pod ...@@ -174,14 +163,12 @@ module Pod
support_files_root + "#{label}-acknowledgements" support_files_root + "#{label}-acknowledgements"
end end
# @return [Pathname] the path of the dummy source generated by CocoaPods # @return [Pathname] the absolute path of the copy resources script.
# #
def dummy_source_path def copy_resources_script_path
support_files_root + "#{label}-dummy.m" support_files_root + "#{label}-resources.sh"
end end
#--------------------------------------#
# @return [String] The xcconfig path of the root from the `$(SRCROOT)` # @return [String] The xcconfig path of the root from the `$(SRCROOT)`
# variable of the user's project. # variable of the user's project.
# #
...@@ -203,12 +190,6 @@ module Pod ...@@ -203,12 +190,6 @@ module Pod
"${SRCROOT}/#{relative_to_srcroot(copy_resources_script_path)}" "${SRCROOT}/#{relative_to_srcroot(copy_resources_script_path)}"
end end
# @return [Specification::Consumer] the specification consumer for the
# library.
#
def consumer
spec.consumer(platform)
end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
# @!group Private Helpers # @!group Private Helpers
...@@ -226,5 +207,59 @@ module Pod ...@@ -226,5 +207,59 @@ module Pod
def relative_to_srcroot(path) def relative_to_srcroot(path)
path.relative_path_from(client_root).to_s path.relative_path_from(client_root).to_s
end end
end
#---------------------------------------------------------------------------#
class SpecTarget < AbstractTarget
# @return [Specification] the spec for the target.
#
attr_reader :spec
# @return [HeadersStore] the header directory for the library.
#
attr_reader :build_headers
# @param [Specification] spec @see spec
# @param [TargetDefinition] target_definition @see target_definition
# @param [Sandbox] sandbox @see sandbox
#
def initialize(spec, target_definition, sandbox)
@spec = spec
@target_definition = target_definition
@sandbox = sandbox
@build_headers = Sandbox::HeadersStore.new(sandbox, "BuildHeaders")
@file_accessors = []
end
# @return [String] the label for the library.
#
def label
"#{target_definition.label.to_s}-#{spec.name.gsub('/', '-')}"
end
# @return [Specification] the specification for this library.
#
attr_accessor :spec
# @return [Array<Sandbox::FileAccessor>] the file accessors for the
# specifications of this library.
#
attr_accessor :file_accessors
#--------------------------------------#
# @return [Specification::Consumer] the specification consumer for the
# library.
#
def consumer
spec.consumer(platform)
end
end 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