<-以下为学习ROS时需要的基础编程知识,记录在案以供翻阅。资料来源于网络,链接附与文末->
1. 编译过程简介
由于ROS编程中需要编写CMakeLists.txt,所以来学习学习编译过程与编译指令。
本文主要记录一下一些必需的编程知识,内容包括:编译过程简介(从源码成为执行文件的过程),Make指令(主要是gcc常用指令)。知道这些基本就可以继续学习CMakeLists.txt的编写了。
2 编译链接过程简介
编译过程就是将源文件代码(.c)转换为机器可以执行的可执行文件(windows下的.exe,linux下无后缀,可用ls -l查看)。具体分为四步:预编译,编译,汇编,链接。
预编译与编译是“读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码”。汇编是“把汇编语言代码翻译成目标机器指令的过程”,最终通过汇编得到目标文件(.o),存放与源程序等效的机器语言代码。
(P.S.一般会有反汇编过程,而没有反编译,因为编译过程已经丢失了编译过程中丢失了高级语言的语法结构信息。汇编则只是将汇编语言映射为机器指令,该映射比较简单。)
链接会将有关的目标文件彼此关联起来。某个源文件可能调用了另外一个源文件定义的某个符号或函数,在编译的过程中,编译器会暂时将这些符号认为是定义好的,在链接过程才会查看符号表在各个目标文件中找到需要的定义。
链接方式分为静态链接与动态链接。1)静态链接下,“函数的代码将从其所在的静态链接库中被拷贝到最终的可执行程序中。”相当于把库函数的代码考入到了最终生成的可执行文件中。2)动态链接下,“函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。”
P.S.具体区别建议看参考网址三《深入浅出静态链接和动态链接》
一般情况下,我们只需要知道分为编译与链接两个过程就可以了:
① 编译过程将.c文件转换为目标代码.o或.obj,将源代码先处理成汇编语言,在根据汇编语言与机器语言的对应,处理为机器语言;
② 链接则将目标代码“与你程序里面调用的库函数对应的代码连接起来形成对应的可执行文件(.exe)”
3 Make简介
你可以将Makefile理解为一个菜谱,它告诉make tool如何处理你的代码,比如程序A用到了程序B的函数,那么编译的顺序就比较重要了。
最简单的编译指令:$ gcc -o go go.c primes.c
该指令将go.c与primes.c源码编译成为go执行文件。执行后可以用 ./go运行该可执行文件。
可以用-L指定链接的库函数绝对路径,用-l指定要链接的库函数。
例如:$ gcc -o myprog myprog.c -L/home/newhall/lib -lmine
可用-I指定include file的绝对路径,例如加上:-I /home/newhall/include,也可以用相对位置 -l ../include
如果想将自己写的library编译,可以再gcc后加后缀:-c
$ gcc -o mylib.o -c mylib.c (会生成mylib.o文件,后续在编译用到mylib函数的源程序只需在用 '$ gcc -o go go.c -L/home/newhall/lib mylib.o' 即可,此为静态链接)
$ gcc -shared -o libmylib.so mylib.o blah.o grr.o -lm (会生成动态链接文件.so,只后用'$ gcc test.c -L/home/newhall/lib -lmylib' 进行链接)
若想用动态链接,需要将.so文件所在位置export到LD_LIBRARY_PATH,在terminal运行如下指令:export LD_LIBRARY_PATH=/home/newhall/lib:$LD_LIBRARY_PATH (其中的/home/newhall/lib应填写动态库所在位置。)
上述为gcc编译器的基本用法,但若程序项目较大,手动编译就会比较繁琐,因此大多首先编写Makefile,然后在用make编译工具自动进行编译。而CMake文件就是为了在不同平台自动生成Makefile而使用的,到此我们就可以进入下一步学习CMake的学习。
4 推荐参考
https://ring0.me/2014/11/c-compiler/ 《编译:一个 C 程序的艺术之旅》(P.S. 非常好的文章!
https://www.cnblogs.com/mickole/articles/3659112.html 《C/C++程序编译过程详解》
https://blog.csdn.net/kang___xi/article/details/80210717 《深入浅出静态链接和动态链接》详细区分“静态链接”与“动态链接”
https://stackoverflow.com/questions/3368121/how-does-a-c-c-compiler-find-the-definitions-of-prototypes-in-header-files
解释linker过程中如何找到找到include文件中的函数源代码
https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_C_libraries.html Guide you through writing your own C library
http://www.lurklurk.org/linkers/linkers.html Beginner's Guide to Linkers
https://gribblelab.org/CBootCamp/12_Compiling_linking_Makefile_header_files.html Compiling, linking, Makefile, header files