一、動態編譯與靜態編譯
動態編譯使用的是動態庫文件進行編譯,默認使用的是動態編譯方法。
gcc hello.c -o hello
靜態編譯使用的是靜態庫文件進行的編譯
gcc -static hello.c -o hello
靜態編譯要把靜態庫文件打包編譯到可執行程序中,動態編譯不會把動態庫文件打包編譯到可執行程序中,它們只是編譯鏈接關系。
二、制作靜態庫
首先看一個例子,有一下三個c語言文件,mylib.c、mylib.h、mytest.c。mylib.h做函數的聲明,mylib.c做函數的定義,mytest.c做功能的測試。
mylib.c
int max(int x,int y)
{
return x>y?x:y;
}
int min(int x,int y)
{
return x
mylib.h
#ifndef __MYLIB_H__
#define __MYLIB_H__
extern int max(int x,int y);
extern int min(int x,int y);
#endif
mytest.c
#include
#include "mylib.h"
int main(int argc,char *argv[])
{
int a=10,b=20,max_num,min_num;
max_num=max(a,b);
min_num=min(a,b);
printf("max_num=%d\\n",max_num);
printf("min_num=%d\\n",min_num);
return 0;
}
下面我們想讓mylib.c打包為一個庫文件。過程如下,首先我們讓想打包的文件生成.o文件
gcc -c mylib.c -o mylib.o
然后將這個.o文件做成一個靜態庫,注意:靜態庫起名的時候必須以lib開頭以.a結尾。
ar rc libmylib.a mylib.o
制作好靜態庫之后,我們可以編譯程序了,這時候就可以不使用mylib.c文件了。編譯程序有三種方法如下:
方法一
這幾個文件都在同一個目錄下面,就可以不用這么麻煩,直接使用下面的命令就可以完成編譯。
gcc -static mytest.c libmylib.a -o mytest
方法二
可以指定頭文件及庫文件路徑,比如我們可以將libmylib.a和mylib.h移動到/home/test文件夾下,那么可以使用的命令如下:
gcc -static mytest.c -o mytest -L/home/test -lmylib -I/home/test
下面對其中的參數做一些解釋:
- -L是指定庫文件的路徑
- -l是指定找哪個庫,指定的只要庫文件lib后面.a前面的部分
- -I是指定頭文件的路徑
方法三
可以將庫文件和頭文件存放到系統默認指定的路徑下。庫文件默認路徑是/lib或者是/usr/lib。頭文件默認路徑是/usr/include。所以可以執行下面兩條命令。
sudo mv libmylib.a /usr/lib
sudo mv mylib.h /usr/include
然后就可以執行編譯程序命令。
gcc -static mytest.c -o mytest -lmylib
-l是指定的要找哪個庫。
三、制作動態庫
還是上面代碼的例子,生成一個mylib.c的動態庫文件。
1、首先是將要加入動態庫的源文件編譯為與位置無關的目標文件。
gcc -fPIC -c mylib.c
這時候就會生成一個與位置無關的目標文件,關于為什么會加上-fPIC的選項,可以參考這個博客。
2、然后第二步是將第一步生成的目標文件打包到動態庫文件 。
gcc -shared -o libmylib.so mylib.o
3、然后是動態庫鏈接生成可執行文件
gcc mytest.c libmylib.so -o mytest
但是這時候執行./mytest會報錯,錯誤代碼如下:
error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
因為系統找不到自定義的庫文件在那,可以有兩種方法解決這個問題。
方法一
庫文件、頭文件均在當前目錄下,通過添加環境變量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
由于所有的庫文件都在當前目錄下,所有將當前路徑添加到環境變量中。然后在使用命令進行編譯:
gcc mytest.c libmylib.so -o mytest
這時候程序可以正常運行。
方法二
庫函數、頭文件假設均在/home文件夾下面,這個時候還需要添加環境變量
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
然后通過以下命令進行編譯:
gcc mytest.c -o mytest -L/home -lmylib -I/home
然后執行可以通過。
方法三
將指定庫函數和頭文件均在系統路徑下:
sudo cp libmylib.so /usr/lib
sudo cp mylib.h /usr/include
然后進行編譯
gcc mytest.c -o mytest -lmylib
這個時候會顯示編譯通過,不需要添加環境變量。
審核編輯:湯梓紅
-
C語言
+關注
關注
180文章
7614瀏覽量
137732 -
靜態庫
+關注
關注
0文章
21瀏覽量
7487 -
編譯
+關注
關注
0文章
661瀏覽量
33046 -
動態庫
+關注
關注
0文章
17瀏覽量
6270
發布評論請先 登錄
相關推薦
評論