寫在前面:最近因為需要在不同版本的linux上運行編譯后的文件,經常會遇到找不到需要的鏈接庫文件的問題,后來突然想起了靜態(tài)編譯這一說。
1:建靜態(tài)庫
/* hellos.h */
#ifndef _HELLO_S_H
#define _HELLO_S_H
void printS(char* str);
#endif
/* hellos.c */
#include "hellos.h"
void printS(char* str)
{
printf("print in static way: %s", str);
}
輸入命令:
gcc -c -o hellos.o hellos.c
ar cqs libhellos.a hellos.o //ar是生成庫的命令,cqs是參數, libhellos.a是生成的靜態(tài)鏈接庫須以lib開頭,hellos是庫名,a表示是靜態(tài)鏈接庫,hellos.o是剛才生成目標文件。于是得到了libhellos.a這么一個靜態(tài)鏈接庫
2:主程序
/* main.c */
#include <stdio.h>
#include "hellos.h"
main()
{
char* text = "Hello World!\n";
printS(text);
}
編譯鏈接:
gcc -o hello main.c -static -L. –lhellos
下面是關于上面命令的解釋:
庫依賴
使用-I參數可以向gcc的頭文件搜索路徑中添加新目錄。
gcc hello.c -I /home/wuzhiguo/include -o hello
使用-L參數可以向gcc的庫文件搜索路徑中添加新目錄。
gcc hello.c -L /home/wuzhiguo/lib -l mylib -o hello
-l mylib 是指示gcc去鏈接庫文件libmylib.so。Linux下的庫文件有一個約定,全部以lib開頭,因此可以省去lib。
動態(tài)庫:.so結尾,在運行時加載。
靜態(tài)庫:.a結尾,在編譯時加載。
默認gcc優(yōu)先加載動態(tài)庫,可以在通過-static選項強制使用靜態(tài)鏈接庫。
gcc hello.c -L /home/wuzhiguo/lib -static -l mylib -o hello
所以-L后面的點為當前目錄,-l后面是要靜態(tài)連接的庫(libhellos.a)
然后運行hello可以看到輸出
print in static way: Hello World!
刪除libhellos.a和hellos.*后, 程序仍然正常運行。
下面再來看動態(tài)鏈接
3:建動態(tài)庫
/* hellod.h */
#ifndef _HELLO_D_H
#define _HELLO_D_H
void printD(char* str);
#endif
/* hellod.c */
#include "hellod.h"
void printD(char* str)
{
printf("print in dynamic way: %s", str);
}
輸入命令:
gcc -shared -o libhellod.so hellod.c
于是得到了libhellod.so這么一個動態(tài)鏈接庫,然后復制到/lib目錄中,否則運行的時候找不到庫文件。
4:主程序
/* main.c */
#include <stdio.h>
#include "hellod.h"
main()
{
char* text = "Hello World!\n";
printD(text);
}
編譯鏈接:
gcc -o hello main.c -L. -lhellod
然后運行hello可以看到輸出
print in dynamic way: Hello World!
如果這時候刪除剛剛生成的hellod.dll,再運行則會報告一個找不到hellod.dll的錯誤,程序無法正常運行。