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?
2
Answers
Solved it. Turns out that
clang
- regardless of development platform - is a lot more forgiving with the order of parameters and options when linking. Withclang
, you can pretty much put your-I
,-L
,-l
, other options and object files in whatever order you want. Not so withgcc
; it's much more particular.clang
made me lazy.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.