簡體   English   中英

Makefile 沒有給出預期的編譯結果

[英]Makefile not giving the expected compilation results

我對 Make 很陌生。 我正在嘗試編寫一個 Makefile 來構建一個中型 Linux C/C++ 應用程序,如下所示。

通過將所有源文件放在一個位置並明確列出源文件來制作一個簡單的 Makefile 對我來說沒問題,但我希望它更通用。

我的所有源文件(C 和 C++)都位於不同子目錄的src文件夾中。 我在incinc/common文件夾中有頭文件,然后在lib文件夾中有 libs。

Makefile 在同一級別上運行:

SRC_DIR := src
OBJ_DIR := obj
BIN_DIR := bin

CXX := /bin/arm-linux-gnueabi-g++

EXE := $(BIN_DIR)/runfile
SRC := $(shell find $(SRC_DIR) -name *.cpp -or -name *.c)   
OBJ := $(patsubst $(SRC_DIR)/%,$(OBJ_DIR)/%,$(addsuffix .o,$(basename $(SRC))))

CPPFLAGS := -Iinc -Iinc/common -MMD -MP
CXXFLAGS := -std=c++11 -Wall
LDFLAGS  := -Llib
LDLIBS   := 

.PHONY: all clean

all: $(EXE)

$(EXE): $(OBJ) | $(BIN_DIR)
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJ_DIR)/%.o: $(SRC) | $(OBJ_DIR)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
    
$(BIN_DIR) $(OBJ_DIR):
    mkdir -p $@

clean:
    @$(RM) -rv $(BIN_DIR) $(OBJ_DIR)

-include $(OBJ:.o=.d)

當我運行它時,我遇到了很多錯誤,如下所示,包括打開依賴文件的問題。 我想我快到了,但看不到我的錯誤:

compilation terminated.
/bin/arm-linux-gnueabi-g++ -Iinc -Iinc/common -MMD -MP -std=c++11 -Wall -c -o obj/main.d.o
cc -Llib  obj/main.d.o   -o obj/main.d
/usr/bin/ld: obj/main.d.o: relocations in generic ELF (EM: 40)
/usr/bin/ld: obj/main.d.o: relocations in generic ELF (EM: 40)
/usr/bin/ld: obj/main.d.o: error adding symbols: file in wrong format

我不知道如何從您在此處顯示的 makefile 生成您顯示的輸出,但無論如何。

這個不對:

$(OBJ_DIR)/%.o: $(SRC) | $(OBJ_DIR)

模式規則是一個模板,它告訴 make “如果你想構建一個匹配這個模式的目標,那么你可以從匹配這個模式的先決條件中構建它”。

在這里,您將所有源文件列為每個目標文件的先決條件。 假設SRC設置為foo.c bar.c biz.c baz.c ,那么這將擴展為:

obj/%.o : foo.c bar.c biz.c baz.c | obj
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

你告訴 make 每一個.o目標都依賴於所有的源文件,而不僅僅是那個目標文件的源文件。 此外,自動變量$<總是擴展到第一個先決條件,這里總是foo.c 因此,您將foo.c編譯四次,創建每個目標文件。

調試 makefile 時的第一個重要規則是仔細查看 make 打印的輸出(命令行)。 如果它們不正確,那么您的 makefile 就不正確。 如果你這樣做,你會看到所有的編譯行都在編譯相同的源代碼,比如:

g++ -c foo.c -o obj/foo.o
g++ -c foo.c -o obj/bar.o
g++ -c foo.c -o obj/biz.o
g++ -c foo.c -o obj/baz.o

這顯然行不通,這就是嘗試將所有這些對象文件鏈接在一起時出現鏈接錯誤的原因:它們都具有相同的內容。

你需要這個:

$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
        @mkdir -p $(@D)
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

它告訴 make 如何從單個源文件構建目標文件。

您還需要創建目標文件將進入的實際輸出目錄。 如果目標文件出現在子目錄中,僅創建$(OBJ_DIR)是不夠的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM