简单加深对编译和链接的理解
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