这是我编写的一个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
由于
答案 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。