You have fallen foul of a difference between the linkage conventions of
Fedora's GCC builds and Debian/Ubuntu's GCC builds.
When you invoke gcc
to perform linkage of a C executable it in turn invokes the system linker
ld
, passing it your commandline linkage options and silently adds to
them a large number of "boilerplate" linkage options which are invariant
for C language linkages (similarly for g++
and C++ language linkages).
Those invariant linkage options are decided by your distro and configured
into their build of GCC. So they are not invariant across distros.
Debian/Ubuntu GCC silently adds --as-needed
to the linkage options at a
position before your input files and libraries. Fedora's GCC does not.
The effect of --as-needed
is to make the linker link a shared library
that it finds in the linkage sequence only if that library provides
a definition of one or more symbols for which the linker has already found
undefined references (i.e. within object files or libraries earlier
in the linkage sequence). This behaviour applies in any case for static libraries.
So --as-needed
makes the linkage rules similar for both static and shared
libraries - which might be considered helpful to the average user.
This difference is a linkage policy difference between the distros. What it
means to you is that to link successfully on Ubuntu, your linkage commandline
must mention any library after any object file or other library that depends
on it. And if you are compiling-and-linking in one command, then you must
mention any library after any source file whose corresponding object file
depends on that library. So on ubuntu, your problem commandline should be:
gcc -I. -o test main.c -L. -lmy
to succeed. This will also of course work for Fedora.
If you are interested in inspecting the hidden differences in the linkage
options between the two distros you can reveal them by add -Wl,-v
to your
compile-and-link command to get verbose linker output.