Use compiled LLVM/clang without gcc - c++

I have been trying to compile LLVM/clang from source, both by myself and using this script. I am compiling clang using gcc 11.2, which itself was also built from source, and hence resides in a non-default location on my system (/scratch/opt/gcc-ml-11.2). Note that it only works with a gcc that was compiled with multilib enabled.
The problem is that I can use the compiled clang and clang++ binaries only if I supply the gcc location as follows: --gcc-toolchain=/scratch/opt/gcc-ml-11.2.0. Without that flag, I run into linker errors:
clang test.c -o test
/usr/bin/ld: cannot find crtbeginS.o: No such file or directory
/usr/bin/ld: cannot find -lgcc
/usr/bin/ld: cannot find -lgcc_s
I do not understand why a clang compiled binary needs to link against some kind of gcc library and why clang does not supply the crtbeginS.O file.
I have also tried using the LLVM linker as well as the LLVM standard library for C++ test applications, i.e., "-fuse-ld=lld -stdlib=libc++. This did not help either.
While I could just export CXXFLAGS=--gcc-toolchain=/scratch/opt/gcc-ml-11.2.0, I am not sure whether this is the right approach. Shouldn't clang/LLVM be able to function without a gcc installation?
I have also tried using my clang installation with the --gcc-toolchain=/scratch/opt/gcc-ml-11.2.0 flag to compile clang again, but the new binary also requires the gcc-toolchain flag.
Should I just globally export the path to my gcc toolchain? Why is this necessary? Isn't clang a standalone compiler that - if supplied with the option to use its own standard library - does not require gcc?
Thank you very much for your help!
Best,
Maxbit

Related

Cannot find -lubsan on using -fsanitize=undefined (mingw-w64)

I'm using mingw-w64 (gcc 7.3.0) and when I compile any C++ program using the following command:
g++ file.cpp -fsanitize=undefined
I get the following error:
...mingw32/bin/ld.exe: cannot find -lubsan
I'm able to successfully compile and run my programs if I remove the -fsanitize=undefined flag, though. After some research I found out that this means the library ubsan (Undefined Behavior Sanitizer) is missing, but I couldn't find anything about the library. How do I fix this?
This is well known issue with mingw see for instance this msys github issue. No proper solution known but there are several WAs.
Install WSL, ubuntu over WSL and you will have ubsan inside it
Build GCC under Windows from source enabling sanitizers build. They are present in GCC sources they are just not here in mingw.
Use -fsanitize=undefined -fsanitize-undefined-trap-on-error to just not use libubsan rich logging capabilities but get it trap on undefined instruction.
Hope one of this helps.

Boost regex: Undefined references when linking

Until some weeks ago, using the boost_regex library I used to compile a C++ file test.cpp using the following command.
g++-4.9 -Wall -O3 -march=native -flto -DNDEBUG -o test \
--std=c++14 test.cpp -lboost_regex -pthread
The compilation was working perfectly. But at some point, I needed to upgrade my OS (more precisely, it was Ubuntu 14.04, now it is Ubuntu 16.04).
I kept my local folders with my data, and I also installed the Boost library again in the new system, including boost_regex.
The Boost version in the new system is 1.58, unfortunately I cannot know which Boost version I was using before because it is now deleted.
I try to compile again the same file in the new system, with the same command as above, and the linker says it cannot find two functions called maybe_assign and construct_init. If I replace the -o test option with just -c (i.e. without linking) then the program is compiled without errors.
More precisely, when I try to do linking I get the following errors (they were extremely long, I hade to shorten using ... dots).
In function `boost::re_detail::perl_matcher<...>::match_match()':
undefined reference to `boost::match_results<...>::maybe_assign(boost::match_results<...> const&)'
In function `bool boost::regex_search<...>(...)':
undefined reference to `boost::re_detail::perl_matcher<...>::construct_init(...)'
In function `boost::re_detail::perl_matcher<...>::match_prefix()':
undefined reference to `boost::match_results<...>::maybe_assign(boost::match_results<...> const&)'
collect2: error: ld returned 1 exit status
I really don't know how this is possible, the libraries seem perfectly installed, nothing seems missing, and the compilation was working with a previous OS installation (then I guess older libraries).
At these point my only guess could be that Boost authors removed such functions? (maybe they are obsolete?). But I didn't find any trace of this on internet. If this is the case, how can I know the boost versions in which such functions are available?
Am I doing any mistake? Do you have any suggestions to investigate about this?
TL;DR use gcc5.
Ununtu 16.04 comes with gcc5 by default. Every C++ library in it is compiled with that compiler.
Now there was an incompatible C++ ABI change between gcc4 and gcc5. It made binaries built from C++ sources with gcc4 incompatible by default with binaries built with gcc5. This incompatibility often manifests itself as a bunch of undefined symbols that reference std::string and/or std::list.
The standard library comes built with a dual ABI to support objects built with older compilers. Other libraries like boost, hovever, don't.

Why does gcc want me to link to libgcc_ext.10.5.dylib?

I've built GCC 4.9.2 on Mac OS X from source statically (using --disable-shared), for C language only (not C++), with the static version of libgcc (libgcc.a). Of course, since I only built the static version of libgcc, there's no such thing as libgcc*.dylib. GCC has built and installed libgcc.a (as expected) and that's all fine. Now when I invoke this newly-built copy of GCC using the following command (using a simple hello, world! example):
gcc -v test.c -o test
it shows these compiler flags as default:
-no_compact_unwind -lSystem -lgcc_ext.10.5 -lgcc -lSystem
No, no no! I don't want you to try to link to a shared version of libgcc! Don't you remember I told you that at the configuration step? And if I use the -static-libgcc option, I get this:
-no_compact_unwind -lgcc_eh -lgcc -lSystem
libgcc_eh? HUH? When was that built during GCC compilation? Oh right, it wasn't, hence why it can't find libgcc_eh.a.
What's going on here? I specifically told GCC I didn't want shared libraries, so why is it trying to link to them by default? I can, of course, remedy all this by using -nodefaultlibs and specifying -lgcc and -lSystem manually, but why should I have to do that?
Furthermore, the GCC documentation has this to say:
-shared-libgcc
-static-libgcc
On systems that provide libgcc as a shared library, these options force the use of either the shared or static version, respectively. If no shared version of libgcc was built when the compiler was configured, these options have no effect.
So, based on this, I take it that if I did not specifically ask GCC to build a shared version of libgcc, it should not assume I would want to link to anything but a static version. But, for some reason, it does anyway. I haven't been able to find a configure option that would prevent this, nor an option that lets me specify which "default libs" get linked to by default. It seems GCC is forcing me to link to a shared version of libgcc that isn't there unless I suppress this using -nodefaultlibs. This seems backwards.
I figured out how to fix this. I had to edit /gcc/config/darwin.h in GCC's source and comment out where the macro REAL_LIBGCC_SPEC is defined. By leaving this macro undefined, it ensures GCC will only pass the -lgcc and -lSystem library flags during linking, which is what I wanted.
The GCC docs for the compilation driver explain what this and other macros do:
https://gcc.gnu.org/onlinedocs/gccint/Driver.html
— Macro: LIBGCC_SPEC
Another C string constant that tells the GCC driver program how and when to place a reference to libgcc.a into the linker command line. This constant is placed both before and after the value of LIB_SPEC.
If this macro is not defined, the GCC driver provides a default that passes the string -lgcc to the linker.
— Macro: REAL_LIBGCC_SPEC
By default, if ENABLE_SHARED_LIBGCC is defined, the LIBGCC_SPEC is not directly used by the driver program but is instead modified to refer to different versions of libgcc.a depending on the values of the command line flags -static, -shared, -static-libgcc, and -shared-libgcc. On targets where these modifications are inappropriate, define REAL_LIBGCC_SPEC instead. REAL_LIBGCC_SPEC tells the driver how to place a reference to libgcc on the link command line, but, unlike LIBGCC_SPEC, it is used unmodified.

Static linking to libcrypto++, with g++

I am trying to compile a program on my system with Debian Wheezy and g++4.7. I want it to be able to run on another system with Debian Squeeze (and no recent g++). I can't compile the program on the Squeeze, because I use certain C++11 features the old g++ does not support, as well as a new Boost version and libcrypto++9.
As far as I understand the usual way to get around this problem is to static link the libraries not supported at the other system, in my case libstdc, boost and crypto++.
My (linking) compiler call right now is
g++-4.7 .obj/btcmirco.o -Wl,-Bstatic -lboost_program_options -lboost_system -lcrypto++ -Wl,-Bdynamic -lcurl -static-libgcc -std=c++11 -o MyProgram
However I seem to have missed something, because it throws a lot of undefined reference errors. It works fine if I dynamic link to crypto++ (and only static link libstdc and boost).
Can anyone tell me whats wrong, or if there is a fundamental error in my approach?
The linker errors I get are (shorted):
`.text._ZN8CryptoPP22BufferedTransformationD2Ev' referenced in section `.text._ZN8CryptoPP22BufferedTransformationD1Ev[_ZN8CryptoPP22BufferedTransformationD1Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o): defined in discarded section `.text._ZN8CryptoPP22BufferedTransformationD2Ev[_ZN8CryptoPP22BufferedTransformationD5Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o)
`.text._ZN8CryptoPP25MessageAuthenticationCodeD2Ev' referenced in section `.text._ZN8CryptoPP25MessageAuthenticationCodeD1Ev[_ZN8CryptoPP25MessageAuthenticationCodeD1Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o): defined in discarded section `.text._ZN8CryptoPP25MessageAuthenticationCodeD2Ev[_ZN8CryptoPP25MessageAuthenticationCodeD5Ev]' of /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libcrypto++.a(cryptlib.o)
I experienced the same problem and this has to do with the fact that you are trying to mix code generated by g++-4.7 (your program) with code generated by a previous version of g++ (cryptopp library).
The reason behind this is that when you execute compile the library executing make command, it uses the default version of g++ set up for your system, usually the one that comes with the OS.
In order to solve the issue what you should do is compile cryptopp library with g++-4.7.
For that, compile the library by executing make CXX=g++-4.7. The resulting static library shouldn't give you the error when being linked with your code.

GCC - Linking bass.lib on Ubuntu

I wrote an application on Windows using CPP and BASS, and now I have to get it running on Linux (UBUNTU).
I am using gcc version 4.5.2.
I have bass.lib in my directory from which I try to compile prog.cpp using the following command arguments:
gcc prog.cpp -L. -lbass.lib
But I get the following error:
/usr/bin/ld: cannot find -lbass.lib
collect2: ld returned 1 exit status
I figure that this is a linking error, the compiler is not finding Bass.lib but I have specified as an argument on the command line.
Not sure what to do, any help would be really great.
bass.lib sounds like the windows library. You cannot use libraries generated on windows, (likely generated with the MSVC compiler), on linux.
The linux version of the library seems to be named libbass.so , in which case you'd use -lbass as the linker argument , and possibly other compiler/linker flags as well depending on where on the system you install the library. The bass.txt in the linux download of libbass have a few notes on what to do on Linux.