JPN*_*gon 26 c++ cmake header-only
我正在编写一个C++库(仅限标题),并使用CMake生成我的(Visual Studio)项目和解决方案文件.我也在编写一个测试套件,它是同一个CMake项目的一部分.
当我在代表我的仅头文件库的目标上调用target_include_directories()时,会出现问题,因此我的库的使用者可能会找到其头文件.我收到以下错误消息(即使生成没有中止).
CMake Error in CMakeLists.txt:
Target "Fonts" INTERFACE_INCLUDE_DIRECTORIES property contains path:
"D:/Projects/GPC/fonts/include"
which is prefixed in the source directory.
Run Code Online (Sandbox Code Playgroud)
(D:/ Projects/GPC/Fonts是我的库项目的顶级目录.如果我将头文件移动到顶层目录,问题仍然存在.)
我的CMakeLists.txt中的违规行是这个(为简单起见):
target_include_directories(Fonts INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
Run Code Online (Sandbox Code Playgroud)
我不明白我做错了什么.没有target_include_directories(),消费者项目的代码根本不能包含我的头文件(除非在已安装的形式,但我还没有达到这一点,并且无论如何我希望能够从其构建树中使用我的库,没有安装.)
我觉得我在这里缺少一些基本的东西; 但是我没有找到解决方案或解释就搜索了几个小时.
Com*_*sMS 56
问题的根源不是target_include_directories命令本身,而是对install具有公共或接口的目标的尝试包括源路径中的前缀目录.
虽然从头开始构建库时使用绝对路径是完全正确和可取的,但是引入该库的预构建版本的第三方库可能希望使用不同的包含路径.毕竟,您不希望所有用户镜像构建计算机的目录结构,只是最终在正确的包含路径中.
CMake的打包机制为这两种用例提供了支持:您可以直接从构建树中提取库(即检查源代码,构建它,并指向find_package()目录),或者从安装目录(运行make INSTALL到内置的东西复制到安装目录,并点find_package()到该目录).后一种方法需要是可重定位的(也就是说,我在我的机器上构建和安装,向您发送生成的目录,并且您可以在不同的目录结构中在您的机器上使用它),而前者不是.
这是一个非常简洁的功能,但您必须在设置包含目录时考虑到它.引用手册target_include_directories:
包含目录使用要求通常在构建树和安装树之间有所不同.的
BUILD_INTERFACE和INSTALL_INTERFACE发电机表达式可以用于描述基于所述使用位置分开的使用要求.INSTALL_INTERFACE表达式中允许相对路径,并相对于安装前缀进行解释.例如:Run Code Online (Sandbox Code Playgroud)target_include_directories(mylib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/mylib> $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib )
在BUILD_INTERFACE和INSTALL_INTERFACE发电机表达式做所有的魔法:
$<INSTALL_INTERFACE:...>
...使用导出属性的内容,install(EXPORT)否则为空.
$<BUILD_INTERFACE:...>
...使用导出属性的内容export(),或者同一构建系统中的另一个目标使用目标时的内容.否则扩展为空字符串.