2016-09-25 29 views
2

我有一個C/C++混合項目,對於每個源代碼,我想從程序集生成一個程序集文件(.S),然後生成一個目標文件(.o)。我想下面的Makefile應該工作:Makefile中的多次跳轉

all: a.o b.o main.o 
    g++ $^ -o main 

%.o: %.S 
    gcc -o [email protected] $< 

%.S: %.c 
    gcc -S -o [email protected] $< 

%.S: %.cc 
    g++ -S -o [email protected] $< 

clean: 
    rm -rf *.o main 

理想的情況下,爲了產生X.oX.S需要通過使用視X.cX.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

有趣:HTTP://stackoverflow.com/questions/39572468/how-can-i-automatically-add-s-to-a-target-in-my-makefile –

+0

@LogicStuff:沒有我的道歉。這確實是一個錯字。但問題依然存在。 – qweruiop

+0

這已被多次詢問。看到我的答案[這裏](http://stackoverflow.com/a/39625452/6644919)(用'.c'和'.cc'代替'.h')。 –

回答

0

您需要取消隱含的規則,因爲他們是更好的匹配,加上下面幾行

%.o: %.cc 
%.o: %.c 

注意,因爲它不創建一個名爲all文件您的all規則被打破,使已知道如何從裝配裝配對象文件,並且它也已經知道如何目標文件鏈接到一個程序,如果目標文件的一個相匹配的目標

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 [email protected] $< 

%.s: %.cc 
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -S -o [email protected] $< 

%.o: %.cc 
%.o: %.c 

clean: ; $(RM) $(objects) $(assembly) main 
+0

你能說說更好的搭配嗎?這肯定會起作用,並且是我想要裝配輸出之前所擁有的。 – qweruiop

+0

我看到你在說什麼通過閱讀https://stackoverflow.com/questions/39619678/pattern-rule-in-makefile/39625452 – qweruiop

+0

當考慮隱式規則時,make將使用最短的鏈,'%.cc' - > '%.o'比'%.cc' - >'%.S' - >'%.o'短一步。 – user657267

0

使用.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 [email protected] $< #o 

%.S: %.c 
    gcc -S -o [email protected] $< #Sc 

%.S: %.cc 
    g++ -S -o [email protected] $< #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 
+0

'.SUFFIXES:'的一個很好的補充是'MAKEFLAGS + = --no-builtin-rules'。 –