2015-10-05 38 views
2

這是在FreeBSD上運行的,它使用PMake而不是GMake。我的Makefile始終構建所有文件

這是我的第一個Makefile文件。我用谷歌很多來幫助創建這個以及諸如'PMake - A Tutorial'等資源。我無法解決的唯一問題是,每次運行Makefile時,即使沒有更改,它也會編譯每個文件。

我有四個目錄。 src用於我的源文件,包括我的頭文件,輸出的obj和可執行文件的bin。

我在做的是掃描源文件夾並創建一個文件列表,用於源和對象以及標題。通常我運行'make debug'進行調試,否則運行'make myservice'。

如果我執行「make乾淨」,「讓調試」和「讓調試」,它會清除我的文件夾,使所有文件,然後進行改造,而不是無所事事的所有文件。

根據我的搜索,我傾向於在$(OBJ)規則是問題,但我不太明白了。爲了構建我的目標和調試規則,他們需要知道如何構建對象。

CC = clang 

BINDIR = $(.CURDIR)/bin 
OBJDIR = $(.CURDIR)/obj 
SRCDIR = $(.CURDIR)/src 
INCDIR = $(.CURDIR)/include 

CFLAGS = -Wall -I/usr/local/include -I$(INCDIR) 
LFLAGS = -lm -lpq -lpthread 
LIBDIR = -L/usr/local/lib 

_SRC != ls $(SRCDIR)/*.c 
SRC = ${_SRC:T} 
INC != ls $(INCDIR)/*.h 
OBJ = ${SRC:S/src/obj/g:.c=.o} 

TARGET = myservice 

$(TARGET): $(OBJ) 
    $(CC) -o $(BINDIR)/[email protected] $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

debug: $(OBJ) 
    $(CC) -g -O0 -o $(BINDIR)/$(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h 
    $(CC) -c $< $(CFLAGS) 

.PHONY: clean 
clean: 
    rm -rf $(OBJDIR)/*.o $(BINDIR)/$(TARGET) 

編輯 - 新的Makefile

新的Makefile。如果沒有更改,不重建。沒有調試,仍然有問題搞清楚調試。

CC  = clang 

BINDIR = $(.CURDIR)/bin 
OBJDIR = $(.CURDIR)/obj 
SRCDIR = $(.CURDIR)/src 
INCDIR = $(.CURDIR)/include 

CFLAGS = -Wall -I/usr/local/include -I$(INCDIR) 
LFLAGS = -lm -lpq -lpthread 
LIBDIR = -L/usr/local/lib 

TARGET = $(BINDIR)/myservice 

_SRC != ls $(SRCDIR)/*.c 
SRC  = ${_SRC:T} 
INC  != ls $(INCDIR)/*.h 
OBJ  = ${SRC:S/src/obj/g:.c=.o} 

$(TARGET): $(OBJ) 
     $(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

$(OBJ) : $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h 
     $(CC) $(CFLAGS) -c $< -o [email protected] 

.PHONY: clean 
clean: 
     rm -rf $(OBJDIR)/*.o $(TARGET) 

編輯 - 工作的Makefile

添加如果有條件進行調試。

CC = clang 

BINDIR = $(.CURDIR)/bin 
OBJDIR = $(.CURDIR)/obj 
SRCDIR = $(.CURDIR)/src 
INCDIR = $(.CURDIR)/include 

CFLAGS = -Wall -I/usr/local/include -I$(INCDIR) 
.if make(debug) 
CFLAGS += -g -O0 
.endif 
LFLAGS = -lm -lpq -lpthread 
LIBDIR = -L/usr/local/lib 

TARGET = $(BINDIR)/myservice 

_SRC != ls $(SRCDIR)/*.c 
SRC = ${_SRC:T} 
INC != ls $(INCDIR)/*.h 
OBJ = ${SRC:S/src/obj/g:.c=.o} 

all: $(TARGET) 

debug: $(TARGET) 

$(TARGET): $(OBJ) 
    $(CC) -o $(TARGET) $(OBJ) $(CFLAGS) $(LIBDIR) $(LFLAGS) 

$(OBJ): $(SRCDIR)/$(.PREFIX).c $(INCDIR)/$(.PREFIX).h 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

.PHONY: clean 
clean: 
    rm -rf $(OBJDIR)/*.o $(TARGET) 
+0

只是一個友好的提示:CMake是一個更高的水平,可能會迴避一些這一點。 –

+0

@JohnZwinck謝謝你的提示。現在,我想繼續使用PMake,這樣我就可以弄清楚我錯在哪裏並從中學習。我簡單看了一下CMake的例子。一旦我瞭解了一點,這絕對是我將進一步研究的內容。 – quickblueblur

回答

1

第二make debug不能什麼都不做,debug是假目標,不是實際的輸出文件,至少在鏈接階段將重新運行。

此外,使用-g -O0重新運行鏈接階段不會使用調試信息重新編譯源文件,也不會進行優化。

順便說一下,$(TARGET)規則也是一個假規則,它產生$(BINDIR)/$(TARGET),而不是$(TARGET)

你應該重寫以不同的規則生成文件,使在調試不同的目錄對象和二進制輸出文件和釋放模式。 gmake模式使得這易於編寫,我不知道pmakecmake爲此目的。

+0

在您的幫助下討論PHONY目標,特別是我的$(TARGET)規則和我的$(BINDIR)/ $(TARGET)規則時,我能夠重新編寫規則並使其工作。我瞭解了一些關於PHONY的目標,但還不夠。根據我的理解,PHONY規則如果被告知將始終運行。因此,通過制定調試規則並調用「make debug」,它將始終構建,因爲調試永遠不會存在。是否有可能創建一條規則來啓用調試,而不需要重建?我使用新的Makefile編輯了我的主帖。 – quickblueblur

+0

您可以制定一個調試規則,該規則取決於調試可執行文件,並制定單獨的規則以從調試對象文件製作調試可執行文件,而製作另一個通用規則以從源文件製作調試對象文件。您還應該將Makefile列爲所有這些規則的依賴項,以便在修改Makefile時強制進行重新編譯,因爲您可能已經更改了命令和/或編譯選項。 – chqrlie

+0

我相信我找到了一種不創建新的重複規則的方式,但條件似乎不起作用。 [條件 - PMake](https://www.freebsd.org/doc/en/books/pmake/book.html#condition)。 '#if defined(DEBUG)|| make(debug)CFLAGS + = -g -O0#endif'使用該代碼,無論我使用make運行什麼,它都會添加-g -O0標誌。我的猜測是DEBUG是以某種方式定義的,所以我刪除了這個「make(debug)」。即使我沒有運行'make debug',運行'make'仍會添加標誌。 – quickblueblur

相關問題