2014-09-25 189 views
2

有點搜索後,我已經成功地拼湊下面的Makefile:Makefile文件 - 移動目標文件

CC = gcc 
CFLAGS = -c -Wall 
LDFLAGS = 
SOURCEFILES = main.c 
SOURCES = src/$(SOURCEFILES) 
OBJECTS = $(SOURCES:.c=.o) 
EXECUTABLE = netsim 

all: $(SOURCES) $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected] 

.c.o: 
    $(CC) $(CFLAGS) $< -o [email protected] 

clean: 
    rm -rf netsim $(OBJECTS) 

我希望能夠到我的對象文件移動到另一個目錄,但一直努力工作。我錯過了什麼?

+0

您的意思是在別處構建它們,還是在它們構建之後將它們移動,作爲'.c.o'規則的一部分,或者是什麼? – Beta 2014-09-25 01:14:56

+0

在別處建造它們。 – kubiej21 2014-09-25 01:29:25

回答

0

這樣的事情?

SOURCES = src/main.c 
OBJECTS = obj/main.o 

... 

obj/%.o: src/%.c 
    $(CC) $(CFLAGS) $< -o [email protected] 

一旦這樣的工作,你可以添加更多的招數,就像這樣:

OBJECTS = $(patsubst src/%.c, obj/%.o, $(SOURCES) 
+0

其實配方部分可能是不必要的 - GNU Make已經知道如何將'.c'編譯成'.o' - 但是依賴關係顯然需要聲明。 – tripleee 2014-09-25 03:32:05

+1

@tripleee雖然確實知道如何將'.c'編譯爲'.o',但它並不知道如何將'src/... c'編譯成'obj/... o' 。所以,需要一個模式規則。 – MadScientist 2014-09-25 11:54:15

+0

我的不好;你是對的。 – tripleee 2014-09-26 07:55:41

6

訣竅是不動的物體。
你應該建立它使用它從他們建造的地方

例如,你有以下目錄結構:

$ tree . 
├── Makefile 
├── include 
│   └── common_head.h 
├── obj 
└── src 
    ├── foo.c 
    └── main.c 

手冊執行:

$ gcc -o ./obj/foo.o -c ./src/foo.c -I ./include # Build Object # 
$ gcc -o ./obj/main.o -c ./src/main.c -I ./include 
$ gcc -o exe ./obj/foo.o ./obj/main.o    # Build Executable # 

Makefile來模擬上述

C_FLAGS := -g -Wall -Wextra 
CC := gcc 
RM := rm 
LINKFLAGS := -lanylibrary 

.PHONY: $(TARGET) 
.PHONY: clean 

VPATH:= ./src/ ./obj/ ./include/ 

# Path for .c , .h and .o Files 
SRC_PATH := ./src/ 
OBJ_PATH := ./obj/ 
INC_PATH := -I ./include 

# Executable Name 
TARGET := exe 

# Files to compile 
OBJ1 := foo.o \ 
     main.o 

OBJ := $(patsubst %,$(OBJ_PATH)%,$(OBJ1)) 

# Build .o first 
$(OBJ_PATH)%.o: $(SRC_PATH)%.c 
       @echo [CC] $< 
       @$(CC) $(C_FLAGS) -o [email protected] -c $< $(INC_PATH)     

# Build final Binary 
$(TARGET):  $(OBJ) 
       @echo [INFO] Creating Binary Executable [$(TARGET)] 
       @$(CC) -o [email protected] $^ $(LINKFLAGS) 

# Clean all the object files and the binary 
clean: 
       @echo "[Cleaning]" 
       @$(RM) -rfv $(OBJ_PATH)* 
       @$(RM) -rfv $(TARGET) 

所以,當你做一個製作

$ make -B 
[CC] src/foo.c 
[CC] src/main.c 
[INFO] Creating Binary Executable [exe] 

要見幹運行使用make -n

$ make clean ; make -n 
g++ -g -Wall -Wextra -o obj/foo.o -c src/foo.c -I ./include 
g++ -g -Wall -Wextra -o obj/main.o -c src/main.c -I ./include 
g++ -o exe obj/foo.o obj/main.o -lanylibrary 

所以建立你的目錄結構之後應該是這樣的。

$ tree . 
├── Makefile 
├── exe 
├── include 
│   └── common_head.h 
├── obj 
│   ├── foo.o 
│   └── main.o 
└── src 
    ├── foo.c 
    └── main.c 

所以從我以前的答案。
您不必使用任何PHONY move,也不會不必要地重新創建對象。

+1

之後不移動目標文件是否會失去將它們放在第一位的目的?如果可執行文件是在移動它們之前構建的,那麼我會認爲每次運行make時,都必須重新創建所有的目標文件才能生成新的可執行文件。我希望在生成可執行文件之前將目標文件放在單獨的目錄中,以便可以重新使用未更改的文件。 – kubiej21 2014-09-25 11:52:06

+0

這不是一個好的makefile。聲明所有對象依賴於所有的源代碼意味着每當你改變任何源文件時,所有的對象文件都會重建。在你的例子中,你只有一個源文件,所以它沒有什麼區別,但大概一個真正的makefile將有更多的源代碼。 – MadScientist 2014-09-25 11:55:45

+0

@MadScientist&kubiej21回答更新。 Makefile重寫。上面的Makefile應該解決問題。差不多一年後我會回到這個問題! – 2015-06-01 14:19:13