如果使用dif标志编译,则重建所有的Makefile

时间:2014-09-15 00:50:04

标签: makefile gnu-make

所以我有一段艰难的时间试图弄清楚如何制作我的Makefile,这样当我make并编译发布版本然后再进行make debug它如果文件尚未更新,则在gcc上设置新的-DDEBUG-g编译调试版本。

例如:

  1. main.cpp已编辑
  2. 运行make
  3. 编译main.cpp
  4. 运行make debug
  5. main.cpp未重新编译,因为即使编译标志不同,也没有任何更改
  6. 注意我不想每次都要做一个干净,因为我不想重新编译文件,如果我连续做2 make所以设置干净作为依赖不是这将是一个有效的答案

3 个答案:

答案 0 :(得分:1)

您可能希望根据构建模式将目标文件编译到不同的目录中,例如:

# default mode, override with `make BUILD=release`
BUILD := debug
obj_dir := ${BUILD}

CFLAGS.debug := -g -O0
CFLAGS.release := -g -O3 -march=native -DNDEBUG

all : ${obj_dir}/test

# Example executable
${obj_dir}/test : ${obj_dir}/test.o

test.c :
    echo "int main() { return 0; }" > $@

# Generic rules

${obj_dir} :
    mkdir $@

${obj_dir}/%.o : %.c Makefile | ${obj_dir} # Also recompile when Makefile changes.
    ${CC} -c -o $@ ${CPPFLAGS} ${CFLAGS} ${CFLAGS.${BUILD}} -MD -MP $<

${obj_dir}/% : Makefile | ${obj_dir} # Also re-link when Makefile changes.
    ${CC} -o $@ ${LDFLAGS} $(filter-out Makefile,$^) ${LDLIBS}

clean :
    rm -rf ${obj_dir}

-include $(wildcard ${obj_dir}/*.d)

${obj_dir}/*.d : ;

.PHONY: all clean

(奖励功能:自动依赖关系生成)。

用法:

[max@localhost:~/tmp] $ make
mkdir debug
echo "int main() { return 0; }" > test.c
cc -c -o debug/test.o   -g -O0 -MD -MP test.c
cc -o debug/test  debug/test.o 

[max@localhost:~/tmp] $ make
make: Nothing to be done for 'all'.

[max@localhost:~/tmp] $ make BUILD=release
mkdir release
cc -c -o release/test.o   -g -O3 -march=native -DNDEBUG -MD -MP test.c
cc -o release/test  release/test.o 

[max@localhost:~/tmp] $ make BUILD=release
make: Nothing to be done for 'all'.

答案 1 :(得分:0)

首先,您不应该运行make debug - 这意味着您要构建不同的目标(debug)。但是你没有,你想用不同的选项构建相同的目标。这就是你所做的,你运行一个不同的选项,一个变量值

>make DEBUG=Y

运行时

>make

你也真的传递了那个变量,只是将空字符串作为值。

现在,为了让它在Makefile中按你想要的方式工作,你可能希望它就像DEBUG是必备文件一样,其配方如下:

foobar.o: foobar.c DEBUG
    gcc $(if $(DEBUG), -DDEBUG -g) -c $< -o $@

当然,通常这不起作用,因为DEBUG是变量,而不是文件。所以你需要一个黑客,我称之为“可靠的变量”。它基本上是一种声明变量的行为方式。我在其他一个答案中描述了这种技术:

How do I add a debug option to Makefile

答案 2 :(得分:0)

我曾经做过这样的事情,看起来像那样(归结为最低限度):

EXE     := a.out
SRC     := $(wildcard *.c)

ifneq ($(MAKECMDGOALS),debug)
OBJ     := $(SRC:.c=.o)
else
OBJ     := $(SRC:.c=-d.o)
endif

.PHONY: all debug

all:    $(EXE)

debug:  CFLAGS += -g -DDEBUG
debug:  $(EXE)

$(EXE): $(OBJ)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

%.o %-d.o:  %.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<

诀窍是使用两个单独的目标文件列表,并根据目标选择一个。