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` ...@@ -8,7 +8,13 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements ##### 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 ##### Bug Fixes
...@@ -19,10 +25,6 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -19,10 +25,6 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Enhancements ##### 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 * Show warning when Pod source uses unencrypted HTTP
[KrauseFx](https://github.com/KrauseFx) [KrauseFx](https://github.com/KrauseFx)
[#7293](https://github.com/CocoaPods/CocoaPods/issues/7293) [#7293](https://github.com/CocoaPods/CocoaPods/issues/7293)
......
...@@ -44,14 +44,10 @@ module Pod ...@@ -44,14 +44,10 @@ module Pod
# @return [Xcodeproj::Config] # @return [Xcodeproj::Config]
# #
def generate 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 = { config = {
'FRAMEWORK_SEARCH_PATHS' => '$(inherited) ', 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) ',
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1', '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) ', 'LIBRARY_SEARCH_PATHS' => '$(inherited) ',
'OTHER_LDFLAGS' => XCConfigHelper.default_ld_flags(target, @test_xcconfig), 'OTHER_LDFLAGS' => XCConfigHelper.default_ld_flags(target, @test_xcconfig),
'PODS_ROOT' => '${SRCROOT}', 'PODS_ROOT' => '${SRCROOT}',
......
...@@ -4,6 +4,8 @@ module Pod ...@@ -4,6 +4,8 @@ module Pod
# the header search paths. # the header search paths.
# #
class HeadersStore class HeadersStore
SEARCH_PATHS_KEY = Struct.new(:platform_name, :target_name)
# @return [Pathname] the absolute path of this header directory. # @return [Pathname] the absolute path of this header directory.
# #
def root def root
...@@ -24,21 +26,32 @@ module Pod ...@@ -24,21 +26,32 @@ module Pod
@sandbox = sandbox @sandbox = sandbox
@relative_path = relative_path @relative_path = relative_path
@search_paths = [] @search_paths = []
@search_paths_cache = {}
end end
# @param [Platform] platform # @param [Platform] platform
# the platform for which the header search paths should be # the platform for which the header search paths should be
# returned # 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 # @return [Array<String>] All the search paths of the header directory in
# xcconfig format. The paths are specified relative to the pods # xcconfig format. The paths are specified relative to the pods
# root with the `${PODS_ROOT}` variable. # root with the `${PODS_ROOT}` variable.
# #
def search_paths(platform) def search_paths(platform, target_name = nil)
platform_search_paths = @search_paths.select { |entry| entry[:platform] == platform.name } 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 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 end
# Removes the directory as it is regenerated from scratch during each # Removes the directory as it is regenerated from scratch during each
......
...@@ -567,6 +567,23 @@ module Pod ...@@ -567,6 +567,23 @@ module Pod
[version.major, version.minor, version.patch].join('.') [version.major, version.minor, version.patch].join('.')
end 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 private
# @param [TargetDefinition] target_definition # @param [TargetDefinition] target_definition
......
Subproject commit b41bd0e2643e317b892d6ce73d7841c6624da56d Subproject commit 5ec8622af1b9adb969d66b5b01bb88e016bca627
...@@ -137,12 +137,12 @@ module Pod ...@@ -137,12 +137,12 @@ module Pod
end end
it 'adds the sandbox public headers search paths to the xcconfig, with quotes, as header search paths' do 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 @xcconfig.to_hash['HEADER_SEARCH_PATHS'].should == expected
end end
it 'adds the sandbox public headers search paths to the xcconfig, with quotes, as system headers' do 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 @xcconfig.to_hash['OTHER_CFLAGS'].should == expected
end end
......
...@@ -27,6 +27,7 @@ module Pod ...@@ -27,6 +27,7 @@ module Pod
) )
vendored_dep_target = stub( vendored_dep_target = stub(
:name => 'BananaLib', :name => 'BananaLib',
:pod_name => 'BananaLib',
:sandbox => config.sandbox, :sandbox => config.sandbox,
:should_build? => false, :should_build? => false,
:requires_frameworks? => true, :requires_frameworks? => true,
...@@ -133,8 +134,8 @@ module Pod ...@@ -133,8 +134,8 @@ module Pod
end end
it 'adds the library build headers and public headers search paths to the xcconfig, with quotes' do 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('" "')}\"" private_headers = "\"#{@pod_target.build_headers.search_paths(Platform.new(:ios)).join('" "')}\""
public_headers = "\"#{config.sandbox.public_headers.search_paths(: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 private_headers
@xcconfig.to_hash['HEADER_SEARCH_PATHS'].should.include public_headers @xcconfig.to_hash['HEADER_SEARCH_PATHS'].should.include public_headers
end end
...@@ -257,6 +258,37 @@ module Pod ...@@ -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"' 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 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 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] @coconut_pod_target.test_dependent_targets = [@monkey_pod_target]
generator = PodXCConfig.new(@coconut_pod_target) generator = PodXCConfig.new(@coconut_pod_target)
......
...@@ -38,12 +38,14 @@ module Pod ...@@ -38,12 +38,14 @@ module Pod
relative_header_paths.each do |path| relative_header_paths.each do |path|
File.open(@sandbox.root + path, 'w') { |file| file.write('hello') } File.open(@sandbox.root + path, 'w') { |file| file.write('hello') }
end end
fake_platform = mock(:name => 'fake_platform')
@header_dir.add_files(namespace_path, relative_header_paths) @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 end
it 'always adds the Headers root to the header search paths' do 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 end
it 'only exposes header search paths for the given platform' do it 'only exposes header search paths for the given platform' do
...@@ -54,5 +56,18 @@ module Pod ...@@ -54,5 +56,18 @@ module Pod
'${PODS_ROOT}/Headers/Public/iOS Search Path', '${PODS_ROOT}/Headers/Public/iOS Search Path',
] ]
end 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
end end
...@@ -7,7 +7,7 @@ module Pod ...@@ -7,7 +7,7 @@ module Pod
@target_definition = Podfile::TargetDefinition.new('Pods', nil) @target_definition = Podfile::TargetDefinition.new('Pods', nil)
@target_definition.abstract = false @target_definition.abstract = false
@pod_target = PodTarget.new([spec], [@target_definition], config.sandbox) @pod_target = PodTarget.new([spec], [@target_definition], config.sandbox)
@pod_target.stubs(:platform).returns(:ios) @pod_target.stubs(:platform).returns(Platform.ios)
end end
describe 'Meta' do describe 'Meta' do
...@@ -233,6 +233,54 @@ module Pod ...@@ -233,6 +233,54 @@ module Pod
it 'returns prefix header path' do it 'returns prefix header path' do
@pod_target.prefix_header_path.to_s.should.include 'Pods/Target Support Files/BananaLib/BananaLib-prefix.pch' @pod_target.prefix_header_path.to_s.should.include 'Pods/Target Support Files/BananaLib/BananaLib-prefix.pch'
end 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 end
describe 'Product type dependent helpers' do 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