ld --as-needed breaks implicit rules in make

Bug #874588 reported by Elliot Kendall
28
This bug affects 5 people
Affects Status Importance Assigned to Milestone
make-dfsg (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

The default use of --as-needed with ld in oneiric breaks some implicit rules used by make. These rules invoke cc with command line in which $(LDFLAGS) appears before the source file being compiled or object file being linked, and that order is preserved when cc invokes ld. As a result, ld thinks the libraries listed in LDFLAGS aren't needed and doesn't link them.

For example, consider a C source file, example.c:

#include "zlib.h"
int main() {
  inflateInit(0);
}

and a Makefile:

LDFLAGS = -lz
example: example.o

Running make invokes make's implicit rule for linking a single object file ("$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)"), and produces the following output:

cc -c -o example.o example.c
cc -lz example.o -o example
/tmp/ccovHoBb.o: In function `main':
example.c:(.text+0x14): undefined reference to `inflateInit_'
collect2: ld returned 1 exit status
make: *** [example] Error 1

Behind the scenes, ld is being run as "ld --as-needed ... -lz example.o ...". When ld processes libz, it doesn't know about any of the references from example.o, so it doesn't include it.

This problem seems to have prevented at least one package (sawfish-pager) from being included in oneiric because it would no longer compile, and I worry that there may be others.

I'm not sure what the best solution would be. One possibility would be patching make to change its implicit rules, but that could have serious consequences elsewhere. At the very least, it would necessitate patching other programs that run UNIX makefiles, such as remake and pmake.

Revision history for this message
Dave Gilbert (ubuntu-treblig) wrote :

So my reading is what you're saying is that the implicit rules in make need changing to match the use of --as-needed?

affects: ubuntu → make (Ubuntu)
Revision history for this message
Elliot Kendall (elliotkendall) wrote :

That's one possible solution, yes. I don't claim to understand this kind of thing well enough to know if that's necessarily a good idea, though.

Revision history for this message
Matthias Klose (doko) wrote :

why use LDFLAGS for libraries in the first place? if the implicit rule offers to use LDLIBS, then please use it. This is not different than the packages using LDFLAGS for libraries outside implicit rules.

see https://wiki.ubuntu.com/OneiricOcelot/ReleaseNotes?action=show&redirect=OneiricOcelot%2FTechnicalOverview#GCC_4.6_Toolchain

Revision history for this message
Elliot Kendall (elliotkendall) wrote :

I agree it does seem preferable to use LDLIBS or LOADLIBES for libraries, but not necessarily incorrect to put them in LDFLAGS.

The GNU make manual defines LDFLAGS as "Extra flags to give to compilers when they are supposed to invoke the linker," which doesn't seem to exclude something like "-lz". It mentions LDLIBS and LOADLIBES, but doesn't define them. Mecklenburg's Managing Projects with GNU make says LDFLAGS "holds options for linking such as -L flags," while LDLIBS and LOADLIBES "contain lists of libraries to link against," which is a little clearer but still not great.

Would there be any harm in moving LDFLAGS in make's implicit rules?

And if it is strictly incorrect to put libraries in LDFLAGS, could make generate a warning when they appear there? At the very least, it would be nice to mention this in the manual.

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in make (Ubuntu):
status: New → Confirmed
Logan Rosen (logan)
affects: make (Ubuntu) → make-dfsg (Ubuntu)
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.