2012-06-30 71 views
0

我試圖創建一個Makefile,其中包括輸出一些library1.a,之後我將重新使用它來創建可執行文件。下面是我的困境:我想讓這個過程變得通用,這樣我就不必每次添加一些文件就編輯Makefile。下面是我的想法:從多個來源創建靜態庫

#Declare phony targets 
.PHONY: all clean build_utils 

#Compiler 
CXX = g++ 

#Flags 
CXXFLAGS = -Wall -Wextra -Wconversion -Werror -pedantic -std=c++0x -O2 

#Directories 
OUTPUT_DIR = _output/linux 
INTERMEDIATE_DIR = _intermediate/linux 
UTILS_DIR = utils 

all: $(OUTPUT_DIR)/libUtils.a 

$(OUTPUT_DIR)/libUtils.a: 
    ar rcs [email protected] $(INTERMEDIATE_DIR)/utils/$(patsubst %.cpp, %.o, $(wildcard $(UTILS_DIR)/ *.cpp)) 

#create .o files in %INTERMEDIATE_DIR/utils 
build_utils: $(UTILS_DIR)/ *.cpp $(UTILS_DIR)/ *.h 
    $(CXX) -c $(CXXFLAGS) $^ -o ## What must be placed here? ## 

所以,基本上,我想在一個臨時目錄中創建所有的目標文件,然後在libUtils.a存檔,但我不能想出如何問編譯器根據輸入文件輸出多個目標文件。基本上,我的標準強加每個.cpp文件,我應該得到一個對象文件,但我不知道如何做到這一點。我不想爲每個.o文件創建一個單獨的目標,因爲它太亂了。

+0

雖然這不是直接回答您的問題,但我建議您查看cmake來爲您生成Makefile文件。它似乎有你想實現內置的自動化類型。 – jpe

+0

@jpe cmake似乎比手動更復雜。我不得不投入幾天的時間,現在我非常着急編譯這個項目。 –

+0

在CMake中,實際上可以從大約三行或四行中匹配特定模式的所有文件創建一個庫,這比Makefile文件要清晰得多。不是說,在Makefile中「手動」這樣做肯定是一個壞主意,只是不要被CMake所看到,也許看起來複雜而複雜 - 它提供了很多很好的功能,但並不是很難習慣。 – sonicwave

回答

0

所以,幾個小時的挖掘後,這裏就是我設法想出:

#Build object files 
$(INTERMEDIATE_DIR)/$(UTILS_DIR)/%.o: $(UTILS_DIR)/%.cpp $(UTILS_DIR)/%.h 
    mkdir -p $(INTERMEDIATE_DIR)/$(UTILS_DIR) 
    $(CXX) $< $(LIBCXXFLAGS) -o [email protected] 

$(INTERMEDIATE_DIR)/$(FUNCTIONS_DIR)/%.o: $(FUNCTIONS_DIR)/%.cpp $(FUNCTIONS_DIR)/%.h 
    mkdir -p $(INTERMEDIATE_DIR)/$(FUNCTIONS_DIR) 
    $(CXX) $< $(LIBCXXFLAGS) -o [email protected] 


#create the library archives 
$(OUTPUT_DIR)/libUtils.a: $(patsubst %.cpp, $(INTERMEDIATE_DIR)/%.o, $(wildcard $(UTILS_DIR)/ *.cpp)) 
    ar rcs [email protected] $^ 
$(OUTPUT_DIR)/libFunctions.a: $(patsubst %.cpp, $(INTERMEDIATE_DIR)/%.o, $(wildcard $(FUNCTIONS_DIR)/ *.cpp)) 
    ar rcs [email protected] $^ 

#Builds the libraries 
libs: $(OUTPUT_DIR)/libUtils.a $(OUTPUT_DIR)/libFunctions.a 

#Main target 
all: libs 

關於它的好處是,我不必每次我加入的時間來編輯它文件。我認爲通過建立目標文件的單個通用目標,可以使其變得更加抽象,但這似乎有點太過分了。

PS:謝謝Martin給我一個好主意,用什麼來使用! :)

LE:似乎很難說服SO不嘗試語法突出顯示。即使<pre></pre>標籤在處理/*時也不會有幫助...

1

您可以使用通配符規則類似下面分別編譯每個C++源文件:

%.o: %.cpp 
    $(CXX) $< $(CXXFLAGS) [email protected] 

CXXFLAGS的末尾添加-c -o後。然後捕捉patsubst表達式的結果地方,例如:

OBJECTS = $(patsubst %.cpp, %.o, $(wildcard $(UTILS_DIR)/*.cpp)) 

...並有$(OUTPUT_DIR)/libUtils.a規則取決於$(OBJECTS)

+0

嗯......這看起來有點混亂,因爲我希望我的.o文件在多個目錄中生成... –

+0

@MihaiTodor,你應該在你的問題中提到你想要多箇中間目錄,而不僅僅是'utils /'。你有多個源目錄,並且每個目錄都需要在INTERMEDIATE_DIR中有相應的目錄? – Beta

+0

是的,那是我的目標。不過,我設法以更「體面的方式」來做到這一點。我今天學到了很多關於Makefiles的知識,並且正在用我的解決方案添加一個答案。 –