Skip to content

Commit

Permalink
Merge branch 'dedicated-targets' of https://github.com/jasl8r/CocoaPods
Browse files Browse the repository at this point in the history
… into jasl8r-dedicated-targets

* 'dedicated-targets' of https://github.com/jasl8r/CocoaPods:
  Support xcconfig files per Podfile target
  Add specs to libraries for non-integrated targets
  Only add a single Manifest.lock phase when dealing with multiple specs
  Identify copy build phase by spec name
  Add per-spec static library targets
  • Loading branch information
fabiopelosin committed Apr 29, 2013
2 parents 71ab8a7 + 717dc51 commit 397eaa9
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 171 deletions.
2 changes: 1 addition & 1 deletion lib/cocoapods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def message
autoload :ExternalSources, 'cocoapods/external_sources'
autoload :Installer, 'cocoapods/installer'
autoload :SourcesManager, 'cocoapods/sources_manager'
autoload :Library, 'cocoapods/library'
autoload :Target, 'cocoapods/target'
autoload :Project, 'cocoapods/project'
autoload :Resolver, 'cocoapods/resolver'
autoload :Sandbox, 'cocoapods/sandbox'
Expand Down
23 changes: 16 additions & 7 deletions lib/cocoapods/generator/xcconfig.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ module Generator
#
class XCConfig

# @return [Target] the library or target represented by this xcconfig.
#
attr_reader :library

# @return [Sandbox] the sandbox where the Pods project is installed.
#
attr_reader :sandbox
Expand All @@ -20,12 +24,13 @@ class XCConfig
#
attr_reader :relative_pods_root

# @param [Sandbox] sandbox @see sandbox
# @param [Array<LocalPod>] pods @see pods
# @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(sandbox, spec_consumers, relative_pods_root)
@sandbox = sandbox
def initialize(library, spec_consumers, relative_pods_root)
@library = library
@sandbox = library.sandbox
@spec_consumers = spec_consumers
@relative_pods_root = relative_pods_root
end
Expand All @@ -50,14 +55,17 @@ def generate
ld_flags << ' -fobjc-arc'
end

public_headers = [library.public_headers.search_paths,
library.libraries.map { |lib| lib.public_headers.search_paths }].flatten

@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_HEADERS_SEARCH_PATHS' => '${PODS_PUBLIC_HEADERS_SEARCH_PATHS}',
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quote(sandbox.build_headers.search_paths),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(sandbox.public_headers.search_paths),
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quote(library.build_headers.search_paths),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(public_headers),
'GCC_PREPROCESSOR_DEFINITIONS' => 'COCOAPODS=1'
})

Expand All @@ -77,7 +85,8 @@ def generate
#
def self.pods_project_settings
{ 'PODS_ROOT' => '${SRCROOT}',
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_BUILD_HEADERS_SEARCH_PATHS}' }
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_BUILD_HEADERS_SEARCH_PATHS} ${PODS_PUBLIC_HEADERS_SEARCH_PATHS}',
'USE_HEADERMAP' => 'NO' }
end

# Generates and saves the xcconfig to the given path.
Expand Down
4 changes: 2 additions & 2 deletions lib/cocoapods/hooks/installer_representation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def libraries
def specs_by_lib
result = {}
installer.libraries.each do |lib|
result[installer.library_rep(lib)] = lib.specs
result[installer.library_rep(lib)] = [lib.spec]
end
result
end
Expand All @@ -71,7 +71,7 @@ def specs_by_lib
def pods_by_lib
result = {}
installer.libraries.each do |lib|
pod_names = lib.specs.map { |spec| spec.root.name }.uniq
pod_names = [lib.spec.root.name]
pod_reps = pods.select { |rep| pod_names.include?(rep.name) }
result[lib.target_definition] = pod_reps
end
Expand Down
54 changes: 31 additions & 23 deletions lib/cocoapods/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def generate_pods_project
UI.section "Generating Pods project" do
prepare_pods_project
install_file_references
install_targets
install_libraries
run_post_install_hooks
write_pod_project
write_lockfiles
Expand All @@ -134,10 +134,10 @@ def generate_pods_project
#
attr_reader :names_of_pods_to_install

# @return [Array<Library>] The libraries generated by the installation
# process.
# @return [Array<Target>] The Podfile targets containing library
# dependencies.
#
attr_reader :libraries
attr_reader :targets

# @return [Array<Specification>] The specifications that where installed.
#
Expand Down Expand Up @@ -165,7 +165,7 @@ def analyze
analyzer = Analyzer.new(sandbox, podfile, lockfile)
analyzer.update_mode = update_mode
@analysis_result = analyzer.analyze
@libraries = analyzer.result.libraries
@targets = analyzer.result.targets
end

# Prepares the Pods folder in order to be compatible with the most recent
Expand All @@ -186,8 +186,12 @@ def prepare_for_legacy_compatibility
# @todo [#247] Clean the headers of only the pods to install.
#
def clean_sandbox
sandbox.build_headers.implode!
sandbox.public_headers.implode!
targets.each do |target|
target.libraries.each do |library|
library.build_headers.implode!
library.public_headers.implode!
end
end

unless sandbox_state.deleted.empty?
title_options = { :verbose_prefix => "-> ".red }
Expand All @@ -203,11 +207,11 @@ def clean_sandbox
# created by the Pod source installer as well.
#
def create_file_accessors
libraries.each do |library|
library.specs.each do |spec|
pod_root = sandbox.pod_dir(spec.root.name)
targets.each do |target|
target.libraries.each do |library|
pod_root = sandbox.pod_dir(library.spec.root.name)
path_list = Sandbox::PathList.new(pod_root)
file_accessor = Sandbox::FileAccessor.new(path_list, spec.consumer(library.platform))
file_accessor = Sandbox::FileAccessor.new(path_list, library.spec.consumer(library.platform))
library.file_accessors ||= []
library.file_accessors << file_accessor
end
Expand Down Expand Up @@ -243,11 +247,9 @@ def install_pod_sources
def install_source_of_pod(pod_name)
specs_by_platform = {}
libraries.each do |library|
specs = library.specs.select { |spec| spec.root.name == pod_name }

unless specs.empty?
if library.spec.root.name == pod_name
specs_by_platform[library.platform] ||= []
specs_by_platform[library.platform].concat(specs)
specs_by_platform[library.platform] << library.spec
end
end

Expand Down Expand Up @@ -286,7 +288,7 @@ def prepare_pods_project
@pods_project.add_podfile(config.podfile_path)
end
sandbox.project = @pods_project
platforms = libraries.map(&:platform)
platforms = targets.map(&:platform)
osx_deployment_target = platforms.select { |p| p.name == :osx }.map(&:deployment_target).min
ios_deployment_target = platforms.select { |p| p.name == :ios }.map(&:deployment_target).min
@pods_project.build_configurations.each do |build_configuration|
Expand All @@ -307,15 +309,14 @@ def install_file_references
installer.install!
end

# Installs the targets of the Pods projects and generates their support
# files.
# Installs the library targets of the Pods projects and generates their
# support files.
#
# @return [void]
#
def install_targets
UI.message"- Installing targets" do
def install_libraries
UI.message"- Installing libraries" do
libraries.sort_by(&:name).each do |library|
next if library.target_definition.empty?
target_installer = TargetInstaller.new(sandbox, library)
target_installer.install!
end
Expand Down Expand Up @@ -368,7 +369,7 @@ def write_lockfiles
def integrate_user_project
UI.section "Integrating client #{'project'.pluralize(libraries.map(&:user_project_path).uniq.count) }" do
installation_root = config.installation_root
integrator = UserProjectIntegrator.new(podfile, sandbox, installation_root, libraries)
integrator = UserProjectIntegrator.new(podfile, sandbox, installation_root, targets)
integrator.integrate!
end
end
Expand Down Expand Up @@ -545,7 +546,14 @@ def pod_reps
# @return [Array<Library>] The library.
#
def libraries_using_spec(spec)
libraries.select { |lib| lib.specs.include?(spec) }
libraries.select { |lib| lib.spec == spec }
end

# @return [Array<Library>] The libraries generated by the installation
# process.
#
def libraries
targets.map(&:libraries).flatten
end

#-------------------------------------------------------------------------#
Expand Down
118 changes: 74 additions & 44 deletions lib/cocoapods/installer/analyzer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ def analyze(allow_fetches = true)
@result.podfile_state = generate_podfile_state
@locked_dependencies = generate_version_locking_dependencies

@result.libraries = generated_libraries
compute_target_platforms
fetch_external_sources if allow_fetches
@result.specs_by_target = resolve_dependencies
@result.specifications = generate_specifications
@result.targets = generate_targets
@result.sandbox_state = generate_sandbox_state
@result
end
Expand Down Expand Up @@ -158,44 +159,59 @@ def update_repositories_if_needed

# Creates the models that represent the libraries generated by CocoaPods.
#
# @note The libraries are generated before the resolution process
# because it might be necessary to infer the platform from the
# user targets, which in turns requires to identify the user
# project.
#
# @note The specification of the libraries are added in the
# {#resolve_dependencies} step.
#
# @return [Array<Libraries>] the generated libraries.
#
def generated_libraries
libraries = []
podfile.target_definition_list.each do |target_definition|
lib = Library.new(target_definition)
lib.support_files_root = sandbox.library_support_files_dir(lib.name)
def generate_targets
targets = []
result.specs_by_target.each do |target_definition, specs|
libs_by_name = {}
target = Target.new(target_definition, sandbox)
targets << target

specs.each do |spec|
lib_target = Podfile::TargetDefinition.from_hash(target_definition.to_hash, target_definition.parent)
if target_definition.name == 'Pods'
lib_target.name = spec.name.gsub('/', '-')
else
lib_target.name = "#{target_definition.name}-#{spec.name.gsub('/', '-')}"
end

if config.integrate_targets?
project_path = compute_user_project_path(target_definition)
user_project = Xcodeproj::Project.new(project_path)
targets = compute_user_project_targets(target_definition, user_project)
lib = Target.new(lib_target, sandbox)
libs_by_name[spec.name] = lib

lib.user_project_path = project_path
lib.client_root = project_path.dirname
lib.user_target_uuids = targets.map(&:uuid)
lib.user_build_configurations = compute_user_build_configurations(target_definition, targets)
lib.platform = compute_platform_for_target_definition(target_definition, targets)
else
unless target_definition.platform
raise Informative, "It is necessary to specify the platform in the Podfile if not integrating."
end
lib.client_root = config.installation_root
lib.user_target_uuids = []
lib.user_build_configurations = {}
lib.support_files_root = sandbox.library_support_files_dir(lib.name)
lib.platform = target_definition.platform
lib.spec = spec

target.support_files_root = sandbox.library_support_files_dir(target.name)
target.platform = target_definition.platform

if config.integrate_targets?
project_path = compute_user_project_path(target_definition)
user_project = Xcodeproj::Project.new(project_path)
native_targets = compute_user_project_targets(target_definition, user_project)

lib.user_project_path = project_path
lib.client_root = project_path.dirname
lib.user_build_configurations = compute_user_build_configurations(target_definition, native_targets)

target.user_project_path = project_path
target.client_root = project_path.dirname
target.user_target_uuids = native_targets.map(&:uuid)
target.user_build_configurations = compute_user_build_configurations(target_definition, native_targets)
else
lib.client_root = config.installation_root
lib.user_target_uuids = []
lib.user_build_configurations = {}
end
target.libraries << lib
end

target.libraries.each do |library|
library.libraries = library.spec.dependencies(library.platform).map { |dep| libs_by_name[dep.name] }
end
libraries << lib
end
libraries
targets
end

# Generates dependencies that require the specific version of the Pods
Expand Down Expand Up @@ -263,8 +279,6 @@ def fetch_external_sources

# Converts the Podfile in a list of specifications grouped by target.
#
# @note In this step the specs are added to the libraries.
#
# @note As some dependencies might have external sources the resolver
# is aware of the {Sandbox} and interacts with it to download the
# podspecs of the external sources. This is necessary because the
Expand All @@ -284,17 +298,10 @@ def fetch_external_sources
#
def resolve_dependencies
specs_by_target = nil

UI.section "Resolving dependencies of #{UI.path podfile.defined_in_file}" do
resolver = Resolver.new(sandbox, podfile, locked_dependencies)
specs_by_target = resolver.resolve
end

specs_by_target.each do |target_definition, specs|
lib = result.libraries.find { |l| l.target_definition == target_definition}
lib.specs = specs
end

specs_by_target
end

Expand Down Expand Up @@ -449,6 +456,29 @@ def compute_platform_for_target_definition(target_definition, user_targets)
Platform.new(name, deployment_target)
end

# Precompute the platforms for each target_definition in the Podfile
#
# @note The platforms are computed and added to each target_definition
# because it might be necessary to infer the platform from the
# user targets.
#
# @return [void]
#
def compute_target_platforms
podfile.target_definition_list.each do |target_definition|
if config.integrate_targets?
project_path = compute_user_project_path(target_definition)
user_project = Xcodeproj::Project.new(project_path)
targets = compute_user_project_targets(target_definition, user_project)
platform = compute_platform_for_target_definition(target_definition, targets)
else
unless target_definition.platform
raise Informative, "It is necessary to specify the platform in the Podfile if not integrating."
end
end
end
end

#-----------------------------------------------------------------------#

class AnalysisResult
Expand All @@ -472,10 +502,10 @@ class AnalysisResult
#
attr_accessor :sandbox_state

# @return [Array<Library>] the libraries generated by the target
# definitions.
# @return [Array<Target>] The Podfile targets containing library
# dependencies.
#
attr_accessor :libraries
attr_accessor :targets

end

Expand Down
Loading

0 comments on commit 397eaa9

Please sign in to comment.