c++ - 为什么link_libraries(stdc++fs) 可以工作,但-lstdc++fs 不行?
问题描述
我试图在 Ubuntu 上使用 CMake/g++ 8.1 编译一个 C++17 程序,其中包含
#include <filesystem>
当我使用这个
set(CMAKE_CXX_FLAGS "-lstdc++fs")
我有一个奇怪的链接器错误
undefined reference to `std::filesystem::__cxx11::recursive_directory_iterator::~recursive_directory_iterator()'
当我尝试使用-lstdc++fs
标志手动调用 g++ 时,也会出现此错误。
另一方面,这条线按我的预期工作
link_libraries(stdc++fs)
我很好奇为什么这两条线会提供不同的结果。该link_libraries()
功能是否使用了一些我不知道的魔法?
解决方案
这会更改编译器标志,但不会更改链接标志:
set(CMAKE_CXX_FLAGS "-lstdc++fs")
这意味着当你编译文件时,你添加了没有效果的库,然后当你链接到创建你的可执行文件时,你不会得到这个标志。
因此,您实际上应该使用以下方式更改链接器:
target_link_libraries(target PRIVATE stdc++fs)
而不是link_libraries
(这是旧式 CMake,不擅长处理多个目标)。
target_link_libraries
建议,因为它只将库添加到target
. PRIVATE
还表示不传播共享库的链接(即依赖库不会链接到stdc++fs
)。
您可以通过以下方式检查两者之间的行为差异:
VERBOSE=1 make
推荐阅读
- python - Tensorflow 代码中的形状错误
- jenkins - 如何使用 Jenkins + Ant 生成项目的 .ear?
- python-3.x - Python while True 阻止以前的代码执行
- graphhopper - Graphhopper 本地实例行程时间
- ffmpeg - 如何配置 AVStream 以使用 FFmpeg 写入 29.97FPS 文件
- mysql - 错误使用 mysql-slow.log 权限
- jsf - 带转换器的 selectOneMenu。java.lang.Integer 不能转换为
- vb.net - VB.NET:application.restart() 进入中断模式
- php - 拆分值数组 ini php
- android-studio - 我是 Flutter 的新手,我尝试在 Android Studio 上运行我的项目,但在控制台中出现错误,例如: