我有一个C / C ++混合项目,对于每个源代码,我想从程序集生成一个程序集文件(.S
),然后生成一个目标文件(.o
)。我认为以下Makefile应该可以工作:
all: a.o b.o main.o
g++ $^ -o main
%.o: %.S
gcc -o $@ $<
%.S: %.c
gcc -S -o $@ $<
%.S: %.cc
g++ -S -o $@ $<
clean:
rm -rf *.o main
理想情况下,为了生成X.o
,需要使用其中一个规则生成X.S
,具体取决于X.c
或X.cpp
是否可用。
然而,make
显然不像我想象的那样工作。它会转换为X.o
的默认规则,并且%.S: %.c
和%.S: %.cpp
都未应用... make -n
提供
cc -c -o a.o a.c
g++ -c -o b.o b.cc
g++ -c -o main.o main.cc
g++ a.o b.o main.o -o main
以下示例代码可以重现:
// a.c
int a() { return 0;}
// b.cc
int b() { return 0;}
// main.cc
extern "C" int a();
extern int b();
int main() { a(); b(); return 0; }
我必须对如何解决目标有一些误解。有什么想法吗?
答案 0 :(得分:0)
您需要取消隐式规则,因为它们是更好的匹配,添加以下行
%.o: %.cc
%.o: %.c
请注意,all
的规则被破坏,因为它没有创建名为all
的文件,make已经知道如何从程序集中汇编目标文件,而且它也已经知道如何链接对象如果其中一个目标文件与目标
assembly := a.s b.s main.s
objects := $(assembly:.s=.o)
.SECONDARY: $(assembly)
main: CC := $(CXX)
main: $(objects)
%.s: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -S -o $@ $<
%.s: %.cc
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -S -o $@ $<
%.o: %.cc
%.o: %.c
clean: ; $(RM) $(objects) $(assembly) main
答案 1 :(得分:0)
将Makefile顶部的.SUFFIXES:
用于flush predefined suffixes。工作示例:
$tail -n +1 a.c b.cc main.cc Makefile; make clean; make; ./main
==> a.c <==
#include <stdio.h>
void a(void) {
printf("a\n");
}
==> b.cc <==
#include <stdio.h>
void b(void) {
printf("b\n");
}
==> main.cc <==
extern "C" {
void a(void);
}
void b(void);
int main(void) {
a();
b();
}
==> Makefile <==
.SUFFIXES:
all: main.o a.o b.o
g++ $^ -o main # all
%.o: %.S
gcc -c -o $@ $< #o
%.S: %.c
gcc -S -o $@ $< #Sc
%.S: %.cc
g++ -S -o $@ $< #Scc
clean:
rm -rf *.o main
rm -rf *.o main
g++ -S -o main.S main.cc #Scc
gcc -c -o main.o main.S #o
gcc -S -o a.S a.c #Sc
gcc -c -o a.o a.S #o
g++ -S -o b.S b.cc #Scc
gcc -c -o b.o b.S #o
g++ main.o a.o b.o -o main # all
rm b.S main.S a.S
a
b