Skip to content

Commit

Permalink
Move Specification#install! to the installer and move TargetInstaller…
Browse files Browse the repository at this point in the history
… to its own file.
  • Loading branch information
alloy committed Nov 26, 2011
1 parent 2f29463 commit ef9ac10
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 161 deletions.
146 changes: 10 additions & 136 deletions lib/cocoapods/installer.rb
@@ -1,5 +1,7 @@
module Pod
class Installer
autoload :TargetInstaller, 'cocoapods/installer/target_installer'

module Shared
def dependent_specifications
@dependent_specifications ||= Resolver.new(@podfile, @definition ? @definition.dependencies : nil).resolve
Expand All @@ -16,137 +18,6 @@ def download_only_specifications
end
end

class TargetInstaller
include Config::Mixin
include Shared

attr_reader :podfile, :project, :definition, :target

def initialize(podfile, project, definition)
@podfile, @project, @definition = podfile, project, definition
end

def xcconfig
@xcconfig ||= Xcodeproj::Config.new({
# In a workspace this is where the static library headers should be found.
'PODS_ROOT' => '"$(SRCROOT)/Pods"',
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers"',
'ALWAYS_SEARCH_USER_PATHS' => 'YES', # needed to make EmbedReader build
# This makes categories from static libraries work, which many libraries
# require, so we add these by default.
'OTHER_LDFLAGS' => '-ObjC -all_load',
})
end

def xcconfig_filename
"#{@definition.lib_name}.xcconfig"
end

def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new(build_specifications.map do |spec|
spec.expanded_resources
end.flatten)
end

def copy_resources_filename
"#{@definition.lib_name}-resources.sh"
end

def bridge_support_generator
Generator::BridgeSupport.new(build_specifications.map do |spec|
spec.header_files.map do |header|
config.project_pods_root + header
end
end.flatten)
end

def bridge_support_filename
"#{@definition.lib_name}.bridgesupport"
end

# TODO move out to Generator::PrefixHeader
def save_prefix_header_as(pathname)
pathname.open('w') do |header|
header.puts "#ifdef __OBJC__"
header.puts "#import #{@podfile.platform == :ios ? '<UIKit/UIKit.h>' : '<Cocoa/Cocoa.h>'}"
header.puts "#endif"
end
end

def prefix_header_filename
"#{@definition.lib_name}-prefix.pch"
end

def headers_symlink_path_name
"#{config.project_pods_root}/Headers"
end

# TODO move xcconfig related code into the xcconfig method, like copy_resources_script and generate_bridge_support.
def install!
# First add the target to the project
@target = @project.targets.new_static_library(@definition.lib_name)

# Clean old header symlinks
FileUtils.rm_r(headers_symlink_path_name, :secure => true) if File.exists?(headers_symlink_path_name)

header_search_paths = []
build_specifications.each do |spec|
xcconfig.merge!(spec.xcconfig)
# Only add implementation files to the compile phase
spec.implementation_files.each do |file|
@target.add_source_file(file, nil, spec.compiler_flags)
end
# Symlink header files to Pods/Headers
spec.copy_header_mappings.each do |header_dir, files|
target_dir = "#{headers_symlink_path_name}/#{header_dir}"
FileUtils.mkdir_p(target_dir)
target_dir_real_path = Pathname.new(target_dir).realpath
files.each do |file|
source = Pathname.new("#{config.project_pods_root}/#{file}").realpath.relative_path_from(target_dir_real_path)
Dir.chdir(target_dir) do
FileUtils.ln_sf(source, File.basename(file))
end
end
end
# Collect all header search paths
header_search_paths.concat(spec.header_search_paths)
end
xcconfig.merge!('HEADER_SEARCH_PATHS' => header_search_paths.sort.uniq.join(" "))

# Now that we have added all the source files and copy header phases,
# move the compile build phase to the end, so that headers are copied
# to the build products dir first, and thus Pod source files can enjoy
# the same namespacing of headers as the app would.
@target.move_compile_phase_to_end!

# Add all the target related support files to the group, even the copy
# resources script although the project doesn't actually use them.
support_files_group = @project.groups.find do |group|
group.name == "Targets Support Files"
end.groups.new("name" => @definition.lib_name)
support_files_group.files.new('path' => copy_resources_filename)
prefix_file = support_files_group.files.new('path' => prefix_header_filename)
xcconfig_file = support_files_group.files.new("path" => xcconfig_filename)
# Assign the xcconfig as the base config of each config.
@target.buildConfigurations.each do |config|
config.baseConfiguration = xcconfig_file
config.buildSettings['OTHER_LDFLAGS'] = ''
config.buildSettings['GCC_PREFIX_HEADER'] = prefix_header_filename
config.buildSettings['PODS_ROOT'] = '$(SRCROOT)'
end
end

def create_files_in(root)
xcconfig.save_as(root + xcconfig_filename)
if @podfile.generate_bridge_support?
bridge_support_generator.save_as(root + bridge_support_filename)
copy_resources_script.resources << bridge_support_filename
end
save_prefix_header_as(root + prefix_header_filename)
copy_resources_script.save_as(root + copy_resources_filename)
end
end

include Config::Mixin
include Shared

Expand Down Expand Up @@ -188,7 +59,11 @@ def install_dependencies!
puts "Using #{spec}" unless config.silent?
else
puts "Installing #{spec}" unless config.silent?
spec.download!
spec = spec.part_of_specification if spec.part_of_other_pod?
downloader = Downloader.for_source(spec.pod_destroot, spec.source)
downloader.download
# TODO move cleaning into the installer as well
downloader.clean(spec.expanded_clean_paths) if config.clean
end
end
end
Expand All @@ -198,23 +73,22 @@ def install!
install_dependencies!
root = config.project_pods_root

puts "==> Generating support files" unless config.silent?
puts "Generating support files..." unless config.silent?
target_installers.each do |target_installer|
target_installer.install!
target_installer.create_files_in(root)
end
generate_lock_file!

puts "==> Running post install hooks" unless config.silent?
puts "* Running post install hooks" if config.verbose?
# Post install hooks run _before_ saving of project, so that they can alter it before saving.
target_installers.each do |target_installer|
target_installer.build_specifications.each { |spec| spec.post_install(target_installer) }
end
@podfile.post_install!(self)

puts "==> Generating Xcode project" unless config.silent?
projpath = File.join(root, 'Pods.xcodeproj')
puts " * Writing Xcode project file to `#{projpath}'" if config.verbose?
puts "* Writing Xcode project file to `#{projpath}'" if config.verbose?
project.save_as(projpath)
end

Expand Down
135 changes: 135 additions & 0 deletions lib/cocoapods/installer/target_installer.rb
@@ -0,0 +1,135 @@
module Pod
class Installer
class TargetInstaller
include Config::Mixin
include Shared

attr_reader :podfile, :project, :definition, :target

def initialize(podfile, project, definition)
@podfile, @project, @definition = podfile, project, definition
end

def xcconfig
@xcconfig ||= Xcodeproj::Config.new({
# In a workspace this is where the static library headers should be found.
'PODS_ROOT' => '"$(SRCROOT)/Pods"',
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Headers"',
'ALWAYS_SEARCH_USER_PATHS' => 'YES', # needed to make EmbedReader build
# This makes categories from static libraries work, which many libraries
# require, so we add these by default.
'OTHER_LDFLAGS' => '-ObjC -all_load',
})
end

def xcconfig_filename
"#{@definition.lib_name}.xcconfig"
end

def copy_resources_script
@copy_resources_script ||= Generator::CopyResourcesScript.new(build_specifications.map do |spec|
spec.expanded_resources
end.flatten)
end

def copy_resources_filename
"#{@definition.lib_name}-resources.sh"
end

def bridge_support_generator
Generator::BridgeSupport.new(build_specifications.map do |spec|
spec.header_files.map do |header|
config.project_pods_root + header
end
end.flatten)
end

def bridge_support_filename
"#{@definition.lib_name}.bridgesupport"
end

# TODO move out to Generator::PrefixHeader
def save_prefix_header_as(pathname)
pathname.open('w') do |header|
header.puts "#ifdef __OBJC__"
header.puts "#import #{@podfile.platform == :ios ? '<UIKit/UIKit.h>' : '<Cocoa/Cocoa.h>'}"
header.puts "#endif"
end
end

def prefix_header_filename
"#{@definition.lib_name}-prefix.pch"
end

def headers_symlink_path_name
"#{config.project_pods_root}/Headers"
end

# TODO move xcconfig related code into the xcconfig method, like copy_resources_script and generate_bridge_support.
def install!
# First add the target to the project
@target = @project.targets.new_static_library(@definition.lib_name)

# Clean old header symlinks
FileUtils.rm_r(headers_symlink_path_name, :secure => true) if File.exists?(headers_symlink_path_name)

header_search_paths = []
build_specifications.each do |spec|
xcconfig.merge!(spec.xcconfig)
# Only add implementation files to the compile phase
spec.implementation_files.each do |file|
@target.add_source_file(file, nil, spec.compiler_flags)
end
# Symlink header files to Pods/Headers
spec.copy_header_mappings.each do |header_dir, files|
target_dir = "#{headers_symlink_path_name}/#{header_dir}"
FileUtils.mkdir_p(target_dir)
target_dir_real_path = Pathname.new(target_dir).realpath
files.each do |file|
source = Pathname.new("#{config.project_pods_root}/#{file}").realpath.relative_path_from(target_dir_real_path)
Dir.chdir(target_dir) do
FileUtils.ln_sf(source, File.basename(file))
end
end
end
# Collect all header search paths
header_search_paths.concat(spec.header_search_paths)
end
xcconfig.merge!('HEADER_SEARCH_PATHS' => header_search_paths.sort.uniq.join(" "))

# Now that we have added all the source files and copy header phases,
# move the compile build phase to the end, so that headers are copied
# to the build products dir first, and thus Pod source files can enjoy
# the same namespacing of headers as the app would.
@target.move_compile_phase_to_end!

# Add all the target related support files to the group, even the copy
# resources script although the project doesn't actually use them.
support_files_group = @project.groups.find do |group|
group.name == "Targets Support Files"
end.groups.new("name" => @definition.lib_name)
support_files_group.files.new('path' => copy_resources_filename)
prefix_file = support_files_group.files.new('path' => prefix_header_filename)
xcconfig_file = support_files_group.files.new("path" => xcconfig_filename)
# Assign the xcconfig as the base config of each config.
@target.buildConfigurations.each do |config|
config.baseConfiguration = xcconfig_file
config.buildSettings['OTHER_LDFLAGS'] = ''
config.buildSettings['GCC_PREFIX_HEADER'] = prefix_header_filename
config.buildSettings['PODS_ROOT'] = '$(SRCROOT)'
end
end

def create_files_in(root)
xcconfig.save_as(root + xcconfig_filename)
if @podfile.generate_bridge_support?
bridge_support_generator.save_as(root + bridge_support_filename)
copy_resources_script.resources << bridge_support_filename
end
save_prefix_header_as(root + prefix_header_filename)
copy_resources_script.save_as(root + copy_resources_filename)
end
end
end
end

25 changes: 0 additions & 25 deletions lib/cocoapods/specification.rb
Expand Up @@ -331,31 +331,6 @@ def validate!
end
end

# Install and download hooks

# Downloads the source of the pod and places it in the project's pods
# directory.
#
# Override this if you need to perform work before or after downloading the
# pod, or if you need to implement custom dowloading. Eg:
#
# Pod::Spec.new do |s|
# def s.download!
# # pre-download
# super # or custom downloading
# # post-download
# end
# end
def download!
if spec = part_of_specification
spec.download!
else
downloader = Downloader.for_source(pod_destroot, source)
downloader.download
downloader.clean(expanded_clean_paths) if config.clean
end
end

# This is a convenience method which gets called after all pods have been
# downloaded, installed, and the Xcode project and related files have been
# generated. (It receives the Pod::Installer::Target instance for the current
Expand Down

0 comments on commit ef9ac10

Please sign in to comment.