簡單加深對編譯和鏈接的理解
1、想要編譯生成一個可執行程序,寫成一行,makefile如下:
test:test.cpp cmqtt.cpp cmqtt.h
g++ -o test test.cpp cmqtt.cpp -lpaho-mqtt3cs \
-L ../../paho.mqtt.c/build \
-I ../../paho.mqtt.c/src \
-pthread -Imqtt \
-std=c++11
其實就是寫了一個test
程序,測試cmqtt
模塊,其中加載了兩個頭文件路徑,鏈接三個庫。
當然這樣寫有點low,想改一下不用每次都全部編譯。
如下:
CC = g++
test:test.o cmqtt.o
$(CC) -o test test.o cmqtt.o -lpaho-mqtt3cs \
-L ../../paho.mqtt.c/build \
-pthread
test.o: test.cpp cmqtt.h
$(CC) -c test.cpp -I ../../paho.mqtt.c/src -Imqtt
cmqtt.o: cmqtt.cpp cmqtt.h
$(CC) -c cmqtt.cpp -I ../../paho.mqtt.c/src -Imqtt -std=c++11
.PHONY:clean
clean:
-rm test *.o
2、主要過程分成兩部分:
編譯
test.o: test.cpp cmqtt.h $(CC) -c test.cpp -I ../../paho.mqtt.c/src -Imqtt cmqtt.o: cmqtt.cpp cmqtt.h $(CC) -c cmqtt.cpp -I ../../paho.mqtt.c/src -Imqtt -std=c++11
這裏我們編譯生成兩
.o
文件供鏈接使用編譯時,編譯器需要的是語法的正確,函數與變量的聲明的正確。對於後者,通常是你需要告訴編譯器頭文件的所在位置,只要所有的語法正確,編譯器就可以編譯出中間目標文件。
編譯階段只是做外觀的檢查,語法是否正確,函數、變量是否能找到聲明,所以只需要考慮頭文件路徑是否完善
-I
,而不用寫-L鏈接庫。
例如,在頭文件聲明瞭一個函數,但是沒有定義,在編譯階段是不會報錯的。錯誤發現在鏈接。鏈接
鏈接時,主要是鏈接函數和全局變量,所以,使用中間目標文件(O文件或是OBJ文件)來鏈接應用程序。鏈接器並不管函數所在的源文件,只管函數的中間目標文件(Object File)
在這裏需要把我們程序中用到的如
thread
等庫補充上,所以加上-l
,-L