我有一个看起来像这样的makefile:
CS := a.c b.c
CPPS := foo.cpp bar.cpp
SOURCES := $(CS) $(CPPS)
OBJS := $(CS:%.c=$(OBJSDIR)/%.o) $(CPPS:%.cpp=$(OBJSDIR)/%.o)
我想创建一个单独的规则来编译它们。但我能想到的唯一选择是:
$(OBJSDIR)/%.o: %.cpp
$(GXX) $(GXXFLAGS) -c $< -o $@
但当然它不起作用,因为某些目标文件没有匹配的C ++源文件。
有什么想法吗?
答案 0 :(得分:2)
假设你有a.cc,b.cc和c.cc,另一方面是d.c,e.c和f.c
program_objs = a.o b.o c.o d.o e.o f.o
program: $(program_objs)
$(CC) $(LDFLAGS) -o $@ $(program_objs)
你不再需要任何东西了,因为make会自动检测哪些文件是c ++,哪些文件是普通c,并会选择合适的编译器。
如果你想要一些特殊的东西,不包含在makefile中,你可以用规则添加一些后缀(文件类型):
.SUFFIXES: .a .b .o
然后使用以下规则将它们编译为.o
.a.o:
$(COMPILER_A) $(COMPILER_A_FLAGS) -c $@ -o $<
.b.o:
$(COMPILER_B) $(COMPILER_B_FLAGS) -c $@ -o $<
让makefile选择合适的编译器(存储在变量COMPILER_A或COMPILER_B中的编译器)来完成工作。
当然,您可以使用显式规则将某些内容编译为.o文件,如:
a.o: a.cc
g++ -o a.o -c a.cc
b.o: b.cc
g++ -o b.o -c b.cc
c.o: c.cc
g++ -o c.o -c c.cc
d.o: d.c
gcc -o d.o -c d.c
e.o: e.c
gcc -o e.o -c e.c
f.o: f.c
gcc -o f.o -c f.c
已经对GNU make%模式进行了一些描述,以构建目标的隐式规则。下面是重写上面的隐含规则来做同样的事情:
%.o: %.a
$(COMPILER_A) $(COMPILER_A_FLAGS) -c $@ -o $<
%.o: %.b
$(COMPILER_B) $(COMPILER_B_FLAGS) -c $@ -o $<
与往常一样,$@
表示规则的目标,$<
(您也可以使用$*
作为文件名,没有任何匹配的后缀)左侧需要的文件。有关可以使用的自动变量的完整列表,建议您阅读制作手册。考虑到旧的后缀语法与新的语法相反(目标后缀在旧语法中最后出现,新语法更类似于冒号左侧的目标的普通makefile规则)
答案 1 :(得分:0)
我想创建一个单独的规则来编译它们。
正如Etan Reisner在评论部分所说,make已经有隐式规则来编译.c
和.cpp
文件,所以你问题的真正答案是:
不要写任何内容来编译您的目标文件。
也就是说,您现在应该删除这两个变量:$(GXX)
和$(GXXFLAGS)
。
要向cc
或gcc
提供标记,应使用CFLAGS
内置变量。
要向g++
提供标记,应使用CXXFLAGS
内置变量
要向预处理器(cpp
)提供标志,应使用CPPFLAGS
变量。
由于您正在混合使用C和C ++源文件,因此应使用CXX
变量作为链接器命令。