How can I make a target “private” in GNU make for internal use only? OR: how to best enforce target-specific variable-values?

后端 未结 5 1917
别那么骄傲
别那么骄傲 2021-02-19 13:14

I have some ancillary targets in a makefile that I want to restrict for internal or \"private\" use (only) inside the makefile. That is, I want to be able to specify these targ

5条回答
  •  半阙折子戏
    2021-02-19 14:13

    One solution to the problem is to migrate the CPPFLAGS to the pattern rules (e.g., bin_debug/%.o: CPPFLAGS...) instead of the regular rule (debug: CPPFLAGS...), final result:

    bin_debug/%.o   : CPPFLAGS += -DDEBUG
    bin_debug/%.o   : %.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
    bin_release/%.o : CPPFLAGS += -DRELEASE
    bin_release/%.o : %.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
    OBJS = foo.o bar.o main.o # or $(SRCS:.o=.c)
    DEBUG_OBJS   = $(addprefix bin_debug/,$OBJS)
    RELEASE_OBJS = $(addprefix bin_release/,$OBJS)
    debug   : $(DEBUG_OBJS)
    release : $(RELEASE_OBJS)
    debug release :
        $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
    

    so make bin_debug/foo.o will get CPPFLAGS including -DDEBUG.

    Now, lets say you have >>2 rules: debug, release, config01, config02, config03, ... each with their own CPPFLAGS.

    One way might be to continue reduplicating all of the pattern rules, but that gets annoying if anything has to change. Furthermore it's not really possible to use in a foreach. This seems handy:

    debug    : CPPFLAGS+=-DDEBUG
    release  : CPPFLAGS+=-DRELEASE
    config01 : CPPFLAGS+=-DSOMETHING
    config02 : CPPFLAGS+=-DSOMETHINGELSE
    TARGETS = debug release config01 config02
    OBJS = foo.o bar.o main.o # or $(SRCS:.o=.c)
    define TARGET_template
     bin_$(1)/%.o : %.c
        $$(CC) $$(CFLAGS) $$(CPPFLAGS) -c -o $@ $<
     $(1): $(addprefix bin_$(1)/,$(OBJS))
     # other TARGET-specific stuff here
    endef
    $(foreach tgt,$(TARGETS),$(eval $(call TARGET_template,$(tgt))))
    

    But still doesn't fix the situation of make bin_debug/foo.o -- still doesn't get CPPFLAGS.

    So, instead of making target-specific variable-value like debug: CPPFLAGS+=... you could have a variable that is specific to the target, like CPPFLAGS_debug, then add to each rule:

    CPPFLAGS_debug    = -DDEBUG
    CPPFLAGS_release  = -DRELEASE
    CPPFLAGS_config01 = -DSOMETHING
    CPPFLAGS_config02 = -DSOMETHINGELSE
    TARGETS = debug release config01 config02
    OBJS = foo.o bar.o main.o # or $(SRCS:.o=.c)
    define TARGET_template
     bin_$(1)/%.o : CPPFLAGS+=$$(CPPFLAGS_$(1))
     bin_$(1)/%.o : %.c
        $$(CC) $$(CFLAGS) $$(CPPFLAGS) -c -o $$@ $$<
     $(1): $(addprefix bin_$(1)/,$(OBJS))
     # other TARGET-specific stuff here
    endef
    $(foreach tgt,$(TARGETS),$(eval $(call TARGET_template,$(tgt))))
    

    Beware; above may need more $$(...)s, untested.

    Problems? Better way?

提交回复
热议问题