生成的文件名作为变量的输入

时间:2014-05-14 08:20:21

标签: c makefile

我在不同的文件中有很多功能。

例如:OBJ_SRC=sum.c sub.c mul.c div.c remainder.c

当我创建一个库时,我喜欢这样:

libarithmatic.a: $(OBJ_SRC)
     gcc -c $(OBJ_SRC)  # creates sum.o sub.o.. 
     ar rcs libarithmatic.a $(OBJS) #<--- problem @OBJS

如何将gcc -c $(OBJ_SRC)add.o sub.o mul.o..(新创建/更新的文件名)的输出存储到OBJS变量中?

1 个答案:

答案 0 :(得分:1)

通常的方法是使用patsubst

OBJS=$(patsubst %.c,%.o,$(OBJ-SRC))

现在调用gcc作为构建库的目标的一部分是一个坏主意。它忽略了使用make的主要观点,因为你要求gcc盲目地重新编译所有对象,而不是让make找到已经改变的对象。通常的规则是:

libarithmatic.a: $(OBJS)
        ar rcs libarithmatic.a $(OBJS)

您可以输入pattern rule来编译.c文件,但如果您只是放入

%.o: %.c
        gcc -c $<
你不必打扰,因为那是隐含的。好吧,default implicit rule确实是

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

其中CC默认为合适的编译器,您可以覆盖它,CPPFLAGSCFLAGS默认为空,您可以将它们设置为您要用于编译的任何标志。 CPPFLAGS适用于C和C ++,CFLAGS仅适用于C,CXXFLAGS仅适用于C ++(C ++编译器为CXX)。


另一方面,我建议查看CMake,它支持为各种平台,IDE和新的超快ninja生成构建文件。相应的CMakeLists.txt

一样简单
project(arithmatic)
add_library(arithmatic sum.c sub.c mul.c div.c remainder.c)

并使其成为一个简单的共享库,如果你想要添加SHARED关键字那么简单。


请注意,%占位符不必位于开头。如果要将对象放在源的不同目录中,可以编写

之类的内容
OBJS=$(patsubst src/%.c,obj/%.o,$(SOURCES))

(在这种情况下,源必须列出目录前缀)或者

OBJS=$(patsubst %.c,.objs/%.o,$(SOURCES))

你也可以在规则中使用模式,所以

obj/%.o: src/%.c
        mkdir -p obj
        $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<

.objs/%.o: %.c
        mkdir -p .objs
        $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<

您必须确保输出目录存在,因为编译器不会创建它(因此我在规则中包含mkdir)并且您必须显式指定编译器输出,因为它会创建它在当前目录中,否则。