編譯、鏈接、Makefile

簡單加深對編譯和鏈接的理解

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章