En un Makefile, ¿cómo puedo evitar que se incluya un prerrequisito falso en $ ^

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.

Aquí hay un ejemplo:

    .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.

preguntado el 09 de marzo de 12 a las 22:03

2 Respuestas

You might consider an requisito previo de solo pedido:

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

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

respondido 09 mar '12, 22:03

Strangely, make is not running my order-only prerequisite first, although I'm not sure how it knows that it can get away with this. It does mess up output though, because now I see things compiling before I echo details of the compile that is starting, which is one thing that start does. - Michael

If you want a prereq to run before the build of something, it needs to be a prereq of that something. In this example, start is NOT a prereq of the .o file, so the .o file might be built first (or at the same time if you use -j). The only order implied currently is that start runs before the link step. - chris dodd

You could put the phony target after the .o target and then use $< en lugar de $^:

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 $@ 

respondido 09 mar '12, 22:03

The first way is fine as long as the target doesn't need more than one object file. The second is effective and only slightly kludgey. +1 - Beta

In some cases I have multiple object files, so the second method would have to be used. This is just a shorter version of something I tried, and I think the problem with it remains that it is still going to try to re-build the executable even if it doesn't need to be, because it thinks start changed. - Michael

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.