为什么 link_libraries(stdc++fs) 有效但 -lstdc++fs 无效?

Vin*_* La 2 c++ g++ cmake c++17

我试图使用 CMake/g++ 8.1 在 Ubuntu 上编译 C++17 程序,其中包含

#include <filesystem>
Run Code Online (Sandbox Code Playgroud)

当我用这个的时候

set(CMAKE_CXX_FLAGS "-lstdc++fs")
Run Code Online (Sandbox Code Playgroud)

我遇到了一个奇怪的链接器错误

undefined reference to `std::filesystem::__cxx11::recursive_directory_iterator::~recursive_directory_iterator()'
Run Code Online (Sandbox Code Playgroud)

当我尝试使用该-lstdc++fs标志手动调用 g++ 时,也会出现此错误。

另一方面,这条线按我的预期工作

link_libraries(stdc++fs)
Run Code Online (Sandbox Code Playgroud)

我很好奇为什么这两行提供不同的结果。该函数是否link_libraries()使用了一些我不知道的魔法?

Mat*_*her 6

这会更改编译器标志,但不会更改链接标志:

set(CMAKE_CXX_FLAGS "-lstdc++fs")
Run Code Online (Sandbox Code Playgroud)

这意味着当您编译文件时,您添加了没有任何效果的库,然后当您链接以创建可执行文件时,您不会获得此标志。

所以你实际上应该更改链接器:

target_link_libraries(target PRIVATE stdc++fs)
Run Code Online (Sandbox Code Playgroud)

而不是link_libraries(这是旧式的 CMake,不擅长处理多个目标)。

target_link_libraries建议这样做,因为它仅将库添加到target. PRIVATE还指示不传播共享库的链接(即依赖库不会链接stdc++fs)。

您可以通过执行以下操作来检查两者之间的行为差​​异:

VERBOSE=1 make
Run Code Online (Sandbox Code Playgroud)