靜態庫與動態庫原理,編譯流程詳解。
編譯原理和語法詳解(何老師)
編譯流程(高級語言轉換成二進制機器語言)
主要流程有:
預處理:完成宏替換,以及去除空行,註釋等,爲下一步的編譯做準備。也就是對各種預處理進行處理,包括頭文件的包含、宏定義的擴展、條件編譯的選擇等。
gcc -E test.c -o test.i 其中的E表示gcc在進行預處理後不再進行下面的操作了。
編譯:將預處理後的代碼編譯成彙編代碼。在這個階段中首先要檢查代碼的規範性、是否有語法的錯誤等。以確定代碼實際要做的工作,在檢查無誤後,再把代碼翻譯成彙編語言。
編譯程序執行時,先分析,後綜合,分析,就是指詞法分析,語法分析,語義分析和中間代碼生成。綜合,就是指代碼優化和代碼生成。
大多數的編譯程序直接產生機器語言的目標代碼,形成可執行的目標文件,也有的是先產生彙編語言一級的符號代碼文件再調用匯編程序進行翻譯和加工處理,最後產生可執行的機器語言目標文件。
gcc -S test.i -o test.s 其中的S讓gcc在編譯結束後停止編譯過程,“test.s”文件爲編譯後生成的彙編代碼。
彙編:就是把編譯階段生成的".s"文件轉成二進制目標代碼,也就是機器代碼(01序列)
gcc -c test.s -o test.o -C表示gcc在彙編結束後停止編譯過程,test.o文件爲彙編生成的機器碼目標文件。
鏈接:就是將多個目標文件以及所需的庫文件鏈接生成可執行目標文件的過程。
gcc test.o -o test test可執行文件,-o本質上是一個重命名選項,不使用-o選項時默認生成的時a.out文件。
靜態庫
靜態庫實際就是一些目標文件(一般以.o結尾)的集合,靜態庫一般以.a結尾,只用於生成可執行文件階段。
在鏈接步驟中,鏈接器將從庫文件取得所需代碼,複製到生成可執行文件中。這種庫稱爲靜態庫。其特點是可執行文件中包含了庫文件的一份完整拷貝,在編譯的過程中被載入程序中,缺點是多次使用就會有多份贅餘拷貝,並對程序的更新部署和發佈迴帶來麻煩,如靜態庫有更新,那麼所有使用它的程序都要重新編譯,發佈。
生成靜態庫,首先生成test.o目標文件,使用ar命令將test.o打包成libtest.a靜態庫
動態庫
動態庫在鏈接階段沒有被複制到程序中,而是在程序運行時由系統動態加載到內存中供程序調用。
系統只需載入一次動態庫,不同的程序可以得到內存中相同動態庫的副本,因此節省很多內存,
生成靜態庫:
生成動態庫
動態庫和靜態庫的區別
MakeFile走讀與語法基礎
makeFile是什麼 是make腳本工具
定義一系列規則,自動化編譯腳本
makefile包含五個:
顯示規則:說明如何生成或多個目標文件
隱晦規則:makefile有自動推導
變量定義:makefile可以定義很多變量,變量就是字符串
文件指示:1、一個引用另一個,2、指定makefile有效部分 ,3、定義多行命令
註釋 行註釋,用#註釋
Makefile的規則
target:目標文件,可以是ObjectFile,也可以是執行文件,還可以是標籤(Lable)
prerequisites:依賴文件,即要生成的那個target所需要的文件或其他target
command :make需要執行的命令
如果在同一行的可以用分號,如果不在一行比如使用tab鍵
Makefile事例
Makefile是如何工作的
Makefile中使用變量
引用其他的Makefile
環境變量MAKEFILES
Makefile預定義變量
Makefile自動變量
Makefile的函數
make的工作流程
GNU的make工作時的執行步驟如下:
-
讀入所有的Makefile。
-
讀入被include的其他Makefile
-
初始化文件中的變量
-
推導隱晦規則,並分析所有規則
-
爲所有的目標文件創建依賴關係鏈
-
根據依賴關係,決定那些目標要重新生成
-
執行生成命令
Android.mk基礎
Android.mk是一個向Android NDK構建系統描述NDK項目的GNUmakefile片段。主要用來編譯生成以下幾種:
-
APK程序:一般的Android應用程序,系統級別的直接push即可
-
JAVA庫:JAVA類庫,編譯打包生成JAR文件
-
C\C++應用程序:可執行的c\c++應用程序
-
C\C++靜態庫:編譯生成C\C++靜態庫,並打包成.a文件
-
C\C++共享庫:編譯生成共享庫,並打包成so文件。
Android.mk基本格式
編譯多個共享庫
編譯靜態庫
使用共享庫共享通用模塊
如何使用預編譯庫
編譯獨立的可執行文件
注意