我在不同的文件中有很多功能。
例如: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
变量中?
答案 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
默认为合适的编译器,您可以覆盖它,CPPFLAGS
和CFLAGS
默认为空,您可以将它们设置为您要用于编译的任何标志。 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
)并且您必须显式指定编译器输出,因为它会创建它在当前目录中,否则。