入門介紹
起因是我在工作中,遇到了一個多個執行文件打包成的組件,而每個執行文件都需要將pb編進二進制中,導致release包非常大。所以想到,是否應該將pb編程動態鏈接庫,再供可執行文件使用呢?達成這個目的需要做兩件事。1、將pb編成.so文件。2、將原本的鏈接方式改為動態鏈接。
makefile是make構建項目所需要的規則文件。通產在其中指定了編譯目標、編譯指令、編譯依賴。通常的makefile被命名為“Makefile”“makefile”,但也可以通過make -f filename去指定非標准命名的makefile,以適應不同的項目需求。
生成目標文件
通常我們想要的目標文件分為三種,可執行文件(a.out),.a文件(靜態鏈接庫),.so(動態鏈接庫)。
許多人都清楚怎樣處理一個單純的main.cpp,g++ main.cpp即可。執行完畢后同級目錄下會出現a.out。a.out代表着g++編譯並鏈接得到的可執行文件。如果不喜歡a.out這個默認名稱,通常使用g++ -o hello hello.cpp這樣的命令。可能有人會不清楚,g++ -o hello hello.cpp 和 g++ hello.cpp -o hello有什么區別呢?畢竟很多人百度g++,無非也只是想得到一個確切能用的命令而已,不了解也不奇怪。-o的意思是 指定了了g++的輸出目標,所以寫在哪里都可以。
g++的常用選項:https://www.cnblogs.com/lidan/archive/2011/05/25/2239517.html
初學者需了解-o -g -static -fPIC -D等常用參數。
makefile說到底還是像腳本一樣執行了g++命令,想要利用makefile構建c++項目,會使用g++命令就是第一步。
makefile基礎語法:https://www.cnblogs.com/wang_yb/p/3990952.html
一個常見簡單的makefile文件通常長這樣:
$(target):*.o
$(CXX) $(CXXFLAGS) -o $@ $^
%.o:%.cpp
$(CXX) $(CXXFLAGS) -o $@ $<
make會從上至下尋找第一個編譯目標。如果將target:*.o挪到文件的最下方,那執行make后,也只能得到一堆.o文件,而無法得到target。
有時候目標文件不止一個,這個時候就要使用all來指定多個target。
在文件上方添加: all:$(target) $(target2)
all:$(target) $(target2)
$(target):*.o
$(CXX) $(CXXFLAGS) -o $@ $^
$(target2):*.o
$(CXX) $(CXXFLAGS) -o $@ $^
%.o:%.cpp
$(CXX) $(CXXFLAGS) -o $@ $<
target和target2是最終的目標文件,但我們為make指定的目的文件是"all",target和target2其實是"all"的依賴。
如果目標是一個/多個普通的可執行文件,CXXFLAGS="-g",如果目標需要鏈接動態鏈接庫,CXXFLAGS="-g -fPIC"
如果目標是一個動態鏈接庫,CXXFLAGS="-g -shared"
如果目標是一個靜態鏈接庫,生成target的指令就不是cxx而是ar
all:$(target) $(target2)
$(target):*.o
ar -cvr $@ $^
$(target2):*.o
$(CXX) $(CXXFLAGS) -o $@ $^
%.o:%.cpp
$(CXX) $(CXXFLAGS) -o $@ $<
鏈接動態鏈接庫
如果目標僅僅是生成可執行文件,那么上一步已經完成了。但是我的目標是生成動態鏈接庫並用可執行文件去鏈接它,已達到節省空間的目的。
g++的-l與-L分別指定了動態鏈接庫和鏈接庫所在的地址。如 g++ -o hello hello.cpp -luuid -L/usr/lib
除此之外,也可以在代碼中指定要使用的動態鏈接庫。dlopen了解一下。
編譯成功后,接下來就是運行的問題了。ldconfig命令可以幫助我們知道,這台機器上動態鏈接庫的地址有哪些。想要成功運行連接了動態鏈接庫的可執行文件,方法有四種。
1、將動態鏈接庫直接丟進ldconfig包含的路徑中。
2、將動態鏈接庫丟到自定義的目錄中,與系統自帶的庫分開,並將自定義目錄加入到/etc/ld.so.conf
文件中
3、如果是daemon進程,在start腳本中export LD_LIBARY_PATH也是個辦法
4、使用g++的rpath指令指定庫的路徑。
3、4是簡單易用的辦法,推薦新手使用。
結語
本文只介紹了構建項目的大體思路,並未給出具體的命令與說明。如果需要更詳細的說明,不妨百度/google我給出的關鍵詞or看看我貼出的兩篇文章。