2013-09-26 49 views
0

我正在創建一個項目,在其中創建.so對象作爲我的輸出,其中包含多個運算符以供其他程序使用。我得到了一個Makefile,它運行得很好,除非它每次運行make時都會重新編譯每個文件。本來這不是問題,但現在圖書館裏有五個或五個以上的操作員,運行make非常慢。麻煩的是,我用我的生命,我無法弄清楚如何改變這個Makefile成一個行爲我想,因爲我從來沒有以這種格式處理的Makefile前的樣子:Makefile for共享庫,只編譯更改的文件?

BOOST_LOCATION=/usr/local/boost_1_54_0 

CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS 
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)" 
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm 

all: 
    @if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi 
    $(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp 

    $(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp 
    $(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp 

    $(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp 
    $(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp 

    ### etc. 

    $(CXX) $(CFLAGS) $(INC) -o libname.so \ 
           plugin.cpp.o \ 
           LogicalFile1.cpp.o \ 
           PhysicalFile1.cpp.o \ 
           LogicalFile2.cpp.o \ 
           PhysicalFile2.cpp.o \ 
           ### etc \ 
           $(LIBS) 

clean: 
    rm -f *.o *.so 

的我遇到的最大問題是隻有一個規則(全部),而且我找不到一個Makefile的例子來實現這個功能,或者如何將它分成多個規則。

+4

這是不是一個真正的makefile文件。它只是一個用makefile格式編寫的shell腳本。你的整個「makefile」是一個調用編譯所有內容的shell命令的規則。你也可以把它寫成一個實際的shell腳本。我發現很難相信你找不到一個一次構建對象的makefile的例子,因爲你找到的每一個單例makefile都會這樣做。這是使用make的*整個*點,而不是shell腳本。 – MadScientist

+0

使用autoconf/automake/libtool生成你的makefile。最初的學習曲線有點痛苦(沒有那麼多,但真的),但獎勵是值得的。請參閱以下教程:[使用自動工具構建庫](http://www.openismus.com/documents/linux/building_libraries/building_libraries) - [使用自動工具構建](http://www.openismus.com/documents/) linux/automake/automake.shtml) - [使用libs與autotools](http://www.openismus.com/documents/linux/using_libraries/using_libraries.shtml) – syam

回答

1

在這種情況下,它實際上非常簡單。現在,你只需要一個all目標即可完成所有建築。你需要打出來的編譯器調用和鏈接步驟到他們自己的規則,你應該去比賽:

BOOST_LOCATION=/usr/local/boost_1_54_0 

CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS 
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)" 
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm 

all: plugin.cpp.o LogicalFile1.cpp.o PhysicalFile1.cpp.o LogicalFile2.cpp.o PhysicalFile2.cpp.o 
    $(CXX) $(CFLAGS) $(INC) -o libname.so \ 
           plugin.cpp.o \ 
           LogicalFile1.cpp.o \ 
           PhysicalFile1.cpp.o \ 
           LogicalFile2.cpp.o \ 
           PhysicalFile2.cpp.o \ 
           ### etc \ 
           $(LIBS) 

plugin.cpp.o: plugin.cpp | test 
    $(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp 

LogicalFile1.cpp.o: File1/LogicalFile1.cpp | test 
    $(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp 

PhysicalFile1.cpp.o: File1/PhysicalFile1.cpp | test 
    $(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp 

LogicalFile2.cpp.o: File2/LogicalFile2.cpp | test 
    $(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp 

PhysicalFile2.cpp.o: File2/PhysicalFile2.cpp | test 
    $(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp 

test: 
    @if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi 

clean: 
    rm -f *.o *.so 

.PHONY:所有乾淨的測試

從這一點,你可以進一步簡化也是。例如,您可以將所有編譯行整合到單個模式規則中。

+0

我不會在這裏使用像'test'這樣的通用名稱,或者至少將其標記爲'.PHONY'。 – MadScientist

+0

它像一個魅力工作!謝謝!! – Ingulit

+0

@ user2820044嘗試更改標題並再次調用make。它可能不會重新編譯,因爲這個makefile會忽略頭文件的依賴關係。 –

1

如果你願意使用標準格式和化妝內置規則,您可以輕鬆地寫出你的整個生成文件爲這樣:

ifeq (,$(wildcard $(IN_SOURCE_DIR)/.)) 
    $(error Try: make IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>) 
endif 

OBJECTS = plugin.o LogicalFile1.o PhysicalFile1.o LogicalFile2.o PhysicalFile2.o ### etc 
BOOST_LOCATION = /usr/local/boost_1_54_0 

CPPFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)" 
CXXFLAGS = -pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -Wno-system-headers -isystem -O2 -g -ggdb3 
LDFLAGS = -L"$(IN_SOURCE_DIR)/lib" -L. 
LDLIBS = -shared -Wl,-soname,libname.so -lm 

all: libname.so 

libname.so: $(OBJECTS) 
     $(LINK.cc) $^ $(LDLIBS) -o [email protected] 

clean: 
     rm -f *.o *.so 

.PHONY: all clean 
+0

這將是很好,如果它也自動構建幷包含依賴關係。 –

+0

包含頭依賴關係將會很好。我想你只需要在標誌中使用'-MMD'來生成依賴文件,並且需要包含$(OBJECTS:.o = .d)'來包含它們。對於獎勵積分,空頭規則'%.h:;'會在刪除標題時強制重新編譯。 (其中一些可能特定於gcc/gnumake。) –

+1

@MikeSeymour「-MP」也是有用的。 –