On ubuntu bionic from Docker, I'm getting this:
No such file or directory
#include <filesystem>
on a C++ file that does this:
#if __cplusplus >= 201703L
#include <filesystem>
#endif
when trying to compile with clang 6.0. Unfortunately I cannot move to experimental/filesystem
because it's not my library, it's from OpenVPN3. I tried with clang 10 and still got the error.
Ubuntu 20.04 (focal on docker) works! However I wanted to use a more older version to have compatibility with older systems.
This is the output that cmake/make produces when compiling the file that gives the error:
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
I guess something's wrong with libstdc++ on Ubuntu 18?
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}"
simply changing bionic
to focal
makes the compilation work.
Whenever a C++ compilation error says the
<filesystem>
header is not found it is because GNU libstdc++ prior to 9.1 and LLVM libc++ prior to 9.0 have not implementedstd::filesystem
yet.EASY SOLUTION:
With this solution the code will compile but it won't support older C++ standard libraries.
The easiest thing you can do is update to a newer C++ standard library. The version of the C++ standard library is the reason that Ubuntu 20.04 Focal Fossa works but Ubuntu 18.04 Bionic Beaver doesn't.
As for clang 10 on Ubuntu 18.04 not compiling is because you are still using the system's older libstdc++ that doesn't contain the
<filesystem>
header. You must install g++ 9 that contains a newer libstdc++ so you can compile with clang 10.On Ubuntu 18.04 do the following :
Now clang 10 will compile correctly.
DIFFICULT SOLUTION:
With this solution the code will compile and it will support older C++ standard libraries. The downside of this solution is that an extra compilation flag will be needed that is different between GNU libstdc++ and LLVM libc++.
If you absolutely need to compile with GNU libstdc++ prior to 9.1 and LLVM libc++ prior to 9.0 you have to modify the code from OpenVPN3. Since OpenVPN3 is open source if you change their code you can then send a pull request and they may accept your contribution.
FIRST PART OF DIFFICULT SOLUTION - CODE CHANGES :
You need to modify OpenVPN3 code so it chooses between the
std::filesystem
andstd::experimental::filesystem
namespaces depending on what header is available.Now you have to use the namespace
fs
namepsace instead ofstd::filesystem
.The code before :
The code after :
Be careful because there are some differences between
std::filesystem
andstd::experimental::filesystem
.SECOND PART OF DIFFICULT SOLUTION - COMPILATION FLAGS:
For GNU libstdc++ before 9.1 with gcc or clang you need to use the flag
-lstdc++fs
as the last flag. The order is important.or
To do the above with CMake add the following after
add_executable()
:For LLVM libc++ before 9.0 with clang you need to use the flag
-lc++fs
as the last flag. To use libc++ do not forget to install thelibc++-dev
andlibc++abi-dev
.To do the above with CMake add the following after
add_executable()
: