2013-02-01 65 views
14
GNU Make 3.82 
gcc 4.7.2 
c89 

創建目標文件我有以下讓文件:入門使特定目錄

INC_PATH=-I/home/dev_tools/apr/include/apr-1 
LIB_PATH=-L/home/dev_tools/apr/lib 
LIBS=-lapr-1 -laprutil-1 
RUNTIME_PATH=-Wl,-rpath,/home/dev_tools/apr/lib 
CC=gcc 
CFLAGS=-Wall -Wextra -g -m32 -O2 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE $(INC_PATH) 
SOURCES=$(wildcard src/*.c) 
OBJECTS=$(patsubst %.c, %.o, $(SOURCES)) 

EXECUTABLE=bin/to 

all: build $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(CFLAGS) -o [email protected] $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS) 

$(OBJECTS): $(SOURCES) 
    $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) 

build: 
    @mkdir -p bin 

clean: 
    rm -rf $(EXECUTABLE) $(OBJECTS) bin 
    find . -name "*~" -exec rm {} \; 
    find . -name "*.o" -exec rm {} \; 

我的目錄結構是這樣的project/src project/bin。我的Makefile位於project (root)文件夾中,所有我的* .h和* .c都位於src目錄中。目前,我只有叫一個源文件timeout.c

我得到這個錯誤:

gcc: error: src/timeout.o: No such file or directory 

我已經使用這個讓所有的源文件:

SOURCES=$(wildcard src/*.c) 

和對象文件:

OBJECTS=$(patsubst %.c, %.o, $(SOURCES)) 

但是,make似乎在項目根文件夾中創建了對象文件,其中麥efile是。它不應該把它放在src目錄中嗎?

回答

12

你有兩個問題在本規則(以及三):

$(OBJECTS): $(SOURCES) 
    $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) 

你還沒有注意到,但規則進行每個對象依賴所有來源,並嘗試構建那樣。只要您只有一個來源,就不是問題。易與static pattern rulean automatic variable修復:

$(OBJECTS): src/%.o : src/%.c 
    $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) 

此外,命令(「$(CC)...」)不指定輸出文件名,所以GCC將源文件名來推斷;如果你給它src/timeout.c,它將產生timeout.o(在工作目錄中,project/)。所以你應該指定輸出文件的所需路徑。容易與另一個自動變量:

$(OBJECTS): src/%.o : src/%.c 
    $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) -o [email protected] 
+0

如何創建共享庫?我跑過了一個網站,聲稱我需要'-c'開關來創建一個共享庫,但是使用它可以防止我使用'-o'。目前,make只是在根項目目錄中創建目標文件。我的文件夾結構是:'src/lib/*',我希望在'obj/lib/*'中生成obj文件。gcc命令是:'g ++ -std = C++ 11 -g -I./include -fPIC -Wall -c ./src/lib/Source1.cpp。/ src/lib/Source2.cpp' – krb686

+0

好吧,我明白了。試圖編譯多個依賴於多個源的對象。我用你的靜態模式規則和自動變量'$ <'和'$ @'替換它,它就像一個魅力。也不知道爲什麼海灣合作委員會抱怨,並說你不能使用'-c'與'-o',但你當然可以。 – krb686

4

使用gcc-o選項將輸出文件寫入特定位置。例如,你可以說:

$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) -o $(OBJECTS) 

遺憾的是,這條線的一個問題:如果有一個以上的源文件中$(SOURCES),它不會工作,因爲$(OBJECTS)也將包含多個文件名, -o選項僅綁定到第一個參數。

一種在源代碼文件列表中編譯每個文件的方法是使用隱式規則。在gmake,你可以這樣寫:

$(EXECUTABLE): $(OBJECTS) 
     $(CC) $(CFLAGS) -o [email protected] $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS) 

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

其中$ <替換爲輸入文件的名稱和$ @被替換出了名的輸出文件。

+2

只要只有一個來源,這工作。 – Beta

+0

@貝塔對不起,你指的是什麼「這個」? – radical7

+0

您的解決方案,「正確的方式」。嘗試使用多個源文件,你會明白我的意思。 – Beta