c++中編譯鏈接總結


1 編譯鏈接過程分為 預處理--->編譯---->匯編---->鏈接。如下圖所示

2 預處理都做了什么

(1)將所有的#define刪除並展開所有的宏

(2)處理所有的條件預編譯指令比如#if #ifdef

(3)處理#Incldue預編譯指令,將包含的文件插入到預編譯的文件中。采用頭文件的目的是可以供多個不同的cpp源程序使用。自己定義的通常用“”,如果包含庫文件的一般是“<>”.

(4)過濾所有的注釋符號

(5)添加行號和文件標識。方便再編譯器產生調試用的行號信息等

(6)保留所有的#pragma編譯器指令。

3 編譯

(1)將預處理完成的文件進行一系列的詞法分析,語法分析等產生匯編代碼文件。

g++ -S hello.i -o hello.s可以通過打開helloword.s查看匯編代碼。

4 鏈接

(1)將鏈接的模塊獨立地編譯然后組裝起來,這就是鏈接啦

(2)最基本的靜態鏈接過程如下圖所示

(3)庫也就是一組目標文件的包,將代碼編譯成目標文件以后打包存放。

(4)靜態鏈接

對函數庫的鏈接放在編譯時期完成的是靜態鏈接。目標文件和相關的函數庫被合成一個可執行文件。通常為libxxx.a

例子:

代碼如下

 1 //main.cpp
 2 
 3 #include "add.h"
 4 #include "sub.h"
 5 #include "iostream"
 6 using namespace std;
 7 //演示靜態鏈接
 8 int main(){
 9     cout<<"1+2="<<add(1,2)<<endl;
10     cout<<"1-2="<<sub(1,2)<<endl;
11     return 0;
12 }
View Code
1 #include "sub.h" 
2 int sub(int a,int b){ 
3  return a-b; 
4 }
View Code
1 //sub.h
2 #ifndef _SUB_H_
3 #define _SUB_H_
4 int sub(int a, int b);
5 #endif 
View Code
1 //add.cpp
2 #include "add.h"
3 int add(int a, int b){
4     return a+b;
5 }
View Code
1 //add.h
2 #ifndef _ADD_H_
3 #define _ADD_H_
4 int add(int a, int b);
5 #endif
View Code

(4-1)先將cpp編譯成.o文件

g++ -c add.cpp

g++ -c sub.cpp  注意 動態和靜態鏈接都是由.o文件船艦

(4-2).o---->.a文件   ar cr libmymath.a sub.o add.o 這樣會生成libmymath.c文件如下圖所示

注意:庫文件規范一般就是以lib開頭 然后靜態庫名 .a后綴名

r:在庫中插入模塊

c:創建一個庫

(4-3)使用靜態庫

g++ -o main main.cpp -L -lmymath這樣生成main文件

(5)動態鏈接

(5-1)靜態鏈接是在編譯時期,那么動態可以推遲到運行時期。擴展名.so

(5-2)生成方法

g++ -fPIC -shared -o libmymath.so add.cpp sub.cpp

編譯參數解析:

-fPIC:編譯為位置獨立的代碼

-Lpath:path目錄搜索庫文件 -L便是當前目錄

-Ipath:表示path目錄中搜索文件

-ltest:編譯器查找動態鏈接庫時候有隱含的命名規則則名字前面lib 后綴.so

注意:運行的時候g++ -o main main.cpp -L. -lmymath鏈接正常但是執行會出錯。主要是找不到.so。因為程序運行

會在/usr/lib和/lib中找相應的動態庫文件。解決方法:將libmymath.so復制到目錄/user/lib中

(6)靜態鏈接和動態鏈接各自的特點

6-1:程序運行的時候,操作系統會看內存是否有庫函數的拷貝,有的話就不會鏈接載入,這樣節省勒內存資源。靜態庫則不同,每個程序都會將這個庫函數拷貝到自己的代碼段中,這樣就占用了內存資源。

6-2 用靜態庫,如果庫發生了變化,使用的庫需要重新編譯。動態庫則不會,提供的接口不會變化,只是重新用新生成的動態庫替換就ok

 

加油----->一天快結束了。。


免責聲明!

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



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