Unverified Commit c05808b2 authored by Dimitris Koutsogiorgas's avatar Dimitris Koutsogiorgas Committed by GitHub

Merge pull request #7116 from dnkoutso/better_header_search_paths

Set direct and transitive dependency header search paths for pod targets
parents 29af0c96 d9bfbc1b
......@@ -8,7 +8,13 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements
* None.
* Set direct and transitive dependency header search paths for pod targets
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#7116](https://github.com/CocoaPods/CocoaPods/pull/7116)
* Log target names missing host for libraries
[Keith Smiley](https://github.com/keith)
[#7346](https://github.com/CocoaPods/CocoaPods/pull/7346)
##### Bug Fixes
......@@ -19,10 +25,6 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements
* Log target names missing host for libraries
[Keith Smiley](https://github.com/keith)
[#7346](https://github.com/CocoaPods/CocoaPods/pull/7346)
* Show warning when Pod source uses unencrypted HTTP
[KrauseFx](https://github.com/KrauseFx)
[#7293](https://github.com/CocoaPods/CocoaPods/issues/7293)
......
......@@ -44,14 +44,10 @@ module Pod
# @return [Xcodeproj::Config]
#
def generate
target_search_paths = target.build_headers.search_paths(target.platform)
sandbox_search_paths = target.sandbox.public_headers.search_paths(target.platform)
search_paths = target_search_paths.concat(sandbox_search_paths).uniq
config = {
'FRAMEWORK_SEARCH_PATHS' => '$(inherited) ',
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1',
'HEADER_SEARCH_PATHS' => XCConfigHelper.quote(search_paths),
'HEADER_SEARCH_PATHS' => XCConfigHelper.quote(target.header_search_paths(@test_xcconfig)),
'LIBRARY_SEARCH_PATHS' => '$(inherited) ',
'OTHER_LDFLAGS' => XCConfigHelper.default_ld_flags(target, @test_xcconfig),
'PODS_ROOT' => '${SRCROOT}',
......
......@@ -4,6 +4,8 @@ module Pod
# the header search paths.
#
class HeadersStore
SEARCH_PATHS_KEY = Struct.new(:platform_name, :target_name)
# @return [Pathname] the absolute path of this header directory.
#
def root
......@@ -24,21 +26,32 @@ module Pod
@sandbox = sandbox
@relative_path = relative_path
@search_paths = []
@search_paths_cache = {}
end
# @param [Platform] platform
# the platform for which the header search paths should be
# returned
#
# @param [String] target_name
# the target for which the header search paths should be
# returned. This will return only header root scope e.g. `${PODS_ROOT}/Headers/Public`
# if the target name specified is `nil`.
#
# @return [Array<String>] All the search paths of the header directory in
# xcconfig format. The paths are specified relative to the pods
# root with the `${PODS_ROOT}` variable.
#
def search_paths(platform)
platform_search_paths = @search_paths.select { |entry| entry[:platform] == platform.name }
def search_paths(platform, target_name = nil)
key = SEARCH_PATHS_KEY.new(platform.name, target_name)
return @search_paths_cache[key] if @search_paths_cache.key?(key)
platform_search_paths = @search_paths.select do |entry|
matches_platform = entry[:platform] == platform.name
matches_target = target_name.nil? || (entry[:path].basename.to_s == target_name)
matches_platform && matches_target
end
headers_dir = root.relative_path_from(sandbox.root).dirname
["${PODS_ROOT}/#{headers_dir}/#{@relative_path}"] + platform_search_paths.uniq.map { |entry| "${PODS_ROOT}/#{headers_dir}/#{entry[:path]}" }
@search_paths_cache[key] = ["${PODS_ROOT}/#{headers_dir}/#{@relative_path}"] + platform_search_paths.uniq.map { |entry| "${PODS_ROOT}/#{headers_dir}/#{entry[:path]}" }
end
# Removes the directory as it is regenerated from scratch during each
......
......@@ -567,6 +567,23 @@ module Pod
[version.major, version.minor, version.patch].join('.')
end
# @param [Boolean] include_test_dependent_targets
# whether to include header search paths for test dependent targets
#
# @return [Array<String>] The set of header search paths this target uses.
#
def header_search_paths(include_test_dependent_targets = false)
header_search_paths = []
header_search_paths.concat(build_headers.search_paths(platform))
header_search_paths.concat(sandbox.public_headers.search_paths(platform, pod_name))
dependent_targets = recursive_dependent_targets
dependent_targets += recursive_test_dependent_targets if include_test_dependent_targets
dependent_targets.each do |dependent_target|
header_search_paths.concat(sandbox.public_headers.search_paths(platform, dependent_target.pod_name))
end
header_search_paths.uniq
end
private
# @param [TargetDefinition] target_definition
......
Subproject commit b41bd0e2643e317b892d6ce73d7841c6624da56d
Subproject commit 5ec8622af1b9adb969d66b5b01bb88e016bca627
......@@ -137,12 +137,12 @@ module Pod
end
it 'adds the sandbox public headers search paths to the xcconfig, with quotes, as header search paths' do
expected = "$(inherited) \"#{config.sandbox.public_headers.search_paths(:ios).join('" "')}\""
expected = "$(inherited) \"#{config.sandbox.public_headers.search_paths(Platform.ios).join('" "')}\""
@xcconfig.to_hash['HEADER_SEARCH_PATHS'].should == expected
end
it 'adds the sandbox public headers search paths to the xcconfig, with quotes, as system headers' do
expected = "$(inherited) -isystem \"#{config.sandbox.public_headers.search_paths(:ios).join('" -isystem "')}\""
expected = "$(inherited) -isystem \"#{config.sandbox.public_headers.search_paths(Platform.ios).join('" -isystem "')}\""
@xcconfig.to_hash['OTHER_CFLAGS'].should == expected
end
......
......@@ -27,6 +27,7 @@ module Pod
)
vendored_dep_target = stub(
:name => 'BananaLib',
:pod_name => 'BananaLib',
:sandbox => config.sandbox,
:should_build? => false,
:requires_frameworks? => true,
......@@ -133,8 +134,8 @@ module Pod
end
it 'adds the library build headers and public headers search paths to the xcconfig, with quotes' do
private_headers = "\"#{@pod_target.build_headers.search_paths(:ios).join('" "')}\""
public_headers = "\"#{config.sandbox.public_headers.search_paths(:ios).join('" "')}\""
private_headers = "\"#{@pod_target.build_headers.search_paths(Platform.new(:ios)).join('" "')}\""
public_headers = "\"#{config.sandbox.public_headers.search_paths(Platform.new(:ios)).join('" "')}\""
@xcconfig.to_hash['HEADER_SEARCH_PATHS'].should.include private_headers
@xcconfig.to_hash['HEADER_SEARCH_PATHS'].should.include public_headers
end
......@@ -257,6 +258,37 @@ module Pod
xcconfig.to_hash['LIBRARY_SEARCH_PATHS'].should == '$(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/BananaLib" "${PODS_CONFIGURATION_BUILD_DIR}/CoconutLib" "${PODS_ROOT}/../../spec/fixtures/banana-lib"'
end
it 'adds correct header search paths for dependent and test targets' do
@monkey_pod_target.build_headers.add_search_path('monkey', Platform.ios)
@monkey_pod_target.sandbox.public_headers.add_search_path('monkey', Platform.ios)
@banana_pod_target.build_headers.add_search_path('BananaLib', Platform.ios)
@banana_pod_target.sandbox.public_headers.add_search_path('BananaLib', Platform.ios)
@coconut_pod_target.build_headers.add_search_path('CoconutLib', Platform.ios)
@coconut_pod_target.sandbox.public_headers.add_search_path('CoconutLib', Platform.ios)
@coconut_pod_target.test_dependent_targets = [@monkey_pod_target]
@coconut_pod_target.dependent_targets = [@banana_pod_target]
generator = PodXCConfig.new(@coconut_pod_target, true)
xcconfig = generator.generate
xcconfig.to_hash['HEADER_SEARCH_PATHS'].should == '"${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/CoconutLib"' \
' "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BananaLib" "${PODS_ROOT}/Headers/Public/CoconutLib" "${PODS_ROOT}/Headers/Public/monkey"'
end
it 'adds correct header search paths for dependent and test targets for non test xcconfigs' do
@monkey_pod_target.build_headers.add_search_path('monkey', Platform.ios)
@monkey_pod_target.sandbox.public_headers.add_search_path('monkey', Platform.ios)
@banana_pod_target.build_headers.add_search_path('BananaLib', Platform.ios)
@banana_pod_target.sandbox.public_headers.add_search_path('BananaLib', Platform.ios)
@coconut_pod_target.build_headers.add_search_path('CoconutLib', Platform.ios)
@coconut_pod_target.sandbox.public_headers.add_search_path('CoconutLib', Platform.ios)
@coconut_pod_target.test_dependent_targets = [@monkey_pod_target]
@coconut_pod_target.dependent_targets = [@banana_pod_target]
# This is not an test xcconfig so it should exclude header search paths for the 'monkey' pod
generator = PodXCConfig.new(@coconut_pod_target, false)
xcconfig = generator.generate
xcconfig.to_hash['HEADER_SEARCH_PATHS'].should == '"${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/CoconutLib"' \
' "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/BananaLib" "${PODS_ROOT}/Headers/Public/CoconutLib"'
end
it 'does not include other ld flags for test dependent targets if its not a test xcconfig' do
@coconut_pod_target.test_dependent_targets = [@monkey_pod_target]
generator = PodXCConfig.new(@coconut_pod_target)
......
......@@ -38,12 +38,14 @@ module Pod
relative_header_paths.each do |path|
File.open(@sandbox.root + path, 'w') { |file| file.write('hello') }
end
fake_platform = mock(:name => 'fake_platform')
@header_dir.add_files(namespace_path, relative_header_paths)
@header_dir.search_paths(:fake_platform).should.not.include('${PODS_ROOT}/Headers/Public/ExampleLib')
@header_dir.search_paths(fake_platform).should.not.include('${PODS_ROOT}/Headers/Public/ExampleLib')
end
it 'always adds the Headers root to the header search paths' do
@header_dir.search_paths(:fake_platform).should.include('${PODS_ROOT}/Headers/Public')
fake_platform = mock(:name => 'fake_platform')
@header_dir.search_paths(fake_platform).should.include('${PODS_ROOT}/Headers/Public')
end
it 'only exposes header search paths for the given platform' do
......@@ -54,5 +56,18 @@ module Pod
'${PODS_ROOT}/Headers/Public/iOS Search Path',
]
end
it 'returns the correct header search paths given platform and target' do
@header_dir.add_search_path('ios-target', Platform.ios)
@header_dir.add_search_path('osx-target', Platform.osx)
@header_dir.search_paths(Platform.ios, 'ios-target').sort.should == [
'${PODS_ROOT}/Headers/Public',
'${PODS_ROOT}/Headers/Public/ios-target',
]
@header_dir.search_paths(Platform.osx, 'osx-target').sort.should == [
'${PODS_ROOT}/Headers/Public',
'${PODS_ROOT}/Headers/Public/osx-target',
]
end
end
end
......@@ -7,7 +7,7 @@ module Pod
@target_definition = Podfile::TargetDefinition.new('Pods', nil)
@target_definition.abstract = false
@pod_target = PodTarget.new([spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(:ios)
@pod_target.stubs(:platform).returns(Platform.ios)
end
describe 'Meta' do
......@@ -233,6 +233,54 @@ module Pod
it 'returns prefix header path' do
@pod_target.prefix_header_path.to_s.should.include 'Pods/Target Support Files/BananaLib/BananaLib-prefix.pch'
end
it 'returns the correct header search paths' do
@pod_target.build_headers.add_search_path('BananaLib', Platform.ios)
@pod_target.sandbox.public_headers.add_search_path('BananaLib', Platform.ios)
header_search_paths = @pod_target.header_search_paths
header_search_paths.sort.should == [
'${PODS_ROOT}/Headers/Private',
'${PODS_ROOT}/Headers/Private/BananaLib',
'${PODS_ROOT}/Headers/Public',
'${PODS_ROOT}/Headers/Public/BananaLib',
]
end
it 'returns the correct header search paths recursively for dependent targets' do
@pod_target.build_headers.add_search_path('BananaLib', Platform.ios)
@pod_target.sandbox.public_headers.add_search_path('BananaLib', Platform.ios)
@pod_target.sandbox.public_headers.add_search_path('monkey', Platform.ios)
monkey_spec = fixture_spec('monkey/monkey.podspec')
monkey_pod_target = PodTarget.new([monkey_spec], [@target_definition], config.sandbox)
monkey_pod_target.stubs(:platform).returns(Platform.ios)
@pod_target.stubs(:dependent_targets).returns([monkey_pod_target])
header_search_paths = @pod_target.header_search_paths
header_search_paths.sort.should == [
'${PODS_ROOT}/Headers/Private',
'${PODS_ROOT}/Headers/Private/BananaLib',
'${PODS_ROOT}/Headers/Public',
'${PODS_ROOT}/Headers/Public/BananaLib',
'${PODS_ROOT}/Headers/Public/monkey',
]
end
it 'returns the correct header search paths recursively for dependent targets excluding platform' do
@pod_target.build_headers.add_search_path('BananaLib', Platform.ios)
@pod_target.sandbox.public_headers.add_search_path('BananaLib', Platform.ios)
@pod_target.sandbox.public_headers.add_search_path('monkey', Platform.osx)
monkey_spec = fixture_spec('monkey/monkey.podspec')
monkey_pod_target = PodTarget.new([monkey_spec], [@target_definition], config.sandbox)
monkey_pod_target.stubs(:platform).returns(Platform.ios)
@pod_target.stubs(:dependent_targets).returns([monkey_pod_target])
header_search_paths = @pod_target.header_search_paths
# The monkey lib header search paths should not be present since they are only present in OSX.
header_search_paths.sort.should == [
'${PODS_ROOT}/Headers/Private',
'${PODS_ROOT}/Headers/Private/BananaLib',
'${PODS_ROOT}/Headers/Public',
'${PODS_ROOT}/Headers/Public/BananaLib',
]
end
end
describe 'Product type dependent helpers' do
......
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