2017-08-03 117 views
0

我正在嘗試創建一個Makefile來編譯我的C程序。我想產生一個調試和發佈版本具有以下目錄結構:Makefile包含基於調試/發佈目標的依賴關係

helloworld/ 
├── Debug/ 
│ ├── bin/ 
│ ├── depends/ 
│ └── obj/ 
├── Release/ 
│ ├── bin/ 
│ ├── depends/ 
│ └── obj/ 
├── mylib/ 
│ ├── bar.c 
│ ├── bar.h 
│ ├── foo.c 
│ └── foo.h 
└── main.c 

我想要做的是有Makefile文件包括基於目標(調試VS版本)不同的依賴文件。我現在使用的makefile文件是這樣的:

CC = clang 

CFLAGS = -c -g -Wall -Wextra -pedantic 

SOURCES = main.c foo.c bar.c 

OBJECTS = $(SOURCES:%.c=Debug/obj/%.o) 
INCLUDE = -Imylib/ 
VPATH = mylib 

.PHONY: debug 

debug: Debug/bin/main 

Debug/bin/main: $(OBJECTS) 
    $(CC) $^ -o -g [email protected] 

Debug/obj/%.o: %.c | Debug 
    $(CC) $(CFLAGS) $< -o [email protected] -MMD -MP -MF Debug/depends/$(@F:.o=.d) $(INCLUDE) 

-include $(SOURCES:%.c=Debug/depends/%.d) 

Debug: 
    -mkdir Debug 
    -mkdir Debug/bin 
    -mkdir Debug/depends 
    -mkdir Debug/obj 

clean: 
    rm -rf Debug 
    rm -rf Release 

這對於調試很有用。但是,當我試圖爲調試和發佈創建單獨的目標,我要和如何修改-include $(SOURCES:%.c=Debug/depends/%.d)

CC = clang 

CFLAGS = -c -g -Wall -Wextra -pedantic 

SOURCES = main.c foo.c bar.c 
DEBUG_OBJECTS = $(SOURCES:%.c=Release/obj/%.o) 
RELEASE_OBJECTS = $(SOURCES:%.c=Debug/obj/%.o) 
INCLUDE = -Imylib/ 
VPATH = mylib 

.PHONY: all debug release 

all: release debug 
release: Release/bin/main 
debug: Debug/bin/main 

Release/bin/main: $(RELEASE_OBJECTS) 
    $(CC) $^ -o [email protected] 

Release/obj/%.o: %.c | Release 
    $(CC) $(CFLAGS) $< -o [email protected] -MMD -MP -MF Release/depends/$(@F:.o=.d) $(INCLUDE) 

Debug/bin/main: $(DEBUG_OBJECTS) 
    $(CC) $^ -o -g [email protected] 

Debug/obj/%.o: %.c | Debug 
    $(CC) $(CFLAGS) $< -o [email protected] -MMD -MP -MF Debug/depends/$(@F:.o=.d) $(INCLUDE) 

# ------------------------------------------------------- 
# -include $(SOURCES:%.c=Debug/depends/%.d) What do I do? 
# ------------------------------------------------------- 

Release: 
    -mkdir Release 
    -mkdir Release/bin 
    -mkdir Release/depends 
    -mkdir Release/obj 

Debug: 
    -mkdir Debug 
    -mkdir Debug/bin 
    -mkdir Debug/depends 
    -mkdir Debug/obj 

clean: 
    rm -rf Debug 
    rm -rf Release 

問題

  1. 我如何可以有條件地包括基於目標的依賴文件難倒?

  2. 有沒有更好的項目組織結構?

  3. 我非常新的makefile。以前,我只是依靠我的IDE來管理構建和配置。有沒有其他提示可以幫助改進這個makefile?

+1

那你已經知道你想要做什麼做的,當你用'讓調試release'(或'讓all')調用它?應該包含哪些依賴文件? –

+0

我的意圖是,無論何時構建調試可執行文件,都會包含Debug/depends,而只要構建發行版可執行文件就會包含Release/depends。通過創建配方,甚至可以在中途切換?如果沒有,我會很高興放棄'make all'並只使用'make debug'和'make release'。 – thndrwrks

+0

包含或不包含文件,這不能依賴於當前構建的目標。否則,每次調用只能創建一個目標,這真的很可惜。你會接受一個基於遞歸make的解決方案嗎(即make make)?有關於這是好還是壞的爭論(像往常一樣,當它有利時,它會變好,而當事情變得更糟時,它會變壞)。 –

回答

0

好吧我想我已經想出了一個可能的解決方案:使用兩個makefile。第一個makefile創建對象文件並創建最終的可執行文件。第二個makefile使用不同的變量調用第一個makefile。

的makefile

export CC := gcc 
export SOURCES := main.c bar.c foo.c 
export VPATH := mylib/ 
export INCLUDES := $(VPATH:%=-I%) 
export DBGFLAGS := -g -c -Wall -Wextra -pedantic 
export RELFLAGS := -c -Wall -Wextra -pedantic -Os 

.PHONY: all debug release 

all: debug release 

release: 
    make -f target.mk TARGET=Release CFLAGS='$(RELFLAGS)' 

debug: 
    make -f target.mk TARGET=Debug CFLAGS='$(DBGFLAGS)' 

clean: 
    make -f target.mk clean TARGET=Debug 
    make -f target.mk clean TARGET=Release 

target.mk

$(TARGET)/bin/main.out: $(SOURCES:%.c=$(TARGET)/obj/%.o) 
    $(CC) $^ -o [email protected] 

$(TARGET)/obj/%.o: %.c | $(TARGET) 
    $(CC) $(CFLAGS) $< -o [email protected] -MMD -MP -MF $(TARGET)/depends/$(@F:.o=.d) $(INCLUDES) 

$(TARGET): 
    -mkdir $(TARGET) 
    -mkdir $(TARGET)/bin 
    -mkdir $(TARGET)/depends 
    -mkdir $(TARGET)/obj 

clean: 
    rm -rf $(TARGET) 

-include $(SOURCES:%.c=$(TARGET)/depends/%.d)