2013-10-21 150 views
0

我被要求做一個makefile,我已經做到了這一點:這個Makefile是否正確?

# La siguiente no es necesariamente requerida, se agrega para 
# mostrar como funciona. 

.SUFFIXES: .o .c 
.c.o: 
    $(CC) -c $(CFLAGS) $< 


# Macros 

CC = g++ 
CFLAGS = -Wall -Wextra -Werror -pedantic 
SRC = main.c metbasicos.c metbasicos.h metintermedios.c metintermedios.h metavanzados.c metavanzados.h 
OBJ = main.c metbasicos.c metintermedios.c metavanzados.c 


# Reglas explicitas 

all: $(OBJ) 
    $(CC) $(CFLAGS) -o p1 $(OBJ) 

clean: 
    $(RM) $(OBJ) main 

# Reglas implicitas 

metbasicos.o: metbasicos.c metbasicos.h 
metintermedios.o: metintermedios.c metintermedios.h 
metavanzados.o: metavanzados.c metavanzados.h 
main.o: main.c metbasicos.h metintermedios.h metavanzados.h 

它是正確的嗎?

編譯我通常使用下面的命令:

g++ -Wall -Wextra -Werror -pedantic main.c metbasicos.c metintermedios.c metavanzados.c -o p1.exe 

,如果我做了一些測試,與:

make ./p1 < input.txt

工作正常,但我不知道這是否是一個正確的實施。

有人可以告訴我,如果我犯了一些嚴重的錯誤?

非常感謝。

+0

你爲什麼試圖重新定義規則將.C成的.o? –

+0

@ IgnacioVazquez-Abrams因爲我使用makefile作爲模板,來自另一個人,我對它們的工作原理有一點點想法......你能告訴我哪些行是不必要的嗎? – Gera

回答

3

這裏沒有任何嚴重的錯誤,但有一些奇怪的事情。正如Ignacio指出的那樣,如果你不想要,你並不需要重新定義編譯規則。但是你可能做的原因是你正在混合C和C++。

您正在編譯.c文件,這是C代碼慣例,與g++,這是一個C++編譯器,這是奇怪的。如果你真的構建C代碼,你應該用gcc進行編譯。如果你真的在構建C++代碼,你應該重命名你的文件,以.cpp.cc或類似的名稱結束。此外,C++編譯器的GNU make變量爲CXX,而不是CC,標誌的變量爲CXXFLAGS而不是CFLAGS

此外,您all目標應取決於p1p1目標應包含的鏈接:

.PHONY: all 
all: p1 
p1: $(OBJ) 
     $(CC) $(CFLAGS) -o p1 $(OBJ) 

否則p1將被重新連接在每次運行即使沒有作出任何改變make時間。

還有其他更先進的東西,你可以添加,像頭文件的先決條件自動構建等

+0

不好意思,程序必須用'C'編寫,並用'g ++'編譯。 這是我的老師希望我們工作的方式。 – Gera

+1

這很奇怪。自從C!= C++以後,我會對此持懷疑態度。換句話說,並非所有的合法C程序都是合法的C++程序(反之亦然)。使用錯誤的編譯器會導致對語言(IMO)的錯誤理解。當然,我不是給你一個分數的人:-p – MadScientist

+0

有些老師不知道他們在做什麼^^「 – Eregrith

1

$(CFLAGS)編譯標誌:他們正在編譯您.c源文件到.o目標文件時使用。

使用$(CFLAGS)時做$(CC) -o $(OBJ)是不常見的做法,雖然它工作正常。正確的方法是使用$(LDFLAGS)鏈接進程的標誌,將所有.o與您正在使用的可能庫一起放入二進制可執行文件中。

通常$(CFLAGS)包含編譯選項,例如您使用的編譯選項,$(LDFLAGS)包含鏈接選項,例如-L. -lpersonal用於在與makefile相同的目錄中加載名爲libpersonal.a的文件。

此外,我建議您使用+=您的CFLAGS聲明保留現有的CFLAGS,如果已經有一些。

.c.o規則是有用的,如果你不想打擾爲每個文件設置規則,你在底部做了什麼。最佳做法是爲每個文件定義自定義規則,添加源文件包含的頭文件作爲該規則的依賴關係。這樣,makefile將管理只重新編譯需要的文件,因爲源中的更改會導致包含的標頭髮生更改。當然,這需要對源文件進行徹底分析,當您更改包含在每個源中的頭文件時,會進行常規修改。

+1

在鏈接中包含'CFLAGS'並不罕見(事實上,這是默認行爲),所以我不會同意它不正確。有時候,鏈接器想知道'CFLAGS',比如'-g','-pthread',代碼覆蓋標誌等等。 – MadScientist

+0

我糾正了我的一句話,謝謝。 – Eregrith