简单的解决方案:

简单的解决方案:

在 Docker 的 ubuntu bionic 上,我得到了这个:

No such file or directory
 #include <filesystem>

在执行此操作的 C++ 文件上:

#if __cplusplus >= 201703L
#include <filesystem>
#endif

尝试使用 clang 6.0 进行编译时。不幸的是,我无法移动到它,experimental/filesystem因为它不是我的库,它来自 OpenVPN3。我尝试使用 clang 10,但仍然出现错误。

Ubuntu 20.04(专注于 docker)可以运行!但是我想使用更旧的版本,以便与旧系统兼容。

这是 cmake/make 在编译出现错误的文件时生成的输出:

cd /workspaces/libopenvpnclient/build/src && /usr/local/clang/bin/clang++  -DASIO_STANDALONE

 -DHAVE_LZ4 -DLZ4_DISABLE_DEPRECATE_WARNINGS -DMBEDTLS_DEPRECATED_REMOVED -DUSE_ASIO 

-DUSE_OPENSSL -I/workspaces/libopenvpnclient/src/../openvpn3 -I/workspaces/libopenvpnclient

/src/../libtins/include -I/workspaces/libopenvpnclient/src/../asio/asio/include -I/workspaces

/libopenvpnclient/src/../literal_ipaddr -I/workspaces/libopenvpnclient/openvpn3/cmake/..

 -I/workspaces/libopenvpnclient/openvpn3/cmake/../../deps/asio/asio/include  -Wall -Wsign-

compare -Wno-missing-field-initializers -std=c++1z -o CMakeFiles/libopenvpn_example.dir

/OpenVPNClient.cpp.o -c /workspaces/libopenvpnclient/src/OpenVPNClient.cpp

我猜测 Ubuntu 18 上的 libstdc++ 有问题?

Dockerfile:

FROM ubuntu:bionic

RUN export DEBIAN_FRONTEND=noninteractive && apt-get update \
&& apt-get install -y clang-6.0 lldb iptables iproute2 cmake \
build-essential libmbedtls-dev libssl-dev liblz4-dev curl git \
xz-utils wget libncurses5

RUN curl --proto '=https' --tlsv1.2 -o rust.sh https://sh.rustup.rs\
    && /bin/bash rust.sh -y


RUN wget -O clang.tar.xz https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz \
&& mkdir clang && tar xf clang.tar.xz -C clang --strip-components 1 \
&& mv clang /usr/local/clang

WORKDIR /home/project

ENV PATH="/root/.cargo/bin:${PATH}"
ENV PATH="/usr/local/cmake/bin:${PATH}"

只需更改bionicfocal即可使编译工作。

答案1

每当 C++ 编译错误显示<filesystem>未找到头文件时,这是因为 9.1 之前的 GNU libstdc++ 和 9.0 之前的 LLVM libc++ 尚未实现std::filesystem

简单的解决方案:

使用此解决方案,代码可以编译,但不支持较旧的 C++ 标准库。

最简单的做法是更新到较新的 C++ 标准库。C++ 标准库的版本是 Ubuntu 20.04 Focal Fossa 可以运行而 Ubuntu 18.04 Bionic Beaver 无法运行的原因。

至于 Ubuntu 18.04 上的 clang 10 无法编译,是因为您仍在使用不包含标<filesystem>头的系统旧 libstdc++。您必须安装包含较新 libstdc++ 的 g++ 9,以便可以使用 clang 10 进行编译。

在 Ubuntu 18.04 上执行以下操作:

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install gcc-9 g++-9

现在 clang 10 可以正确编译。

困难的解决方案:

使用此解决方案,代码将编译并支持较旧的 C++ 标准库。此解决方案的缺点是需要一个额外的编译标志,GNU libstdc++ 和 LLVM libc++ 之间有所不同。

如果您确实需要使用 9.1 之前的 GNU libstdc++ 和 9.0 之前的 LLVM libc++ 进行编译,则必须修改 OpenVPN3 中的代码。因为OpenVPN3是开源的,如果你更改他们的代码,你可以发送拉取请求,他们可能会接受你的贡献。

困难解决方案的第一部分-代码更改:

您需要修改 OpenVPN3 代码,以便它根据可用的标头在std::filesystem和命名空间之间进行选择。std::experimental::filesystem

#if __has_include(<filesystem>)
  #include <filesystem>
  namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
  #include <experimental/filesystem> 
  namespace fs = std::experimental::filesystem;
#else
  error "Missing the <filesystem> header."
#endif

现在您必须使用命名空间fsnamepsace 而不是std::filesystem

之前的代码:

std::filesystem::path file("document.txt");

之后的代码:

fs::path file("document.txt");

std::filesystem请小心,因为和之间存在一些差异std::experimental::filesystem

困难解决方案的第二部分-编译标志:

对于使用 gcc 或 clang 的 9.1 之前的 GNU libstdc++,您需要将该标志用作-lstdc++fs最后一个标志。顺序很重要。

g++ -std=c++17 your_code.cpp -lstdc++fs

或者

clang++ -std=c++17 your_code.cpp -lstdc++fs

要使用 CMake 执行上述操作,请在后面添加以下内容add_executable()

target_link_libraries(project_name_here stdc++fs)

对于使用 clang 的 9.0 之前的 LLVM libc++,您需要使用标志-lc++fs作为最后一个标志。要使用 libc++,请不要忘记安装libc++-devlibc++abi-dev

clang++ -std=c++17 -stdlib=libc++ -lc++abi your_code.cpp -lstdc++fs

要使用 CMake 执行上述操作,请在后面添加以下内容add_executable()

target_link_libraries(project_name_here c++fs)

相关内容