I have some helper purposes in a makefile that I want to restrict for internal or "private" use (only) inside the makefile. That is, I want to specify these targets as dependencies from the makefile, but I want the target not to be specified as the build target from the command line. It is very similar to the private function from OOP: the goal is harmful (or simply does not make sense) to build separately.
I want a special target .HIDDEN or .PRIVATE or something similar, similar to what .PHONY does for non-file purposes, but I donโt think it exists. The private keyword is for variables only.
What is a good / general / elegant way to protect a target for internal / private use only?
The best workaround I could come up with is to check $(MAKECMDGOALS) for "unacceptable" purposes, then an error if indicated; it seems inelegant. I am sure that the makefile can be rewritten to avoid this situation - perhaps an excellent solution, but it is not.
Under the neckline ... here's a contrived example to illustrate.
Although I'm looking for a general solution, one example of goals that are harmful as individual / primary goals is the inheritance of the target values โโof the variables:
override CFLAGS += -Wall all : debug %.o : %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< debug : CFLAGS += -g3 -O0 release : CFLAGS += -O3 debug : CPPFLAGS += -DDEBUG release : CPPFLAGS += -DRELEASE debug release : foo.o bar.o main.o $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) clean: -rm -f *.o debug release .PHONY: all clean
The implicit rule is duplicated (optional) for illustration. For the purpose of debug or release , foo.o and others inherit the corresponding CFLAGS and CPPFLAGS - if one make clean debug , all objects will be consistent. But, for example, if someone creates foo.o separately, he will not be able to inherit the corresponding flags; for example, make clean foo.o debug you get foo.o , built by default CFLAGS ; then when creating debug it does not need to be updated, so it will be associated with other objects with different optimizations or different macro settings. It will probably work in this case, but it is not what was intended. Marking foo.o etc., since illegal targets can interfere with this.
EDIT:
It is clear that my example (above) was not a good choice for my more general question: hiding goals was not the best way to fix the problem with my example. Here is a modified example illustrating the modified question, "How to apply target values?" - It is based on comments from @Michael, @Beta, @Ross below and allows you to pose and respond to this more limited scenario.
As described in previous answers below, in this case it is much better to create objects that have different assembly flags in different places. eg,
bin_debug/%.o : %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< bin_release/%.o : %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< OBJS = foo.o bar.o main.o
The template rule is duplicated because I think it should be (several "template goals" ( % ) to convince make all goals are built at once with one recipe, see the questions SO this and this ).
So add to the target flags:
debug : CPPFLAGS += -DDEBUG release : CPPFLAGS += -DRELEASE
But it still suffers:
make bin_debug/foo.o
will not get CPPFLAGS from debug . I accepted @Michael's answer below, as it made me think about this issue in a more useful way, but also answered some of my own rhetorical questions below.