Ubuntu20.4下G++10+C++20项目<filesystem>编译链接错误求助
C++20项目中CMake引入的问题
环境
Ubuntu 20.04 LTS,G10编译器,CMake构建C20项目
代码示例
properties.hpp
#include <string> #include <filesystem> class File { private: std::filesystem::path m_filePath; public: explicit File(); ~File(); void setPath(const std::string &p_fullPath); };
properties.cpp
#include "properties.hpp" ff::prop::File::File() { this->setPath(""); } ff::prop::File::~File() { this->setPath(""); } void ff::prop::File::setPath(const std::string &p_fullPath) { using namespace std::filesystem; if (p_fullPath == "") this->m_filePath = path(); else this->m_filePath = path(p_fullPath); }
CMake配置
cmake_minimum_required(VERSION 3.26 FATAL_ERROR) ### cmake settings set(CXX_STANDARD_REQUIRED ON) set(CXX_STANDARD 20) set(CMAKE_CXX_COMPILER /usr/bin/g++-10) cmake_language(GET_MESSAGE_LOG_LEVEL VERBOSE) message("The c++ version is ${CXX_STANDARD} ${CMAKE_CXX_COMPILER}") set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall -Wextra -std=c++20") set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall") ### project setttings project(ff VERSION 0.0.1 LANGUAGES CXX) add_executable(${PROJECT_NAME} app/main.cpp app/src/app.cpp app/src/properties.cpp )
问题现象
- 执行
cmake -DCMAKE_BUILD_TYPE=Debug -S . -B debug时,输出显示编译器运行在C++20模式;但执行cmake --build debug/时,出现编译错误:‘filesystem’ in namespace ‘std’ does not name a type。 - 改用
<experimental/filesystem>头文件,将std::filesystem::path改为std::experimental::filesystem::path后,编译通过但出现链接错误,提示无法找到experimental filesystem的实现。 - 最小示例代码直接用
g++-10 main.cpp a.cpp -o app -std=20编译成功,但CMake项目中失败;执行cmake --system-information info.txt显示CMAKE_CXX_COMPILER == "/usr/bin/c++",但编译器实际版本为10.3.0。
疑问
- 既然G10对C20的
<filesystem>头文件提供支持,为何项目无法编译? - 为何使用experimental/filesystem能编译但出现链接错误?
- 该如何解决这个问题?
解决方案
问题根因
CMake配置存在变量名错误:你使用了CXX_STANDARD和CXX_STANDARD_REQUIRED,但CMake中控制C标准的正确变量是带CMAKE_前缀的CMAKE_CXX_STANDARD和CMAKE_CXX_STANDARD_REQUIRED。变量名错误导致CMake未正确启用C20标准,编译器仍以默认标准编译,因此无法识别C++20中的std::filesystem。
修正步骤
- 修正CMake标准变量:将配置中的标准相关变量改为正确名称:
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD 20) - 移除冗余编译选项:删除
CMAKE_CXX_FLAGS_DEBUG_INIT中的-std=c++20,避免和CMake自动生成的标准选项冲突:set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall -Wextra") - 验证编译器配置:可添加以下命令确认编译器版本,确保CMake正确识别G++10:
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE CXX_VERSION) message("Compiler version:\n${CXX_VERSION}")
关于experimental/filesystem的链接错误
G的<experimental/filesystem>是C17正式标准前的实验实现,需要显式链接stdc++fs库才能使用。如果一定要用该版本,需在CMake中添加链接指令:
target_link_libraries(${PROJECT_NAME} stdc++fs)
但推荐使用C++20标准的<filesystem>,无需额外链接。
内容的提问来源于stack exchange,提问作者Dhairya Gupta
相关产品推荐
相关产品推荐

