在makefile中,如何在变量中的每个文件名上执行命令?

时间:2009-10-16 06:21:50

标签: c++ makefile

我知道我做错了,但我无法弄清楚如何组织这个makefile。我定义了我的util源文件,并使用一些函数在这里定义.o文件:

UTIL_SRC = utils/src/foo.cpp utils/src/bar.cpp utils/src/baz.cpp

UTIL_OBJS = $(patsubst utils/src/%.cpp,utils/obj/%.o,$(UTIL_SRC))

这是我使用这些文件的目标:

lib : lib/libutils.a

lib/libutils.a : $(UTIL_OBJS)
    rm -f lib/libutils.a
    ar -c -q lib/libutils.a $(UTIL_OBJS)

然后,当我达到编译这些婴儿的规则时,我希望只有一个命令可以遍历每个UTIL_OBJS文件和每个UTIL_SRC文件。相反,我采用了这种怪物,这使得将它们存储在变量中的目的就失败了。

$(UTIL_OBJS) : $(UTIL_SRC)
    g++ $(UTIL_FLAGS) utils/src/foo.cpp -o utils/obj/foo.o
    g++ $(UTIL_FLAGS) utils/src/bar.cpp -o utils/obj/bar.o
    g++ $(UTIL_FLAGS) utils/src/baz.cpp -o utils/obj/baz.o

我可以将其浓缩为一行吗?怎么样?谢谢,很棒!

2 个答案:

答案 0 :(得分:9)

使用隐式规则通常更容易。有很多预定义的,你只需要指定变量。

CXX=g++
CXXFLAGS=$(UTIL_FLAGS)

然后你需要定义一个可执行文件,比如这个

myutil: $(UTIL_OBJS)

由于您没有将对象存储在同一目录中,因此您也需要指定一个新的隐式规则(否则,我们现在就完成)。

utils/obj/%.o: utils/obj/%.cpp

%是模式匹配,它将匹配左侧和右侧的相同文本,因此此规则将使foo.o脱离foo.cpp。 尝试在没有命令的情况下工作(它可能从另一个规则中抓取了它,我不确定),否则让它说:

utils/obj/%.o: utils/obj/%.cpp
    $(CXX) $(CXXFLAGS) -o $@ $^

$ @是规则的目标(例如foo.o),$ ^是右侧的所有文件。 我正在写这篇文章,没有测试的可能性,所以请让我知道结果如何.. :)

为了使它更优雅,您可以包含一个依赖文件

include .depend

如果你正在运行GNU make,它会尝试制作.depend文件,如果它找不到它(用旧学校制作,你需要先自己创建它,它可能只是一个虚拟,但是,如果你想通过makefile管理它

.depend: $(UTIL_SRC)
    $(CXX) -MM -o $@ $^

依赖项文件将包含每个.cpp文件的行,告诉make它需要哪些头文件,这将允许make在您更改某些内容时重新编译必要的文件。这对你原来的问题没有帮助,只是觉得它可能会派上用场。

修改:
作为对您的编辑的回复。您也可以删除用于创建.a文件的命令,这些命令也已作为隐式规则提供。虽然不确定它是如何工作的,但还没有使用它。我知道在处理.a(rchive?)文件时有很多怪癖。

答案 1 :(得分:0)

我想你可以用这个:

$(UTIL_OBJS) : $(UTIL_SRC)
    g++ $(UTIL_FLAGS) $(@ : .o = .cpp)  -o $@ 

再次,我不太确定...特别是$(@:。cpp = .o)部分