linking against different libc++ for clang14 on macOS 10.13 - c++

edit: My question is not related to Link errors using <filesystem> members in C++17 at all!
-lstdc++fs is not available on clang14 for macOS 10.13
edit2: Latest Xcode for macOS 10.13 is clang10, that is another reason for using clang14 from llvm. Also I can not update Xcode because my macOS Is stuck at high-serria
I am compiling the minimal example below with clang14.
#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;
int main()
{
std::cout << "Current path is " << fs::current_path() << '\n';
}
as follows:
clang-14++ path.cpp -std=c++20
which results in a linking error:
ld64.lld: error: undefined symbol: std::__1::__fs::filesystem::__current_path(std::__1::error_code*)
>>> referenced by /var/folders/_z/1q84ymcj36dgx7d2z7ybs6h40000gn/T/path-201e1b.o
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
running -v outputs the following:
https://pastebin.com/G1PDDkTJ
My understanding is that -lc++ is linking against the system's default libc++ (the one shipped with apple-clang and not the one with shipped clang14)
I verified that by appending
-L/path/to/clang14/lib/folder
before the -lc++
and it did compile and work however, generated the warning:
ld64.lld: warning: /Users/alia/.local/clang_llvm_apple/lib/libc++.dylib has version 11.6.0, which is newer than target minimum of 10.13.0
ld64.lld: warning: /Users/alia/.local/clang_llvm_apple/lib/libunwind.dylib has version 11.6.0, which is newer than target minimum of 10.13.0
any way to tell clang to link against its own default libc++? or should I just alias some command to compile first and then append -L as above and link?
also, does this have any impact or possible gotchas that I should be aware of? I am using clang14 because apple-clang doesn't support address sanitizers.

Related

How to link libcxx application to a C++ library compiled with gcc

I am trying to link an application that is compiled with clang/libc++ to the v8-devel system library on Fedora. However the latter is compiled with gcc/libstdc++ which leads to a linking error for std::unique_ptr, I think due to inlining.
Is there anything I can change in eiher my application code, or the compiler/linker flags (other than -stdlib) , such that my program can be linked to v8-devel while being still compiled with clang+libcxx?
Below a minimal toy example to reproduce the problem on Fedora (in reality, the only compiler that I have available is a custom clang version with libcxx, so switching to libstdc++ is not an option):
#include <libplatform/libplatform.h>
#include <v8.h>
using namespace v8;
int main(){
std::unique_ptr<Platform> platform = platform::NewDefaultPlatform();
V8::InitializePlatform(platform.get());
}
Then on Fedora we do:
# Install dependencies
yum install -y clang libcxx-devel v8-devel
# Try to compile test program
clang++ test.cpp -std=gnu++17 -stdlib=libc++ -lv8 -lv8_libplatform
Which gives the following linker error:
/usr/bin/ld: /tmp/test-9925a1.o: in function `main':
test.cpp:(.text+0x24): undefined reference to `v8::platform::NewDefaultPlatform(int, v8::platform::IdleTaskSupport, v8::platform::InProcessStackDumping, std::__1::unique_ptr<v8::TracingController, std::__1::default_delete<v8::TracingController> >)'
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
You can automatically run the steps above using this Dockerfile.

Cannot use filesystem::path when compiling with MacPorts LLVM / Clang 15.0.5 on macOS 10.13 or 10.14 [duplicate]

I was trying to out the new filesystem STL library, but for some reason am getting errors. The Clang++7 website indicates that it should support the new filesystem library – indeed clang is running ahead of g++ I believe.
I used some code from another Stack Exchange post, so it should be valid based upon the number of upvotes. This could should go to the specified directory and print all files in that directory. Here is the code.
#include <iostream>
#include <string>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main(int argc, char *argv[])
{
std::string path = "/home/.../Downloads";
for (const auto & entry : fs::directory_iterator(path))
{
std::cout << entry.path() << std::endl;
}
}
The error messages I am getting are:
CMakeFiles/filesystem_app.dir/main.cpp.o: In function `main':
/media/.../clangcpp/filesystem_app/main.cpp:13: undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() const'
/media/.../clangcpp/filesystem_app/main.cpp:13: undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
CMakeFiles/filesystem_app.dir/main.cpp.o: In function `path<std::__cxx11::basic_string<char>, std::experimental::filesystem::v1::__cxx11::path>':
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/experimental/fs_path.h:198: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
CMakeFiles/filesystem_app.dir/main.cpp.o: In function `directory_iterator':
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/experimental/fs_dir.h:188: undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path const&, std::experimental::filesystem::v1::directory_options, std::error_code*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I made sure to include the experimental/filesystem header instead of just filesystem which removed any red squiggles in Clion. I tried to compile from CLion as well as from the command line. The compilation string I used was:
clang++-7 -Wall -std=c++17 main.cpp -o app
Does anyone have a sense of what is wrong here? In the compile error messages I see the reference to std::experimental::filesystem::v1::__cxx11::.. and I am wondering why this does not say cxx17, but I was not sure if that was the cause of the issue. I explicitly indicated c++17 in the compilation string above.
filesystem is still experimental and requires an extra library.
If you are using libstdc++, link with -lstdc++fs (or target_link_libraries(${PROJECT_NAME} stdc++fs)).
For libc++, use -lc++fs (similar for the CMake command).

Clang MacOs over command line does not work

I am fairly new to both MacOs and C++ and have a problem which is similar to the one described here but also no solution I find in the Internet works.
'fatal error: 'wchar.h' file not found' error with the new macos 11.3 update
If I try to compile the most simple c++ program on my machine via command line it does not work.
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
Since it used to work I probably broke something but don't know what
The simple test command I use is the following
clang -v --target=arm64 helloworld.cpp
Which results in a iostream not found error
if I now include the xcode include directory via
clang -v --target=arm64 -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/ helloworld.cpp
The iostream error disappears and I get a wchar.h not found error
I removed xcode completely and reinstalled it but this seems to not help also does it not make a difference if I use clang or clang++.
With Clion and cmake it works but I do not know why
xcode-select version 2392
/usr/bin/clang
Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: arm64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
locate iostream.h
`/Library/Frameworks/Mono.framework/Versions/6.12.0/include/glib-2.0/gio/gfileiostream.h
/Library/Frameworks/Mono.framework/Versions/6.12.0/include/glib-2.0/gio/giostream.h
/opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/basic_socket_iostream.hpp
/opt/homebrew/Cellar/boost/1.76.0/include/boost/iostreams/detail/iostream.hpp
/opt/homebrew/Cellar/boost/1.76.0/include/boost/math/cstdfloat/cstdfloat_iostream.hpp
/opt/homebrew/Cellar/boost/1.76.0/include/boost/nowide/iostream.hpp
/opt/homebrew/Cellar/boost/1.76.0/include/boost/typeof/std/iostream.hpp
/opt/homebrew/Cellar/glib/2.70.2/include/glib-2.0/gio/gfileiostream.h
/opt/homebrew/Cellar/glib/2.70.2/include/glib-2.0/gio/giostream.h
/opt/homebrew/Cellar/glib/2.70.2/include/glib-2.0/gio/gsimpleiostream.h
I had similar troubles building clang + llvm, then trying to use the newly built clang via
./build/bin/clang -std=c++20 <my_file>
gave me a
fatal error: 'iostream' file not found
What fixed it was if I compiled with the following instead:
./build/bin/clang -std=c++20 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk <my_file>
The fix largely comes from https://github.com/MaskRay/ccls/issues/191#issuecomment-556983460 and the discussion there

clang++ fails to compile hello world

I installed clang in my conda environment along with gcc. Their versions are
gcc 7.2.0
clang 7.0.0
libcxx 7.0.0
I then created an hello world src file a.cpp
If I compile the file using clang++ a.cpp. The error reads
a.cpp:1:10: fatal error: 'iostream' file not found
#include <iostream>
^~~~~~~~~~
1 error generated.
Using clang++ a.cpp --stdlib=libstdc++, the error is the same
Using clang++ a.cpp --stdlib=libc++, the error becomes
~/conda/envs/test/bin/ld: cannot find crtbegin.o: No such file or directory
~/conda/envs/test/bin/ld: cannot find -lgcc
clang-7: error: linker command failed with exit code 1 (use -v to see invocation)
Using clang++ a.cpp -I$HOME/conda/envs/test/include/c++/7.2.0
In file included from a.cpp:1:
/site/home/shliu/conda/envs/test/include/c++/7.2.0/iostream:38:10: fatal error: 'bits/c++config.h' file not found
#include <bits/c++config.h>
^~~~~~~~~~~~~~~~~~
1 error generated.
I use a shared computer so I cannot install system wide compilers and header files.
Questions:
What should I do to have it work?
If clang does not ship with its own header files and I need to use what are provided by gcc, should I consider the compatibility of clang version and the gcc version?
Do I need to install libc++ in the same conda environment in order to use clang++?
After some test, I found the way to do it in conda, which is posted as the an answer. However, I still don't understand how clang works, especially its relation with gcc. I would appreciate it very much if any one could answer (and I will accept that as the answer to this post):
Does clang forward all the jobs to gcc so we always need the gcc tool chain to be installed in order to use clang?
I found an include folder for clang, which is $HOME/conda/envs/test/include/c++/v1 alongside with $HOME/conda/envs/test/include/c++/7.2.0 which is from gcc. But if the --gcc-toolchain has been specified, the v1 folder is not searched for headers, (which can be seen from the output by adding -v to the compiler. Then what is the usage of the v1 include files?
Finally I found the way, which is to do
clang++ --gcc-toolchain=$HOME/conda/envs/test a.cpp
This is not obvious at all.

What library do I need to link to use std::list in clang++?

I am trying to use the std::list class in C++, and I need to use clang++ to compile the program. g++ compiles the following program just fine, but I can't figure out how to compile/link it with clang++:
#include <iostream>
#include <list>
int main(){
std::list<int> L;
L.push_back(10);
std::cout << L.back() << std::endl;
return 0;
}
I've tried clang++ -lstdc++ listTest.cpp but still get the following error:
/tmp/listTest-3175a9.o: In function `std::list<int, std::allocator<int> >::_M_insert(std::_List_iterator<int>, int const&)':
listTest.cpp:(.text._ZNSt4listIiSaIiEE9_M_insertESt14_List_iteratorIiERKi[_ZNSt4listIiSaIiEE9_M_insertESt14_List_iteratorIiERKi]+0x31): undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Clang version:
clang version 3.4 (tags/RELEASE_34/final)
linux version:
LSB_VERSION=base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Red Hat Enterprise Linux Server release 6.5 (Santiago)
You should provide library arguments after the translation unit that uses them:
clang++ listTest.cpp -lstdc++
I should note that I couldn't reproduce your issue, but that could easily be down to differences in version/configuration (particularly w.r.t. a stdlib implementation selected for use by default).
I solved it on mine (redhat, clang 3.4, gcc 4.7.2).
By default this project was linking against /usr/lib/libstdc++. I have a build of gcc 4.7.2 installed in a separate location; when I add lines analogous to the following to the link step it works fine
-L${GCC_PATH}/lib -Wl,-R${GCC_PATH}/lib
... provided they appear in the link step before analogous statements for /usr/lib.
edit
You can use strace to help diagnose this problem; I did something like the following:
// copy the link step into a temp shell script
strace -f ./temp.sh |& grep -P 'lib(std)?c\+\+'
... which is when I realized I probably needed a different build of the C++ runtime because I saw it was finding and linking against the one in /usr/lib.