當前位置:首頁 » 編程軟體 » 編譯選項fpic

編譯選項fpic

發布時間: 2022-09-04 21:15:36

『壹』 linux下使用make命令,總是報要加上「-fPIC」,請問如何加

gcc -c -fpic XXX.c

『貳』 怎樣把.c文件編譯成.so文件

比如有一個test.c文件,我想打包成動態庫test.so,
直接gcc
test.c
-o
test.o
-fpic
gcc
-o
test.so
test.o
-shared
使用的時候發布.so和頭文件即可。
鏈接的時候要記得丟在默認目錄或者將其所在目錄聲明到環境變數,不然有時候會提示找不到這個庫文件。

『叄』 gcc 生成動態庫時-fpic選項是什麼意思

使用 -fPIC 選項,會生成 PIC 代碼。.so 要求為 PIC,以達到動態鏈接的目的,否則,無法實現動態鏈接。
non-PIC 與 PIC 代碼的區別主要在於 access global data, jump label 的不同。
比如一條 access global data 的指令,
non-PIC 的形勢是:ld r3, var1
PIC 的形式則是:ld r3, var1-offset@GOT,意思是從 GOT 表的 index 為 var1-offset 的地方處
指示的地址處裝載一個值,即 var1-offset@GOT 處的4個 byte 其實就是 var1 的地址。這個地址只有在運行的時候才知道,
是由 dynamic-loader(ld-linux.so) 填進去的。
再比如 jump label 指令
non-PIC 的形勢是:jump printf ,意思是調用 printf。
PIC 的形式則是:jump printf-offset@GOT,意思是跳到 GOT 表的 index 為 printf-offset 的地方處
指示的地址去執行,這個地址處的代碼擺放在 .plt section,每個外部函數對應一段這樣的代碼,其功能是呼叫
dynamic-loader(ld-linux.so) 來查找函數的地址(本例中是 printf),然後將其地址寫到 GOT 表的 index 為 printf-offset 的地方,
同時執行這個函數。這樣,第2次呼叫 printf 的時候,就會直接跳到 printf 的地址,而不必再查找了。
GOT 是 data section, 是一個 table, 除專用的幾個 entry,每個 entry 的內容可以再執行的時候修改;
PLT 是 text section, 是一段一段的 code,執行中不需要修改。
每個 target 實現 PIC 的機制不同,但大同小異。
比如 MIPS 沒有 .plt, 而是叫 .stub,功能和 .plt 一樣。

『肆』 關於c/c++靜態庫和動態庫的區別

靜態庫

之所以成為【靜態庫】,是因為在鏈接階段,會將匯編生成的目標文件.o與引用到的庫一起鏈接打包到可執行文件中。因此對應的鏈接方式稱為靜態鏈接。

試想一下,靜態庫與匯編生成的目標文件一起鏈接為可執行文件,那麼靜態庫必定跟.o文件格式相似。其實一個靜態庫可以簡單看成是一組目標文件(.o/.obj文件)的集合,即很多目標文件經過壓縮打包後形成的一個文件。靜態庫特點總結:

l 靜態庫對函數庫的鏈接是放在編譯時期完成的。

l 程序在運行時與函數庫再無瓜葛,移植方便。

l 浪費空間和資源,因為所有相關的目標文件與牽涉到的函數庫被鏈接合成一個可執行文件。

下面編寫一些簡單的四則運算C++類,將其編譯成靜態庫給他人用,頭文件如下所示:

StaticMath.h頭文件

#pragma once

class StaticMath

{

public:

StaticMath(void);

~StaticMath(void);

static double add(double a, double b);//加法

static double sub(double a, double b);//減法

static double mul(double a, double b);//乘法

static double div(double a, double b);//除法

void print();

};

Linux下使用ar工具、Windows下vs使用lib.exe,將目標文件壓縮到一起,並且對其進行編號和索引,以便於查找和檢索。一般創建靜態庫的步驟如圖所示:

圖:創建靜態庫過程

Linux下創建與使用靜態庫

Linux靜態庫命名規則

Linux靜態庫命名規范,必須是"lib[your_library_name].a":lib為前綴,中間是靜態庫名,擴展名為.a。

創建靜態庫(.a)

通過上面的流程可以知道,Linux創建靜態庫過程如下:

l 首先,將代碼文件編譯成目標文件.o(StaticMath.o)

g++ -c StaticMath.cpp

注意帶參數-c,否則直接編譯為可執行文件

l 然後,通過ar工具將目標文件打包成.a靜態庫文件

ar -crv libstaticmath.a StaticMath.o

生成靜態庫libstaticmath.a。

大一點的項目會編寫makefile文件(CMake等等工程管理工具)來生成靜態庫,輸入多個命令太麻煩了。

使用靜態庫

編寫使用上面創建的靜態庫的測試代碼:

測試代碼:

#include "StaticMath.h"

#include <iostream>

using namespace std;

int main(int argc, char* argv[])

{

double a = 10;

double b = 2;

cout << "a + b = " << StaticMath::add(a,
b) << endl;

cout << "a - b = " << StaticMath::sub(a,
b) << endl;

cout << "a * b = " << StaticMath::mul(a,
b) << endl;

cout << "a / b = " << StaticMath::div(a,
b) << endl;

StaticMath sm;

sm.print();

system("pause");

return 0;

}

Linux下使用靜態庫,只需要在編譯的時候,指定靜態庫的搜索路徑(-L選項)、指定靜態庫名(不需要lib前綴和.a後綴,-l選項)。

# g++ TestStaticLibrary.cpp -L../StaticLibrary -lstaticmath

l -L:表示要連接的庫所在目錄

l -l:指定鏈接時需要的動態庫,編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.a或.so來確定庫的名稱。

Windows下創建與使用靜態庫

創建靜態庫(.lib)

如果是使用VS命令行生成靜態庫,也是分兩個步驟來生成程序:

l 首先,通過使用帶編譯器選項 /c 的 Cl.exe 編譯代碼 (cl
/c StaticMath.cpp),創建名為「StaticMath.obj」的目標文件。

l 然後,使用庫管理器 Lib.exe 鏈接代碼 (lib StaticMath.obj),創建靜態庫StaticMath.lib。

當然,我們一般不這么用,使用VS工程設置更方便。創建win32控制台程序時,勾選靜態庫類型;打開工程「屬性面板」è」配置屬性」è」常規」,配置類型選擇靜態庫。

圖:vs靜態庫項目屬性設置

Build項目即可生成靜態庫。

使用靜態庫

測試代碼Linux下面的一樣。有3種使用方法:

方法一:

在VS中使用靜態庫方法:

l 工程「屬性面板」è「通用屬性」è 「框架和引用」è」添加引用」,將顯示「添加引用」對話框。 「項目」選項卡列出了當前解決方案中的各個項目以及可以引用的所有庫。 在「項目」選項卡中,選擇 StaticLibrary。 單擊「確定」。

l 添加StaticMath.h 頭文件目錄,必須修改包含目錄路徑。打開工程「屬性面板」è」配置屬性」è 「C/C++」è」 常規」,在「附加包含目錄」屬性值中,鍵入StaticMath.h 頭文件所在目錄的路徑或瀏覽至該目錄。

編譯運行OK。

圖:靜態庫測試結果(vs)

如果引用的靜態庫不是在同一解決方案下的子工程,而是使用第三方提供的靜態庫lib和頭文件,上面的方法設置不了。還有2中方法設置都可行。

方法二:

打開工程「屬性面板」è」配置屬性」è 「鏈接器」è」命令行」,輸入靜態庫的完整路徑即可。

方法三:

l 「屬性面板」è」配置屬性」è 「鏈接器」è」常規」,附加依賴庫目錄中輸入,靜態庫所在目錄;

l 「屬性面板」è」配置屬性」è 「鏈接器」è」輸入」,附加依賴庫中輸入靜態庫名StaticLibrary.lib。

動態庫

通過上面的介紹發現靜態庫,容易使用和理解,也達到了代碼復用的目的,那為什麼還需要動態庫呢?

為什麼還需要動態庫?

為什麼需要動態庫,其實也是靜態庫的特點導致。

l 空間浪費是靜態庫的一個問題。

l 另一個問題是靜態庫對程序的更新、部署和發布頁會帶來麻煩。如果靜態庫liba.lib更新了,所以使用它的應用程序都需要重新編譯、發布給用戶(對於玩家來說,可能是一個很小的改動,卻導致整個程序重新下載,全量更新)。

動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行是才被載入。不同的應用程序如果調用相同的庫,那麼在內存里只需要有一份該共享庫的實例,規避了空間浪費問題。動態庫在程序運行是才被載入,也解決了靜態庫對程序的更新、部署和發布頁會帶來麻煩。用戶只需要更新動態庫即可,增量更新。

動態庫特點總結:

l 動態庫把對一些庫函數的鏈接載入推遲到程序運行的時期。

l 可以實現進程之間的資源共享。(因此動態庫也稱為共享庫)

l 將一些程序升級變得簡單。

l 甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制(顯示調用)。

Window與Linux執行文件格式不同,在創建動態庫的時候有一些差異。

l 在Windows系統下的執行文件格式是PE格式,動態庫需要一個DllMain函數做出初始化的入口,通常在導出函數的聲明時需要有_declspec(dllexport)關鍵字。

l Linux下gcc編譯的執行文件默認是ELF格式,不需要初始化入口,亦不需要函數做特別的聲明,編寫比較方便。

與創建靜態庫不同的是,不需要打包工具(ar、lib.exe),直接使用編譯器即可創建動態庫。

Linux下創建與使用動態庫

linux動態庫的命名規則

動態鏈接庫的名字形式為 libxxx.so,前綴是lib,後綴名為「.so」。

l 針對於實際庫文件,每個共享庫都有個特殊的名字「soname」。在程序啟動後,程序通過這個名字來告訴動態載入器該載入哪個共享庫。

l 在文件系統中,soname僅是一個鏈接到實際動態庫的鏈接。對於動態庫而言,每個庫實際上都有另一個名字給編譯器來用。它是一個指向實際庫鏡像文件的鏈接文件(lib+soname+.so)。

創建動態庫(.so)

編寫四則運算動態庫代碼:

DynamicMath.h頭文件

#pragma once

class DynamicMath

{

public:

DynamicMath(void);

~DynamicMath(void);

static double add(double a, double b);//¼Ó·¨

static double sub(double a, double b);//¼õ·¨

static double mul(double a, double b);//³Ë·¨

static double div(double a, double b);//³ý·¨

void print();

};

l 首先,生成目標文件,此時要加編譯器選項-fpic

g++ -fPIC -c DynamicMath.cpp

-fPIC 創建與地址無關的編譯程序(pic,position independent code),是為了能夠在多個應用程序間共享。

l 然後,生成動態庫,此時要加鏈接器選項-shared

g++ -shared -o libdynmath.so DynamicMath.o

-shared指定生成動態鏈接庫。

其實上面兩個步驟可以合並為一個命令:

g++ -fPIC -shared -o libdynmath.so DynamicMath.cpp

使用動態庫

編寫使用動態庫的測試代碼:

測試代碼:

#include "../DynamicLibrary/DynamicMath.h"

#include <iostream>

using namespace std;

int main(int argc, char* argv[])

{

double a = 10;

double b = 2;

cout << "a + b = " << DynamicMath::add(a, b) << endl;

cout << "a - b = " << DynamicMath::sub(a, b) << endl;

cout << "a * b = " << DynamicMath::mul(a, b) << endl;

cout << "a / b = " << DynamicMath::div(a, b) << endl;

DynamicMath dyn;

dyn.print();

return 0;

}

引用動態庫編譯成可執行文件(跟靜態庫方式一樣):

g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath

然後運行:./a.out,發現竟然報錯了!!!

可能大家會猜測,是因為動態庫跟測試程序不是一個目錄,那我們驗證下是否如此:

發現還是報錯!!!那麼,在執行的時候是如何定位共享庫文件的呢?

1) 當系統載入可執行代碼時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑。此時就需要系統動態載入器(dynamic linker/loader)。

2) 對於elf格式的可執行程序,是由ld-linux.so*來完成的,它先後搜索elf文件的DT_RPATH段—環境變數LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 目錄找到庫文件後將其載入內存。

如何讓系統能夠找到它:

l 如果安裝在/lib或者/usr/lib下,那麼ld默認能夠找到,無需其他操作。

l 如果安裝在其他目錄,需要將其添加到/etc/ld.so.cache文件中,步驟如下:

n 編輯/etc/ld.so.conf文件,加入庫文件所在目錄的路徑

n 運行ldconfig ,該命令會重建/etc/ld.so.cache文件

我們將創建的動態庫復制到/usr/lib下面,然後運行測試程序。

Windows下創建與使用動態庫

創建動態庫(.dll)

與Linux相比,在Windows系統下創建動態庫要稍微麻煩一些。首先,需要一個DllMain函數做出初始化的入口(創建win32控制台程序時,勾選DLL類型會自動生成這個文件):

dllmain.cpp入口文件

// dllmain.cpp : Defines the entry point for the DLL application.

#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hMole,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

return TRUE;

}

通常在導出函數的聲明時需要有_declspec(dllexport)關鍵字:

DynamicMath.h頭文件

#pragma once

class DynamicMath

{

public:

__declspec(dllexport) DynamicMath(void);

__declspec(dllexport) ~DynamicMath(void);

static __declspec(dllexport) double add(double a, double b);//加法

static __declspec(dllexport) double sub(double a, double b);//減法

static __declspec(dllexport) double mul(double a, double b);//乘法

static __declspec(dllexport) double div(double a, double b);//除法

__declspec(dllexport) void print();

};

生成動態庫需要設置工程屬性,打開工程「屬性面板」è」配置屬性」è」常規」,配置類型選擇動態庫。

圖:v動態庫項目屬性設置

Build項目即可生成動態庫。

使用動態庫

創建win32控制台測試程序:

TestDynamicLibrary.cpp測試程序

#include "stdafx.h"

#include "DynamicMath.h"

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

double a = 10;

double b = 2;

cout << "a + b = " << DynamicMath::add(a,
b) << endl;

cout << "a - b = " << DynamicMath::sub(a,
b) << endl;

cout << "a * b = " << DynamicMath::mul(a,
b) << endl;

cout << "a / b = " << DynamicMath::div(a,
b) << endl;

DynamicMath dyn;

dyn.print();

system("pause");

return 0;

}

方法一:

l 工程「屬性面板」è「通用屬性」è 「框架和引用」è」添加引用」,將顯示「添加引用」對話框。「項目」選項卡列出了當前解決方案中的各個項目以及可以引用的所有庫。 在「項目」選項卡中,選擇 DynamicLibrary。 單擊「確定」。

l 添加DynamicMath.h 頭文件目錄,必須修改包含目錄路徑。打開工程「屬性面板」è」配置屬性」è 「C/C++」è」 常規」,在「附加包含目錄」屬性值中,鍵入DynamicMath.h 頭文件所在目錄的路徑或瀏覽至該目錄。

編譯運行OK。

圖:動態庫測試結果(vs)

方法二:

l 「屬性面板」è」配置屬性」è 「鏈接器」è」常規」,附加依賴庫目錄中輸入,動態庫所在目錄;

l 「屬性面板」è」配置屬性」è 「鏈接器」è」輸入」,附加依賴庫中輸入動態庫編譯出來的DynamicLibrary.lib。

這里可能大家有個疑問,動態庫怎麼還有一個DynamicLibrary.lib文件?即無論是靜態鏈接庫還是動態鏈接庫,最後都有lib文件,那麼兩者區別是什麼呢?其實,兩個是完全不一樣的東西。

StaticLibrary.lib的大小為190KB,DynamicLibrary.lib的大小為3KB,靜態庫對應的lib文件叫靜態庫,動態庫對應的lib文件叫【導入庫】。實際上靜態庫本身就包含了實際執行代碼、符號表等等,而對於導入庫而言,其實際的執行代碼位於動態庫中,導入庫只包含了地址符號表等,確保程序找到對應函數的一些基本地址信息。

動態庫的顯式調用

上面介紹的動態庫使用方法和靜態庫類似屬於隱式調用,編譯的時候指定相應的庫和查找路徑。其實,動態庫還可以顯式調用。【在C語言中】,顯示調用一個動態庫輕而易舉!

在Linux下顯式調用動態庫

#include <dlfcn.h>,提供了下面幾個介面:

l void * dlopen( const char * pathname, int mode ):函數以指定模式打開指定的動態連接庫文件,並返回一個句柄給調用進程。

l void* dlsym(void* handle,const char* symbol):dlsym根據動態鏈接庫操作句柄(pHandle)與符號(symbol),返回符號對應的地址。使用這個函數不但可以獲取函數地址,也可以獲取變數地址。

l int dlclose (void *handle):dlclose用於關閉指定句柄的動態鏈接庫,只有當此動態鏈接庫的使用計數為0時,才會真正被系統卸載。

l const char *dlerror(void):當動態鏈接庫操作函數執行失敗時,dlerror可以返回出錯信息,返回值為NULL時表示操作函數執行成功。

在Windows下顯式調用動態庫

應用程序必須進行函數調用以在運行時顯式載入 DLL。為顯式鏈接到 DLL,應用程序必須:

l 調用 LoadLibrary(或相似的函數)以載入 DLL 和獲取模塊句柄。

l 調用 GetProcAddress,以獲取指向應用程序要調用的每個導出函數的函數指針。由於應用程序是通過指針調用 DLL 的函數,編譯器不生成外部引用,故無需與導入庫鏈接。

l 使用完 DLL 後調用 FreeLibrary。

顯式調用C++動態庫注意點

對C++來說,情況稍微復雜。顯式載入一個C++動態庫的困難一部分是因為C++的name
mangling;另一部分是因為沒有提供一個合適的API來裝載類,在C++中,您可能要用到庫中的一個類,而這需要創建該類的一個實例,這不容易做到。

name mangling可以通過extern "C"解決。C++有個特定的關鍵字用來聲明採用C
binding的函數:extern "C" 。用 extern "C"聲明的函數將使用函數名作符號名,就像C函數一樣。因此,只有非成員函數才能被聲明為extern
"C",並且不能被重載。盡管限制多多,extern "C"函數還是非常有用,因為它們可以象C函數一樣被dlopen動態載入。冠以extern
"C"限定符後,並不意味著函數中無法使用C++代碼了,相反,它仍然是一個完全的C++函數,可以使用任何C++特性和各種類型的參數。

『伍』 如何使用android的ndk編譯器 編譯c++的庫

1. 概述 首先回顧一下 Android NDK 開發中,Android.mk 和 Application.mk 各自的職責。 Android.mk,負責配置如下內容: (1) 模塊名(LOCAL_MODULE) (2) 需要編譯的源文件(LOCAL_SRC_FILES) (3) 依賴的第三方庫(LOCAL_STATIC_LIBRARIES,LOCAL_SHARED_LIBRARIES) (4) 編譯/鏈接選項(LOCAL_LDLIBS、LOCAL_CFLAGS) Application.mk,負責配置如下內容: (1) 目標平台的ABI類型(默認值:armeabi)(APP_ABI) (2) Toolchains(默認值:GCC 4.8) (3) C++標准庫類型(默認值:system)(APP_STL) (4) release/debug模式(默認值:release) 由此我們可以看到,本文所涉及的編譯選項在Android.mk和Application.mk中均有出現,下面我們將一個個詳細介紹。 2. APP_ABI ABI全稱是:Application binary interface,即:應用程序二進制介面,它定義了一套規則,允許編譯好的二進制目標代碼在所有兼容該ABI的操作系統和硬體平台中無需改動就能運行。(具體的定義請參考 網路 或者 維基網路 ) 由上述定義可以判斷,ABI定義了規則,而具體的實現則是由編譯器、CPU、操作系統共同來完成的。不同的CPU晶元(如:ARM、Intel x86、MIPS)支持不同的ABI架構,常見的ABI類型包括:armeabi,armeabi-v7a,x86,x86_64,mips,mips64,arm64-v8a等。 這就是為什麼我們編譯出來的可以運行於Windows的二進製程序不能運行於Mac OS/Linux/Android平台了,因為CPU晶元和操作系統均不相同,支持的ABI類型也不一樣,因此無法識別對方的二進製程序。 而我們所說的「交叉編譯」的核心原理也跟這些密切相關,交叉編譯,就是使用交叉編譯工具,在一個平台上編譯生成另一個平台上的二進制可執行程序,為什麼可以做到?因為交叉編譯工具實現了另一個平台所定義的ABI規則。我們在Windows/Linux平台使用Android NDK交叉編譯工具來編譯出Android平台的庫也是這個道理。 這里給出最新 Android NDK 所支持的ABI類型及區別: 那麼,如何指定ABI類型呢?在 Application.mk 文件中添加一行即可: APP_ABI := armeabi-v7a //只編譯armeabi-v7a版本 APP_ABI := armeabi armeabi-v7a //同時編譯armeabi,armeabi-v7a版本 APP_ABI := all //編譯所有版本 3. LOCAL_LDLIBS Android NDK 除了提供了Bionic libc庫,還提供了一些其他的庫,可以在 Android.mk 文件中通過如下方式添加依賴: LOCAL_LDLIBS := -lfoo 其中,如下幾個庫在 Android NDK 編譯時就默認鏈接了,不需要額外添加在 LOCAL_LDLIBS 中: (1) Bionic libc庫 (2) pthread庫(-lpthread) (3) math(-lmath) (4) C++ support library (-lstdc++) 下面我列了一個表,給出了可以添加到「LOCAL_LDLIBS」中的不同版本的Android NDK所支持的庫: 下面是我總結的一些常用的CFLAGS編譯選項: (1)通用的編譯選項 -O2 編譯優化選項,一般選擇O2,兼顧了優化程度與目標大小 -Wall 打開所有編譯過程中的Warning -fPIC 編譯位置無關的代碼,一般用於編譯動態庫 -shared 編譯動態庫 -fopenmp 打開多核並行計算, -Idir 配置頭文件搜索路徑,如果有多個-I選項,則路徑的搜索先後順序是從左到右的,即在前面的路徑會被選搜索 -nostdinc 該選項指示不要標准路徑下的搜索頭文件,而只搜索-I選項指定的路徑和當前路徑。 --sysroot=dir 用dir作為頭文件和庫文件的邏輯根目錄,例如,正常情況下,如果編譯器在/usr/include搜索頭文件,在/usr/lib下搜索庫文件,它將用dir/usr/include和dir/usr/lib替代原來的相應路徑。 -llibrary 查找名為library的庫進行鏈接 -Ldir 增加-l選項指定的庫文件的搜索路徑,即編譯器會到dir路徑下搜索-l指定的庫文件。 -nostdlib 該選項指示鏈接的時候不要使用標准路徑下的庫文件 (2) ARM平台相關的編譯選項 -marm -mthumb 二選一,指定編譯thumb指令集還是arm指令集 -march=name 指定特定的ARM架構,常用的包括:-march=armv6, -march=armv7-a -mfpu=name 給出目標平台的浮點運算處理器類型,常用的包括:-mfpu=neon,-mfpu=vfpv3-d16 -mfloat-abi=name 給出目標平台的浮點預算ABI,支持的參數包括:「soft」, 「softfp」 and 「hard」

『陸』 matlab怎麼生成動態鏈接庫

1>首先生成目標文件,但是此時要加編譯器選項-fpic和鏈接器選項-shared,

gcc -fpic -c add.c

gcc -fpic -c sub.c

生成中間文件add.o和sub.o

2>其次生成動態庫

gcc -shared –o libtiger.so add.o sub.o

生成動態庫libtiger.so,libtiger.so就是我們生成的目標動態庫。我們以後使用動態庫和main.c程序生成可執行程序

說明:

以上兩部也可以合成一步搞定:

gcc -fpic -shared add.c sub.c -o libtiger.so

2.使用動態鏈接庫

在編譯程序時,使用動態鏈接庫和靜態庫是一致的,使用」-l庫名」的方式,在生成可執行文件的時候會鏈接庫文件。

1>使用命令:

gcc -o main main.c -L ./ -ltiger

2>-L指定動態鏈接庫的路勁,-ldtiger鏈接庫函數tiger。-ltiger是動態庫的調用規則。Linux系統下的動態庫命名方式是lib*.so,而在鏈接時表示位-l*,*是自己命名的庫名。

3>但是程序會提示如下錯誤

error while loading shared libraries: libtiger.so: cannot open shared object file: No such file or direct

『柒』 gcc 生成動態庫時-fpic選項是什麼意思。

fpic:產生位置無關碼

解釋一下,位置無關碼就是可以在進程的任意內存位置執行的目標碼,動態鏈接庫必須使用。

『捌』 如何使用lame源代碼在編譯生成linux環境下的動態庫

動態庫的生成
1>首先生成目標文件,但是此時要加編譯器選項-fpic和鏈接器選項-shared,

gcc -fpic -c add.c

gcc -fpic -c sub.c

生成中間文件add.o和sub.o

2>其次生成動態庫

gcc -shared –o libtiger.so add.o sub.o

生成動態庫libtiger.so,libtiger.so就是我們生成的目標動態庫。我們以後使用動態庫和main.c程序生成可執行程序

說明:

以上兩部也可以合成一步搞定:

gcc -fpic -shared add.c sub.c -o libtiger.so

2.使用動態鏈接庫

在編譯程序時,使用動態鏈接庫和靜態庫是一致的,使用」-l庫名」的方式,在生成可執行文件的時候會鏈接庫文件。

1>使用命令:

gcc -o main main.c -L ./ -ltiger

2>-L指定動態鏈接庫的路勁,-ldtiger鏈接庫函數tiger。-ltiger是動態庫的調用規則。Linux系統下的動態庫命名方式是lib*.so,而在鏈接時表示位-l*,*是自己命名的庫名。

3>但是程序會提示如下錯誤

error while loading shared libraries: libtiger.so: cannot open shared object file: No such file or direct

這是因為程序運行時沒有找到動態鏈接庫造成的。程序編譯時鏈接動態庫和運行時使用動態鏈接庫的概念是不同的,在運行時,程序鏈接的動態鏈接庫需要在系統目錄下才行。

4>使用以下方法可以解決此問題

a. 在linux下最方便的解決方案是拷貝libtiger.so到絕對目錄 /lib 下(但是,要是超級用戶才可以,因此要使用sudo哦,親)。就可以生成可執行程序了

b.第二種方法是:將動態鏈接庫的目錄放到程序搜索路徑中,可以將庫的路徑加到環境變數LD_LIBRARY_PATH中實現:

export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

『玖』 gcc -shared -fPIC 什麼意思,詳細解釋下

-shared 表示要編譯成為動態鏈接庫
-fPIC表示庫可以在進程的任意內存地址處運行

熱點內容
linux內核搶占 發布:2025-02-13 10:36:32 瀏覽:889
家裝公司源碼 發布:2025-02-13 10:35:35 瀏覽:48
aspnet更新資料庫 發布:2025-02-13 10:35:34 瀏覽:384
海爾壓縮機不工作 發布:2025-02-13 10:15:32 瀏覽:223
才兒坊編程 發布:2025-02-13 10:09:58 瀏覽:729
手機存儲速度測試 發布:2025-02-13 10:09:58 瀏覽:368
什麼是安卓客戶端開發 發布:2025-02-13 10:07:48 瀏覽:614
加密脫殼 發布:2025-02-13 10:07:44 瀏覽:639
oppor9怎麼壓縮圖片 發布:2025-02-13 10:06:13 瀏覽:948
雲伺服器app哪個最好 發布:2025-02-13 09:47:53 瀏覽:1000