Compilation flags to build runtime on linux machines - c++

What compiler flags are used to build standard c/c++ libraries like glibc and libstdc++?
Are they same across the distributions like debian, fedora, archlinux etc?
On debian machines there is dpkg-buildflags but I'm not sure if they are overridden for critical runtime libraries.

The one common factor is -O2, with -O2 -g (enabling gdb debugging symbols) being the most common. -O2 is definitely the expected optimization level maintainers assume packages should be compiled at.
If you look at debian/rules in Debian source packages (or -debian.tar.* tarballs), you'll usually find HOST_CFLAGS and HOST_CXXFLAGS describing the C and C++ compiler flags used when the source package is built using Debian tools.
This is documented in for example the man 1 dpkg-buildflags man page: "The default value set by the vendor includes -g and the default optimization level (-O2 usually, or -O0 if the DEB_BUILD_OPTIONS environment variable defines noopt)."
Outside Debian, Gentoo recommends -O2 -pipe and a -march= for the current architecture. (The -pipe option tells GCC to use pipes instead of temporary files during the build, which is usually faster but uses more RAM, during the build. It has no effect on the compiled binaries.)
Embedded systems like OpenWRT often use -Os instead, to generate smaller binaries.

Related

Clang not generating debug info on -g flag

When using clang v8.0.0 on Windows (from llvm prebuilt binaries) with -g or -gline-tables-only source map tables are not being picked up by gdb or lldb debuggers.
Upon including -g flag file grows in size (which is to be expected) yet neither gdb nor lldb pickes the source up
When compiled with gcc though (with -g flag) source files are detected by debugger.
I have tried running the same command (clang -g <codefile>) on macOS High Sierra (clang -v says it is Apple LLVM version 10.0.0 (clang-1000/10.44.4)) where there source files are being picked up by lldb. So I guessed it is localized to my windows instance or llvm for windows build.
P.S. output of clang -v on windows:
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
On Windows, Clang is not self-sufficient (at least not the official binaries). You need to have either GCC or MSVC installed for it to function.
As Target: x86_64-pc-windows-msvc indicates, by default your Clang is operating in some kind of MSVC-compatible mode. From what I gathered, it means using the standard library and other libraries provided by your MSVC installation, and presumably generating debug info in some MSVC-specific format.
Add --target=x86_64-w64-windows-gnu to build in GCC-compatible mode. (If you're building for 32 bits rather than 64, replace x86_64 with i686). This will make Clang use headers & libraries provided by your GCC installation, and debug info should be generated in a GCC-compatible way. I'm able to debug resulting binaries with MSYS2's GDB (and that's also where my GCC installation comes from).
If you only have GCC installed and not MSVC, you still must use this flag.
How do I know this is the right --target? This is what MSYS2's Clang uses, and I assume they know what they're doing. If you don't want to type this flag every time, you can replace the official Clang with MSYS2's one, but I'm not sure if it's the best idea.
(I think they used to provide some patches to increase compatibility with MinGW, but now the official binaries work equally well, except for the need to specify the target. Also, last time I checked their binary distribution was several GB larger, due to their inability to get dynamic linking to work. Also some of the versions they provided were prone to crashing. All those problems come from them building their Clang with MinGW, which Clang doesn't seem to support very well out of the box. In their defence, they're actively maintaining their distribution, and I think they even ship libc++ for Windows, which the official distribution doesn't do.)

Runtime error [abi:cxx11] when compile with g++-4.9 on Ubuntu 15.10

I recently updated Ubuntu from 15.04 to 15.10. One of the major differences between these versions is the update of the default gcc version from gcc-4.9 -> gcc-5. The library I'm developing has been written and compiled for gcc-4.9, and relies on other libraries which only work in gcc-4.9.
I have installed gcc-4.9 onto my computer, and I can successfully compile both the library and my source file. However, when I tried to run the resultant program I get this error:
terminate called after throwing an instance of 'std::ios_base::failure[abi:cxx11]'
what(): basic_ios::clear: iostream error
Aborted (core dumped)`
The source code, and the file I'm trying to read here used to work before the upgrade. I have tried using the -D_GLIBCXX_USE_CXX11_ABI=0 flag, but I'm not sure this is the right thing to do, also it doesn't work.
This is an example of the flags I'm currently including in my makefile:
CPPFLAGS = -O0 -g3 -Wall -c -fpermissive -D_GLIBCXX_USE_CXX11_ABI=0 -std=c++0x -fPIC -MMD -MP
Any ideas that might help me out?
You "simply" need to recompile everything your program needs that is C++.
See eg the Debian wiki on the transision which has (inter alia)
The good news is, that GCC 5 now provides a stable libcxx11 ABI, and stable support for C++11 (GCC version before 5 called this supported experimental). This required some changes in the libstdc++ ABI, and now libstdc++6 provides a dual ABI, the classic libcxx98 ABI, and the new libcxx11 (GCC 5 (<< 5.1.1-20) only provides the classic libcxx98 ABI). The bad news is that the (experimental) C++11 support in the classic libcxx98 ABI and the new stable libcxx11 ABIs are not compatible, and upstream doesn't provide an upgrade path except for rebuilding
There is no shortcut.

What's the relationship between binutils and gcc?

As titled, is binutils contained in gcc for Centos Linux?
If I install gcc rpm package, is there need to install binutils also?
What's more, are gcc and g++ both installed by default in Centos?
The gcc package probably contains the compiler proper, e.g. files /usr/bin/gcc and directory /usr/lib/gcc/x86_64-linux-gnu/4.8/ (which contains the cc1 executable).
The /usr/bin/gcc program starts cc1 (or cc1plus etc...) to compile your source code *.c, and also as to translate cc1-generated assembly code (produced by cc1) into object file *.o, and at last ld to link.
Compile once with gcc -v to understand what is happening, it would show the really executed binaries. Notice that gcc is only a driving program (starting other executables like cc1, as, ld ...)
The as and ld programs are provided by binutils -which is needed to compile.
So the binutils package is a required dependency for the gcc package (with many other dependencies, probably including libc and libc-devel, but if you really want you could use some other libc like MUSL libc; the libc is generally providing the dynamic linker like /lib/ld-linux.so*).
Learn how to use rpm (on Centos, or dpkg on Ubuntu & Debian) to query the dependencies between packages.
For development you probably want some other packages. Debian has the build-essential virtual package. Probably CentOS has an equivalent. And you'll surely want to use some libraries (and you want the development packages for them, e.g. on Debian libcurl4-gnutls-dev to develop with the libcurl HTTP client library). See also this answer (for Ubuntu and Debian, but you can adapt it for CentOS).
In 2021 you want to use GCC 10 at least, as g++ -Wall -Wextra -g and you could decide to code your own GCC plugin (checking some coding rules in your C++ code; you also want to document your coding conventions by writing). Be aware of the rule of five.

Cross compile x86_64 on i686 system on Ubuntu with distcc

I am attempting to setup a small build cluster at home using distcc. There are two x64 systems and 1 i686 systems. All systems are running Ubuntu 10.10 and are up to date. The system that is initiating the build is x64. Distcc works fine between the two x64 systems but all build tasks sent to the i686 system fail.
So far:
I have installed the multilib package for g++ on that system. I am able to cross-compile to x64 locally using g++ -m64
Changed the link in /usr/lib/distcc/g++ to point to a script that explicity sets the -m64 parameter.
Any suggestions?
Attempting this one again after more research:
GCC has a page describing the i386 and x86-64 options. The -m64 flag says to generate 64-bit code, but you'll also want to specify the type of CPU with -march=i686 or -march=k8 or similar, to use the correct instruction set.
Since distcc sends the GCC command line flags out, you should try adding these to the distcc command running locally and skip the remote script for setting flags.
If you test the architecture flags on your local x64 machine without distcc, just g++, then it should give you the right binaries when using distcc.

Compiling my C++ code for ARM Architecture

I am a java developer. I have some C++ code to make some system realted calls. This code is compiled on Intel 32-bit platform using GCC (I have make files) and it works fine on regular Intel based 32-bit linux machine. Now I need to run this on a linux OS running on Marvell ARM processor. When I load the shared objects in java I get the following error.
cannot open shared object file: No such file or directory (Possible cause: can't load IA 32-bit .so on a ARM-bit platform)
Please tell me how to resolve this issue. I looked at the GCC options and I found one option to specify the architecture (-march=armv5) and I can't compile with that option.
Thanks in advance.
You need more than just a switch, you need a cross-compiler. You can make your own, but probably the easiest way is :
Find the development tools for your board. It probably comes with a development kit that includes a cross-compilation toolchain
If you don't have these, you can try to install a precompiled cross-compilation like the ones provided freely by CodeSourcery
Then you have to make the location of your toolchain (look for something like arm-none-linux-gnueabi-gcc) available in your path.
Cross compiling simple project is then easy, just override the CC variable in your Makefile :
CROSS = arm-none-linux-gnueabi-
CC = $(CROSS)gcc
LD = $(CROSS)ld
Try using the -mcpu=armv5 switch for gcc.
Here is what's written on http://elinux.org/RPi_Software#ARM:
-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s