This Time Self-Hosted
dark mode light mode Search

Fixing CFLAGS/LDFLAGS handling with a single boilerplate Makefile (maybe an eclass, too?)

So, in the last few weeks I’ve been filing bugs for packages that don’t respect CFLAGS (or CXXFLAGS) using the beacon trick. Beside causing some possibly false positives, the testing is going well.

The problem is that I found more than a couple of packages that either do call gcc manually (I admit I’m the author of a couple of ebuilds doing that) or where the patch to fix the Makefile would be more complex than just using a boilerplate makefile.

So what is the boilerplate makefile I talk about? Something like this:

$(TARGET): $(OBJS)
        $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

Does it work? Yes it does, and it will respect CFLAGS, CXXFLAGS and LDFLAGS just fine, the invocation on an ebuild (taking one I modified earlier today) would be as easy as:

src_compile() {
    emake CC="$(tc-getCC)" 
        TARGET="xsimpsons" 
        OBJS="xsimpsons.o toon.o" 
        LIBS="-lX11 -lXext -lXpm" || die "emake failed"
}

Now of course this would suck if you had to do it for every and each ebuild, but what if we were to simplify it to an eclass? Something like having an ebuild just invoking it this way:

ESIMPLE_TARGET="xsimpsons"
ESIMPLE_OBJS="xsimpsons.o toon.o"
ESIMPLE_LIBS="-lX11 -lXext -lXpm"

inherit esimple

For slightly more complicated things you could make it use PKG_CONFIG too…

ESIMPLE_TARGET="xsimpsons"
ESIMPLE_OBJS="xsimpsons.o toon.o"
ESIMPLE_REQUIRED="x11 xext xpm"

inherit esimple

so that it would call pkg-config for those rather than using the libraries directly (this would allow to simplify also picoxine’s ebuild for instance that uses xine-lib).

Even better (or maybe I’m getting over the top here ;)), one could make the eclass accept a possibly static USE flag that would call pkg-config --static instead of standard pkg-config and append -static to the LDFLAGS, so that the resulting binary would be, well, static…

If anybody has comments about this, to flesh it out before it could actually be proposed for an eclass, it would be a nice time to say here so we can start with the right foot!

Comments 7
  1. Doesn’t seem to fit well with our general policy of upstreaming changes. That applies to fixing upstream’s build system too, IMHO.

  2. Should it be OBJS=”xsimpsons.o toon.o” or SRCS=”xsimpsons.c toon.c” with an extra rule that transforms SRCS to OBJS to get better parallelization?This looks like it’s doing down the same route I went for ebdftopcf.

  3. I try to send mails upstream about these problems, but there are tons of small packages that don’t even _care_ about makefiles :(And for those, such an eclass would probably help…

  4. Robin, what do you mean about that? How changing it to SRCS would improve parallelisation? GNU make will take care of that, whatever OBJS is…If we used SRCS and pass them at one build call, _that_ wouldn’t parallelise…

  5. I think make “standard” is to use LDLIBS for lib linking:

    $ cat Makefileall: bar
    $ LDLIBS="-lm" makecc     bar.c  -lm -o bar

    maybe even shorter:

    $ cat Makefileall: barbar: bar.o foo.o
    $ LDLIBS=-lm makecc    -c -o bar.o bar.ccc    -c -o foo.o foo.ccc   bar.o foo.o  -lm -o bar

    which in turn gives:

    $ LDFLAGS="-Wl,--as-needed" CFLAGS="-O2" LDLIBS=-lm makecc -O2   -c -o bar.o bar.ccc -O2   -c -o foo.o foo.ccc -Wl,--as-needed  bar.o foo.o  -lm -o bar
  6. This whole topic makes me feel worth mentioning dev-util/confix (“Confix”:http://confix.sourceforge.net, “A Build Tool on Top of GNU Automake”).Confix creates automake/autoconf-input files, to create one library per directory, or one executable per directory when “main()” is found therein, optionally using libtool, by simply searching the C/C++ source code.It requires an (usually) empty file in each directory to consider, and one toplevel file containing the package name and version.Inter-directory dependencies are also resolved to link dependent libraries together, simply triggered by @#include@ lines found in the source code.Additionally, some repo-file is installed to allow for resolving inter-package dependencies automagically.

  7. Nice idea, though I think it needs a bit of tweaking.$(COMPILE.c) by default (on GNU) is:$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -cand $(LINK.c) is:$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)These are used for pattern rule %: %.c as:$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@and for %.o: %.c as:$(COMPILE.c) $(OUTPUT_OPTION) $<where OUTPUT_OPTION = -o $@We use LDLIBS for project-wide libs like -lc or -lm (which are in specs on some systems) and LOADLIBES for libs for the individual case, although they’re both there for historical reasons aiui.$(LINK.o) is just:$(CC) $(LDFLAGS) $(TARGET_ARCH)used for %: %.o as:$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@Overall I’d say it’d be better to allow make to use its default rules as far as possible. You can either just not specify any rules, only the deps, or use the above as a basis for a more standardised setup.see: make -p # for more rules.I think the static idea is definitely worth pursuing.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.