CMake學習(零):關於編譯過程與gcc編譯


<-以下為學習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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM