为啥即使对于私有链接也会继承包含路径

Posted

技术标签:

【中文标题】为啥即使对于私有链接也会继承包含路径【英文标题】:Why include paths are inherited even for private linking为什么即使对于私有链接也会继承包含路径 【发布时间】:2018-05-14 16:51:37 【问题描述】:

我有一个简单的项目,由 2 个“库”ab 和可执行文件 c 组成。我将库 a (PUBLIC) 的包含路径设置为 X(出于测试目的,实际上没有这样的路径)。 现在,ba 私下链接,cb 链接。我希望 X 在编译 c.cpp 时不会出现在包含路径中,因为“它不应该知道 a,因为它在 b 中是私有的”但显然它就在这里。

所以我的问题是它是否是预期的行为以及为什么。

我的代码:

a.cpp

void a() 

b.cpp

void b() 

c.cpp

int main() 

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

add_library(a a.cpp)
target_include_directories(a PUBLIC X)

add_library(b b.cpp)
target_link_libraries(b PRIVATE a)

add_executable(c c.cpp)
target_link_libraries(c PUBLIC b)

(详细)编译日志:

 /usr/local/Cellar/cmake/3.8.1/bin/cmake -H/Users/alexeyd/test/dir -B/Users/alexeyd/test/dir/build --check-build-system CMakeFiles/Makefile.cmake 0
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/Makefile2 c
/usr/local/Cellar/cmake/3.8.1/bin/cmake -H/Users/alexeyd/test/dir -B/Users/alexeyd/test/dir/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_progress_start /Users/alexeyd/test/dir/build/CMakeFiles 6
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/Makefile2 CMakeFiles/c.dir/all
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/a.dir/build.make CMakeFiles/a.dir/depend
cd /Users/alexeyd/test/dir/build && /usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/alexeyd/test/dir /Users/alexeyd/test/dir /Users/alexeyd/test/dir/build /Users/alexeyd/test/dir/build /Users/alexeyd/test/dir/build/CMakeFiles/a.dir/DependInfo.cmake --color=
Dependee "/Users/alexeyd/test/dir/build/CMakeFiles/a.dir/DependInfo.cmake" is newer than depender "/Users/alexeyd/test/dir/build/CMakeFiles/a.dir/depend.internal".
Dependee "/Users/alexeyd/test/dir/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/Users/alexeyd/test/dir/build/CMakeFiles/a.dir/depend.internal".
Scanning dependencies of target a
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/a.dir/build.make CMakeFiles/a.dir/build
[ 16%] Building CXX object CMakeFiles/a.dir/a.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -I/Users/alexeyd/test/dir/X   -o CMakeFiles/a.dir/a.cpp.o -c /Users/alexeyd/test/dir/a.cpp
[ 33%] Linking CXX static library liba.a
/usr/local/Cellar/cmake/3.8.1/bin/cmake -P CMakeFiles/a.dir/cmake_clean_target.cmake
/usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_link_script CMakeFiles/a.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar qc liba.a  CMakeFiles/a.dir/a.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib liba.a
[ 33%] Built target a
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/b.dir/build.make CMakeFiles/b.dir/depend
cd /Users/alexeyd/test/dir/build && /usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/alexeyd/test/dir /Users/alexeyd/test/dir /Users/alexeyd/test/dir/build /Users/alexeyd/test/dir/build /Users/alexeyd/test/dir/build/CMakeFiles/b.dir/DependInfo.cmake --color=
Dependee "/Users/alexeyd/test/dir/build/CMakeFiles/b.dir/DependInfo.cmake" is newer than depender "/Users/alexeyd/test/dir/build/CMakeFiles/b.dir/depend.internal".
Dependee "/Users/alexeyd/test/dir/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/Users/alexeyd/test/dir/build/CMakeFiles/b.dir/depend.internal".
Scanning dependencies of target b
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/b.dir/build.make CMakeFiles/b.dir/build
[ 50%] Building CXX object CMakeFiles/b.dir/b.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -I/Users/alexeyd/test/dir/X   -o CMakeFiles/b.dir/b.cpp.o -c /Users/alexeyd/test/dir/b.cpp
[ 66%] Linking CXX static library libb.a
/usr/local/Cellar/cmake/3.8.1/bin/cmake -P CMakeFiles/b.dir/cmake_clean_target.cmake
/usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_link_script CMakeFiles/b.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar qc libb.a  CMakeFiles/b.dir/b.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib libb.a
[ 66%] Built target b
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/c.dir/build.make CMakeFiles/c.dir/depend
cd /Users/alexeyd/test/dir/build && /usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/alexeyd/test/dir /Users/alexeyd/test/dir /Users/alexeyd/test/dir/build /Users/alexeyd/test/dir/build /Users/alexeyd/test/dir/build/CMakeFiles/c.dir/DependInfo.cmake --color=
Dependee "/Users/alexeyd/test/dir/build/CMakeFiles/c.dir/DependInfo.cmake" is newer than depender "/Users/alexeyd/test/dir/build/CMakeFiles/c.dir/depend.internal".
Dependee "/Users/alexeyd/test/dir/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/Users/alexeyd/test/dir/build/CMakeFiles/c.dir/depend.internal".
Scanning dependencies of target c
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f CMakeFiles/c.dir/build.make CMakeFiles/c.dir/build
[ 83%] Building CXX object CMakeFiles/c.dir/c.cpp.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -I/Users/alexeyd/test/dir/X   -o CMakeFiles/c.dir/c.cpp.o -c /Users/alexeyd/test/dir/c.cpp
[100%] Linking CXX executable c
/usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_link_script CMakeFiles/c.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/c.dir/c.cpp.o  -o c libb.a liba.a
[100%] Built target c
/usr/local/Cellar/cmake/3.8.1/bin/cmake -E cmake_progress_start /Users/alexeyd/test/dir/build/CMakeFiles 0

日志中有趣的部分:

[ 83%] Building CXX object CMakeFiles/c.dir/c.cpp.o 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -I/Users/alexeyd/test/dir/X   -o CMakeFiles/c.dir/c.cpp.o -c /Users/alexeyd/test/dir/c.cpp

我使用 CMake 3.8.1

【问题讨论】:

旁注:记住游戏有两个不同的阶段;编译和链接。包含路径仅在编译期间相关(以查找头文件),而不是在链接期间。链接时,使用一组不同的路径来搜索要链接的目标文件/库。对于 gcc,这是 -I and -L 选项之间的区别。 @JesperJuhl 我不确定这在这里有什么关系。这主要是一个 CMake 问题。 target_link_libraries 不仅仅与链接器交互;它可以让您将 CMake 目标链接在一起(设置包含目录和其他所有内容) 这里让我吃惊的是,如果b 私下链接到c,包含路径仍然存在... 【参考方案1】:

如果您指定最低 CMake 版本 >= 2.8.12,则不会出现奇怪的行为:

cmake_minimum_required(VERSION 2.8.12)

target_include_directoriesPRIVATE/PUBLIC 区别在 CMake 2.8.12 之前不存在。我的看法是,对于比 CMake 更早的版本,默认情况下会选择制作所有内容 PUBLIC

【讨论】:

我什至会说现在指定cmake_minimum_required(VERSION 3.0) 是合理的 没想到 smth 取决于与我使用的版本相反的 minimum_required 版本

以上是关于为啥即使对于私有链接也会继承包含路径的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使模板访问私有属性,Angular AOT 也会编译?

Java:为啥即使路径完整,使用 file.exists() 也会给出错误值?

关于pwd命令小技巧-确认当前工作目录的绝对路径中是否包含软链接目录名

即使库链接,DLL 也会被忽略

即使已经安装了应用程序,分支深度链接也会打开 App Store 而不是 App

4.html5中超链接和路径