make执行顺序的问题

时间:2016-05-16 04:07:37

标签: c++ terminal makefile

这是我编写的一个make文件,目前的目标是将目录中的所有c ++文件转换为目标文件。我的问题是它总是首先执行g ++然后再执行任何其他命令。

CC=g++
CPPFLAGS=`pkg-config --cflags --libs gtkmm-3.0`
SRCS=$(wildcard classes/source/*.cc)
PROGS=$(patsubst %.cc,%,$(SRCS))
CLASS_HEADERS=classes/
all: $(PROGS)
    mkdir -p build/release/objs 
%: %.cc
    $(CC) -I$(CLASS_HEADERS) -c $< -o build/release/objs/$(@F).o $(CPPFLAGS)

结果:

g++ -Iclasses/ -c classes/source/helloworld.cc -o build/release/objs/helloworld.o `pkg-config --cflags --libs gtkmm-3.0`
mkdir -p build/release/objs 

由于

3 个答案:

答案 0 :(得分:3)

最简单的解决方法是在使用目标目录之前始终发出mkdir。如果使用-p选项,冗余执行此命令确实没有坏处。

%: %.cc
   mkdir -p build/release/objs
   $(CC) -I$(CLASS_HEADERS) -c $< -o build/release/objs/$(@F).o $(CPPFLAGS)

正如我对GNU make's -j option的回答中所述:虽然它有时可行,但在现有mkdir依赖关系列表中简单地添加all目标作为初始依赖关系是不正确的。原则上,这些可以按任何顺序执行(因此mkdir不一定是第一个)。如果你想采用基于依赖的方法,你必须开始做更复杂的事情。例如,使用make递归:

all: do_mkdir
   $(MAKE) $(progs)

do_mkdir:
   mkdir -p build/release/objs

答案 1 :(得分:1)

可能的解决方案是为对象目录创建目标并将其放在构建目标之前:

......
OBJ_DIR := build/release/objs

all: create_obj_dir $(PROGS)

create_obj_dir:
    mkdir -p  $(OBJ_DIR)

%: %.cc
    $(CC) -I$(CLASS_HEADERS) -c $< -o $(OBJ_DIR)/$(@F).o $(CPPFLAGS)

答案 2 :(得分:1)

目标的配方在任何先决条件之后执行,因此当您all生成$(PROGS)之前,{}运行mkdir之前将会{。}}。

build/release/objs应该是目标文件的先决条件,因为除非目录存在,否则无法创建它们。该目录也应该是order-only prerequisite,因为如果目录时间戳发生变化,您不希望重新映射每个目标文件。

您的模式规则也是broken(参见2),并且您使用了错误的flag variables。您还可以回收built-in implicit rule for compiling

CXXFLAGS := $(shell pkg-config --cflags --libs gtkmm-3.0)
CPPFLAGS := -Iclasses/
SRCS     := $(wildcard classes/source/*.cc)
OBJS     := $(SRCS:classes/source/%.cc=build/release/objs/%.o)

.PHONY: all
all: $(OBJS)

$(OBJS): build/release/objs/%.o: classes/source/%.cc | build/release/objs
    $(COMPILE.cc) $(OUTPUT_OPTION) $<

build/release/objs: ; mkdir -p $@

旁注:由于您只是编译-libs gtkmm-3.0可能不应该在标志中,因此在链接时提供了lib。