Commit 3868eba8 authored by Jeremy Slater's avatar Jeremy Slater

Add Pods integration library

Adds the libPods.a and target derivatives back as targets in the Pods 
project.  The integration libraries are simple containers linked with 
all of the per spec libraries to create a single library for the user 
project to link with.  The xcconfig file for the integration library 
merges namespaced config settings for all dependent specs for use by 
the user project.
parent c9235c6d
......@@ -55,24 +55,52 @@ module Pod
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(library.build_headers.search_paths),
'PODS_PUBLIC_HEADERS_SEARCH_PATHS' => quote(public_headers),
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1'
})
spec_consumers.each do |consumer|
add_spec_build_settings_to_xcconfig(consumer, @xcconfig)
# 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.
if library.spec
prefix = library.xcconfig_prefix
config = {
'ALWAYS_SEARCH_USER_PATHS' => 'YES',
'OTHER_LDFLAGS' => ld_flags,
'HEADER_SEARCH_PATHS' => '${PODS_HEADERS_SEARCH_PATHS}',
'PODS_ROOT' => '${SRCROOT}',
'PODS_HEADERS_SEARCH_PATHS' => '${PODS_BUILD_HEADERS_SEARCH_PATHS} ${PODS_PUBLIC_HEADERS_SEARCH_PATHS}',
'PODS_BUILD_HEADERS_SEARCH_PATHS' => quote(library.build_headers.search_paths),
'PODS_PUBLIC_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|
config[k] = "#{config[k]} ${#{library.xcconfig_prefix}#{k}}"
config["#{library.xcconfig_prefix}#{k}"] = 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',
'USE_HEADERMAP' => '$(inherited)'
}
library.libraries.each do |lib|
consumer_xcconfig(lib.consumer).to_hash.each do |k, v|
config[k] = "#{config[k]} ${#{lib.xcconfig_prefix}#{k}}"
end
end
end
@xcconfig = Xcodeproj::Config.new(config)
@xcconfig.includes = library.libraries.map(&:name) unless library.spec
@xcconfig
end
......@@ -80,15 +108,6 @@ module Pod
#
attr_reader :xcconfig
# @return [Hash] The settings of the xcconfig that the Pods project
# needs to override.
#
def self.pods_project_settings
{ 'PODS_ROOT' => '${SRCROOT}',
'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.
#
# @param [Pathname] path
......@@ -143,12 +162,14 @@ module Pod
#
# @return [void]
#
def add_spec_build_settings_to_xcconfig(consumer, xcconfig)
def consumer_xcconfig(consumer)
xcconfig = Xcodeproj::Config.new()
xcconfig.merge!(consumer.xcconfig)
xcconfig.libraries.merge(consumer.libraries)
xcconfig.frameworks.merge(consumer.frameworks)
xcconfig.weak_frameworks.merge(consumer.weak_frameworks)
add_developers_frameworks_if_needed(consumer, xcconfig)
xcconfig
end
# @return [Array<String>] The search paths for the developer frameworks.
......
......@@ -186,10 +186,10 @@ module Pod
# @todo [#247] Clean the headers of only the pods to install.
#
def clean_sandbox
sandbox.public_headers.implode!
targets.each do |target|
target.libraries.each do |library|
library.build_headers.implode!
library.public_headers.implode!
end
end
......@@ -247,7 +247,7 @@ module Pod
def install_source_of_pod(pod_name)
specs_by_platform = {}
libraries.each do |library|
if library.spec.root.name == pod_name
if library.spec && library.spec.root.name == pod_name
specs_by_platform[library.platform] ||= []
specs_by_platform[library.platform] << library.spec
end
......@@ -553,7 +553,7 @@ module Pod
# process.
#
def libraries
targets.map(&:libraries).flatten
targets + targets.map(&:libraries).flatten
end
#-------------------------------------------------------------------------#
......
......@@ -203,6 +203,9 @@ module Pod
lib.client_root = config.installation_root
lib.user_target_uuids = []
lib.user_build_configurations = {}
target.client_root = config.installation_root
target.user_target_uuids = []
target.user_build_configurations = {}
end
target.libraries << lib
end
......
......@@ -111,14 +111,14 @@ module Pod
library.file_accessors.each do |file_accessor|
headers_sandbox = Pathname.new(file_accessor.spec.root.name)
library.build_headers.add_search_path(headers_sandbox)
library.public_headers.add_search_path(headers_sandbox)
sandbox.public_headers.add_search_path(headers_sandbox)
header_mappings(headers_sandbox, file_accessor, file_accessor.headers).each do |namespaced_path, files|
library.build_headers.add_files(namespaced_path, files)
end
header_mappings(headers_sandbox, file_accessor, file_accessor.public_headers).each do |namespaced_path, files|
library.public_headers.add_files(namespaced_path, files)
sandbox.public_headers.add_files(namespaced_path, files)
end
end
end
......
......@@ -148,9 +148,6 @@ module Pod
target.build_configurations.each do |c|
c.base_configuration_reference = xcconfig_file_ref
Generator::XCConfig.pods_project_settings.each do |key, value|
c.build_settings[key] = value
end
end
end
end
......@@ -161,7 +158,7 @@ module 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.spec])
generator = Generator::TargetEnvironmentHeader.new(library.libraries.map { |l| l.spec })
generator.save_as(path)
add_file_to_support_group(path)
end
......
......@@ -27,12 +27,11 @@ module Pod
#
def integrate!
UI.section(integration_message) do
create_xcconfig_file
add_xcconfig_base_configuration
add_pods_library
add_copy_resources_script_phase
add_check_manifest_lock_script_phase
save_user_project
save_projects
end
end
......@@ -49,6 +48,13 @@ module Pod
@user_project ||= Xcodeproj::Project.new(target.user_project_path)
end
# Read the pods project from the disk to ensure that it is up to date as
# other TargetIntegrators might have modified it.
#
def pods_project
@pods_project ||= Xcodeproj::Project.new(target.sandbox.project_path)
end
# @return [String] a string representation suitable for debugging.
#
def inspect
......@@ -67,23 +73,6 @@ module Pod
@spec_consumers ||= target.libraries.map(&:file_accessors).flatten.map(&:spec_consumer)
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 = target.xcconfig_path
UI.message "- Generating xcconfig file at #{UI.path(path)}" do
gen = Generator::XCConfig.new(target, spec_consumers, target.relative_pods_root)
gen.set_arc_compatibility_flag = target.target_definition.podfile.set_arc_compatibility_flag?
gen.save_as(path)
target.xcconfig = gen.xcconfig
end
end
# Adds the `xcconfig` configurations files generated for the current
# {TargetDefinition} to the build configurations of the targets that
# should be integrated.
......@@ -108,20 +97,27 @@ module Pod
end
end
# Adds a file reference to the library of the {TargetDefinition} and
# adds it to the frameworks build phase of the targets.
# Adds spec libraries to the frameworks build phase of the
# {TargetDefinition} integration libraries. Adds a file reference to
# the library of the {TargetDefinition} and adds it to the frameworks
# build phase of the targets.
#
# @return [void]
#
def add_pods_library
native_target = pods_project.targets.select { |t| t.name == target.name }.first
products = pods_project.products_group
target.libraries.each do |library|
product = products.files.select { |f| f.path == library.product_name }.first
native_target.frameworks_build_phase.add_file_reference(product)
end
frameworks = user_project.frameworks_group
native_targets.each do |native_target|
target.libraries.each do |library|
lib = frameworks.files.select { |f| f.path == library.product_name }.first ||
frameworks.new_static_library(library.name)
unless native_target.frameworks_build_phase.files_references.include?(lib)
native_target.frameworks_build_phase.add_file_reference(lib)
end
library = frameworks.files.select { |f| f.path == target.product_name }.first ||
frameworks.new_static_library(target.name)
unless native_target.frameworks_build_phase.files_references.include?(library)
native_target.frameworks_build_phase.add_file_reference(library)
end
end
end
......@@ -133,14 +129,13 @@ module Pod
# @return [void]
#
def add_copy_resources_script_phase
phase_name = "Copy Pods Resources"
native_targets.each do |native_target|
target.libraries.each do |library|
phase_name = "Copy Pods Resources (#{library.name})"
next if native_target.shell_script_build_phases.select { |bp| bp.name == phase_name }.first
phase = native_target.new_shell_script_build_phase(phase_name)
path = library.copy_resources_script_relative_path
phase.shell_script = %{"#{path}"\n}
end
phase = native_target.shell_script_build_phases.select { |bp| bp.name == phase_name }.first ||
native_target.new_shell_script_build_phase(phase_name)
phase.shell_script = target.libraries.map do |lib|
"#{lib.copy_resources_script_relative_path}"
end.join("\n")
end
end
......@@ -176,8 +171,9 @@ module Pod
#
# @return [void]
#
def save_user_project
def save_projects
user_project.save_as(target.user_project_path)
pods_project.save_as(target.sandbox.project_path)
end
#---------------------------------------------------------------------#
......
......@@ -55,10 +55,6 @@ module Pod
#
attr_reader :root
# @return [HeadersStore] the header directory for the Pods libraries.
#
attr_reader :build_headers
# @return [HeadersStore] the header directory for the user targets.
#
attr_reader :public_headers
......@@ -67,7 +63,6 @@ module Pod
#
def initialize(root)
@root = Pathname.new(root)
@build_headers = HeadersStore.new(self, "BuildHeaders")
@public_headers = HeadersStore.new(self, "Headers")
@predownloaded_pods = []
@checkout_sources = {}
......
......@@ -21,19 +21,15 @@ module Pod
#
attr_reader :build_headers
# @return [HeadersStore] the public header directory for the library.
#
attr_reader :public_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/#{target_definition.name}")
@public_headers = Sandbox::HeadersStore.new(sandbox, "Headers/#{target_definition.name}")
@build_headers = Sandbox::HeadersStore.new(sandbox, "BuildHeaders")
@libraries = []
@file_accessors = []
end
# @return [String] the label for the library.
......@@ -54,6 +50,12 @@ module Pod
"lib#{label}.a"
end
# @return [String] the XCConfig namespaced prefix.
#
def xcconfig_prefix
label.upcase.gsub(/[^A-Z]/, '_') + '_'
end
# @return [String] A string suitable for debugging.
#
def inspect
......@@ -201,6 +203,12 @@ module Pod
"${SRCROOT}/#{relative_to_srcroot(copy_resources_script_path)}"
end
# @return [Specification::Consumer] the specification consumer for the
# library.
#
def consumer
spec.consumer(platform)
end
#-------------------------------------------------------------------------#
# @!group Private Helpers
......
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