Run time linking with with GCC - c

As mentioned over here and here
So if your program is using math functions and including math.h, then
you need to explicitly link the math library by passing the ‘-lm’ flag
But I just manage to get the linking without using -lm flag with gcc on my benign C code.
and It work perfectly well.
Any clue.
gcc -version
gcc -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

On many systems some parts of what's traditionally in libm are included in the standard C library for various reasons. Other parts may be implemented directly in the math.h header, yet others might be just implemented inline by the compiler.
Whatever code you had, you got away with not linking with libm. You'll often end up in situations where you get away with doing something despite it not being perfectly correct. A good habit is to ignore that luck and still do what the standards/documentation says because it reduces the number of problems in the future.

Related

clang does not generate gdb symbols on windows [duplicate]

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.)

Must link to dependent libraries' dependents; why?

I have an application - let's call it "P" - that uses custom SO's: A.so, B.so, and C.so
The A.so library uses another custom library - D.so - as well as SSL and the math library.
The "P" application makes no calls whatsoever to SSL or math routines.
On macOS (with clang), I could build P with -lA -lB -lC and all was good.
I'm migrating everything to Linux (Debian) with GCC.
Now, when I bulid P, I have to -lA -lB -lC -lD -lm -lssl
What am I doing wrong?
I'm using simple makefiles - no autoconfig, no cmake, etc.
Could this be an "install_name_tool" vs. "chrpath" issue when I build the libraries?
This is because of a combination of the following two factors:
On macOS, the standard C library (libSystem.dylib) which is automatically linked by the compiler already includes a lot more functionality than on Linux. It may include some (or all) the necessary functions for your program. For example, as you can read from this documentation page, libSystem already includes the math library (which is a separate file on Linux and needs to be linked with -lm).
The shared libraries you are linking were compiled for macOS with additional functions already embedded into them, so those don't need to link to other shared libraries. It is not uncommon for a library to depend on different other libraries on different operating systems.
On the other hand, on Linux, the standard C library is split into different files: -lc is automatically linked by the compiler, but the math library (-lm) and other parts (-ldl, -lpthread, etc) are not, and therefore need to be linked manually.
Solved it. Turns out that clang - regardless of development platform - is a lot more forgiving with the order of parameters and options when linking. With clang, you can pretty much put your -I, -L, -l, other options and object files in whatever order you want. Not so with gcc; it's much more particular. clang made me lazy.

How to compile with c11 standard library on OS X with clang?

Hey I am trying to compile c code that uses functions from the c11 standard library on OS X with clang.
The compiler option -std=c11 allows me to use c11 language features. But when I am using new functions like at_quick_exit I get the following warning implicit declaration of function 'at_quick_exit' is invalid in C99.
The source code has the following line #include <stdlib.h>
The clang option -stdlib does not help.
My Systems:
OS X Yosemite 10.10.3
$ clang -v
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
Ubuntu 14.04 LTS
$ clang -v
Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: x86_64-pc-linux-gnu
Thread model: posix
To be more explicit. How can I get on OS X a c11 standard library?
Thanks for any kind of help.
Typically a self-hosted system compiler alone does not provide the full Standard C environment including runtime libraries. Typically the underlying system provides most, if not all, of the libraries (and headers), while the compiler just compiles.
So, if you need some specific functions that are not provided on a given system then you will have to write them yourself, or source them from some portable library that is compatible with your target system.
In this particular case you will also probably find that quick_exit() itself is not provided by the system's libc, and so it should be easy enough to write both functions on your own.

linking library built with g 2.95.2 to object files built with gcc 4.6

I'm trying to reuse an old static library built with Linux GCC 2.95.2. I'm using a recent compiler (GCC 4.6) from a 32bit Ubuntu distro. The library is written in C++. I have problems linking against the functions which are encapsulated in classes.
I guess that the naming of the symbols has changed.
http://www.qnx.com/developers/docs/6.3.2/momentics/compatibility/about.html#C++_code:
GCC 2.95.3 (from 6.2.1 or 6.3) and GCC 3.3.5 use different C++ ABIs and have different name mangling. As a result, you can't link C++ binaries (objects, executables, libraries) built with GCC 2.95.3 with binaries built with GCC 3.3.5.
The error output of ld is:
undefined reference to `foo1::Bar()'
(class foo1; Member Bar)
With the tool mn the symbols could be read out. The matching symbol is named in a different way:
Bar__4Foo1
Question: Is there a way the rename the symbols in the library file? Or can I force ld to accept the old naming format?
I guess that the naming of the symbols has changed.
Correct.
What you are missing is that the naming has changed for a reason, namely code produced by g++ 2.95 and g++ 3.3 is ABI incompatible. If you were allowed to link two objects compiled with these compilers together, all you'd get is unexplainable crashes.
By changing the name mangling, GCC developers have saved you the trouble of debugging such crashes.
Is there a way the rename the symbols in the library file?
There is, but if you succeed with that, you'll end up with said crashes, so don't shoot your foot off.

How to trace or debug GMP?

I have downloaded the source of GMP library 5.02, and - as suggested here for maximum debuggability - I ran :
./configure --disable-shared --enable-assert --enable-alloca=debug --host=none CFLAGS=-g
and compiled it with make, then installed the library with make install. I then compiled my program like this: gcc -lgmp -std=c99 -g -c program.c and then I ran : ltrace ./a.out
However I realized that ltrace is not at all invoking the TRACE() functions I can find in the source code. I would like to trace the content that's in TRACE().
How should I go for that? Or is there any other straightforward way of debugging inside the GMP library? (I couldn't figure it out how to do it with gdb, it never wanted to step into gmp_printf)
Thanks.
EDIT:
I tried to investigate further, and realized that I couldn't modify the GMP library although I had the sources. I inserted a printf("hello\n"); at the very beginning of the mpz_init2 function which I do call at the beginning of my program, I recompiled all GMP (even after a make clean) re-installed the library with make install, then I compiled and launched my program, but it never printed "hello". I also made sure, I wasn't using another installed GMP library (when I do make uninstall my program cannot compile as it does not find the library). Still, I insisted that gcc looks for the library in the GMP source folder with the -L option.
I don't know what I'm doing wrong :(
Your final compile of a.out is not producing a statically linked a.out executable. So, even though as you state, during compilation of program.c the compiler is using your GMP library, at runtime it is picking up a shared library somewhere. You need to do one of two things:
Compile with -Bstatic (or something similar; check man page for your compiler)
Set the LD_LIBRARY_PATH (or something similar; check 'ld' or 'dyld' man pages)
I think #1 is actually your only choice given that you built only the static version of GMP. For #1 make sure you explicitly provide -L/path/to/gmplib in the compilation of program.c

Resources