Michael
Michael

Reputation: 9402

In a Makefile, how do I prevent a phony pre-requisite from being included in $^

I have a pre-requisite that I need to declare for a target that needs to always run before I try to build the target. It doesn't actually generate a file. The problem is, if I declare it as the first dependency of the target itself, then the phony dependency winds up in $^ and confuses a subsequent step of linking.

Here is an example:

    .PHONY: start
    sample-prog-1 : start sample-prog-1.o

Elsewhere I have a rule for building an executable from the object file:

%: %.o
        echo "Building executable $@";$(CC) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)

Problem is, "start" is a phony target, so it doesn't exist, but the link stage is being called with "start" as one of the object files, so the build process croaks!

I found a work-around, which is simply to strip out "start" from the list of object files:

%: %.o
    echo "Building executable $@";$(CC) $(LDFLAGS) $(shell echo "$^" | sed s/start//g) $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)

But in addition to seeming very hacky and ugly, it also means I can't have any source files that have "start" in them. I also wind up always re-building sample-prog-1, as "begin" always winds up being remade.

This just seems like the wrong solution, but I'm at a loss as to what the "right" way to do this is. I'm thinking I should do something where I factor out the executable with something like this:

    sample-prog-1 : sample-prog-1.o
    do_sample-prog-1 : start sample-prog-1

But this is unintuitive, because now if I want to build a given target i have to remember to prepend or append some other string to that target name so that the start code will be run before the executable is built.

Upvotes: 1

Views: 318

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126175

You could put the phony target after the .o target and then use $< instead of $^:

sample-prog-1 : sample-prog-1.o start

%: %.o
        echo "Building executable $@";$(CC) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS) -o $@ $(LDFLAGS_$@)

Or, if you're using gnu-make, use the builtin filter to get just the object files:

$(CC) $(LDFLAGS) $(filter %.o $^) $(LOADLIBES) $(LDLIBS) -o $@ 

Upvotes: 1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

You might consider an order-only prerequisite:

sample-prog-1 : sample-prog-1.o | start

Amongst other things, order-only prerequisites don't appear in $^.

Upvotes: 2

Related Questions