2014-09-25 191 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