當前位置:首頁 » 編程軟體 » ide編譯時找不到靜態庫

ide編譯時找不到靜態庫

發布時間: 2023-09-16 03:50:33

A. 多級目錄makefile,靜態庫

在lib 目錄下編譯需要生成動態庫的文件,生成動態庫,並安裝到系統的標准庫中,供
程序調用。具體步驟如下:
(1) 編寫Makefile.am 文件
AUTOMAKE_OPTIONS=foreign
lib_LTLIBRARIES=libhello.la
libhello_la_SOURCES=test.c
這里lib_LTLIBRARIES 的意思是生成的動態庫,然後指定動態庫依賴的源文件
test.c ,若有多個源文件用空格隔開。
(2) 在lib 目錄下,用命令autoscan 產生configure.scan 文件,並改名為configure.in。 這
里需加上宏AC_PROG_LIBTOOL,表示利用libtool 來自動生成動態庫
#configure.in
# Process this file with autoconf to proce a configure script.
AC_PREREQ(2.59)
AC_INIT(hello,1.0, [[email protected]])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([test.c])
#AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_PROG_LIBTOOL
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
(3) 執行命令aclocal、libtoolize -f -c 、autoconf、automake --add-missing、./configure、
make、make install 將動態庫安裝到系統的標准庫中,以供調用(一般為/usr/local/lib)。
註:libtoolize 提供了一種標準的方式來將libtool 支持加入一個軟體包,而GNU libtool 是
一個通用庫支持腳本,將使用動態庫的復雜性隱藏在統一、可移植的介面中。
4. 生成src 目錄下的hello 可執行文件
(1) 編寫src/Makefile.am 文件
AUTOMAKE_OPTIONS=foreign
INCLUDES= -I../include
bin_PROGRAMS=hello
hello_SOURCES=hello.c
hello_LDADD=-lhello
-ldir 指定編譯時搜索庫的路徑。與靜態庫不同的是,創建動態庫時不用指定庫路
徑,編譯器自動在標准庫中查找libhello.so 文件。
(2) 執行autoscan 生成configure.scan 文件,將它重命名為configure.in 並修改其內容。
# configure.in
# Process this file with autoconf to proce a configure script.
AC_PREREQ(2.59)
AC_INIT(hello,1.0, [[email protected]])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([hello.c])
#AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
(3) 在src 目錄下編譯並生成目標文件,執行命令aclocal、libtoolize -f -c 、autoconf、
automake --add-missing、./configure、make,此時你一定會覺得,成功近在咫尺了。再
執行目標文件./hello,結果卻在你的意料之外:
./hello: error while loading shared libraries: libhello.so.0 : cannot open shared object file:
No such file or directory
在執行目標文件的時候,Shell 找不到共享庫的位置,需要我們手工載入庫路徑。
5. shell 搜索動態庫路徑位置的兩種方法
(1) 使用命令導入動態庫的路徑,命令如下:
export LD_LIBRARY_PATH=dir (如/usr/local/lib)
(2) 修改/etc/ld.so.conf 文件,加入搜索路徑,修改後用ldconfig 命令載入修改。
將自己可能存放庫文件的路徑都加入到/etc/ld.so.conf 中是明智的選擇 ^_^。添加
方法也極其簡單,將庫文件的絕對路徑直接寫進去就OK 了,一行一個。例如:
/usr/local/lib
/usr/lib
/lib
需要注意的是:這種搜索路徑的設置方式對於程序連接時的庫(包括共享庫和靜態
庫)的定位已經足夠了,但是對於使用了共享庫的程序的執行還是不夠的。這是 因為
為了加快程序執行時對共享庫的定位速度,避免使用搜索路徑查找共享庫的低效率,所
以是直接讀取庫列表文件 /etc/ld.so.cache 從中進行搜索的。/etc/ld.so.cache 是一個非
文本的數據文件,不能直接編輯,它是根據 /etc/ld.so.conf 中設置的搜索路徑由
/sbin/ldconfig 命令將這些搜索路徑下的共享庫文件集中在一起而生成的(ldconfig 命令
要以 root 許可權執行)。因此,為了保證程序執行時對庫的定位,在 /etc/ld.so.conf 中
進行了庫搜索路徑的設置之後,還必須要運行 /sbin/ldconfig 命令更新 /etc/ld.so.cache
文件之後才可以。ldconfig ,簡單的說,它的作用就是將/etc/ld.so.conf 列出的路徑下的庫
文件 緩存到/etc/ld.so.cache 以供使用。因此當安裝完一些庫文件,(例如剛安裝好glib),
或者修改ld.so.conf 增加新的庫路徑後,需要運行一下/sbin/ldconfig 使所有的庫文件都
被緩存到ld.so.cache 中,如果沒做,即使庫文件明明就在/usr/lib 下的,也是不會被使
用的,結果編譯過程中報錯,缺少xxx 庫,去查看發現明明就在那放著,搞的想大罵
computer 蠢豬一個^_^。極力推薦使用這種方法!
利用gcc 創建和使用動態庫
1. 用下面的命令將mylib.c 程序創建成一個動態庫:
gcc –fPIC –o mylib.o –c mylib.c
gcc –shared –o libtt.so mylib.o
-fPIC 作用於編譯階段,告訴編譯器產生與位置無關代碼(Position-Independent Code),
則產生的代碼中,沒有絕對地址,全部使用相對地址,故而代碼可以被載入器載入到內存的
任意位置,都可以正確的執行。這正是共享庫所要求的,共享庫被載入時,在內存的位置不
是固定的。
-shared 作用於鏈接階段,實際傳遞給鏈接器ld,讓其添加作為共享庫所需要的額外描
述信息,去除共享庫所不需的信息。
也可以直接使用下面一條命令:
gcc –fPIC –shared –o libtt.so mylib.c
2. 將動態庫拷貝到linux 的標准庫中,usr/local/lib 或者/usr/lib 或者/lib:
cp libttt.so /usr/local/lib
3. 編譯src 目錄下的源程序時,指定動態庫文件的目錄,調用動態庫中的函數
gcc –o test test.c /usr/lib/libttt.so
4. 設置shell 動態庫搜索路徑,運行生成的可執行文件。

B. 程序編譯成動態庫能正常運行而靜態庫卻不行!

我感覺問題不太清楚呢,有如下疑問。
1. 樓主是用的BREW4.0或之前的版本來開發的嗎?還是用的最新的Brew MP?
2. 用的模擬器還是下載到設備?
3. 一般不需要自己寫makefile 啊,因為開發brew app有很多固有的框架代碼,這些一般都由IDE上的插件幫忙生成,而且不需要自己構造命令編譯連接的。

我的開發環境是: VC6.0 sp6 + BREW sdk4.0 + ADS1.2 這個可以生成mod下載到手中。
還有另外一個環境:VC2008 + Brew MP 5.0 這個只能在模擬器上測試。

首先,如果不是Brew MP的話,要把程序做成靜態的只能和手機的代碼一起編譯成rom,下載到手機中,這個不能在模擬器上調試。
Brew MP封裝了OEM也就是我們無法直接修改手機代碼,所以它提供了上層編寫靜態程序的方法。
所以有些不太清楚你遇到的是那種情況。

一般來說MALLOC掛掉是分配的太大,這種情況很少,除非我故意去測試,真正開發的時候從來沒有遇到過,而且跟手機代碼一起開發的時候是可以用標准函數malloc的。也可以使用全局變數或靜態變數,動態的不可以。

說到makefile,編譯mod文件一用自己寫,尤其是用VC的時候,brew的插件幫我們寫好了,只要點一下就能進行ARM編譯和鏈接,即使是用ADS來編譯,也不需要自己寫。

有問題再聯系吧

C. 編譯錯誤,如何解決error LNK2001: unresolved external symbol

導致「error LNK2001: unresolved external symbol」的原因為getStats此方法的鏈接庫沒有找到。很可能是工程中引用了第三方開源庫或者自己編譯生成的庫,且只用了頭文件,而沒有將對應的lib文件路徑加入到工程中。

具體解決方法為(此方法針對vs系列集成開發環境):

1.如果還未引入頭文件,那麼可以右鍵點擊項目,然後點擊「屬性」。

D. 升級Xocde10,真機調試,報錯ld: library not found for -licucore,模擬器編譯正常,求大神解答

報錯ld: library not found for -licucore原因是Xcode10升級後某些框架被移除了,解決方法如下:

1、在終端輸入以下命令打開Xcode中的目錄。

E. 關於動態庫 靜態庫 區別與使用 路徑查找等

一、引言

我們通常把一些公用函數製作成函數庫,供其它程序使用。
函數庫分為靜態庫和動態庫兩種。

通常情況下,對函數庫的鏈接是放在編譯時期(compile time)完成的。所有相關的對象文件(object file)與牽涉到的函數庫(library)被鏈接合成一個可執行文件(executable file)。程序在運行時,與函數庫再無瓜葛,因為所有需要的函數已拷貝到相應目錄下下。所以這些函數庫被成為靜態庫(static libaray),通常文件名為「libxxx.a」的形式。

其實,我們也可以把對一些庫函數的鏈接載入推遲到程序運行的時期(runtime)。這就是動態鏈接庫(dynamic link library)技術。

二、兩者區別:
a,靜態庫的使用需要:
1 包含一個對應的頭文件告知編譯器lib文件裡面的具體內容
2 設置lib文件允許編譯器去查找已經編譯好的二進制代碼

b,動態庫的使用:
程序運行時需要載入動態庫,對動態庫有依賴性,需要手動加入動態庫

c,依賴性:
靜態鏈接表示靜態性,在編譯鏈接之後, lib庫中需要的資源已經在可執行程序中了, 也就是靜態存在,沒有依賴性了
動態,就是實時性,在運行的時候載入需要的資源,那麼必須在運行的時候提供 需要的 動態庫,有依賴性, 運行時候沒有找到庫就不能運行了

d,區別:
簡單講,靜態庫就是直接將需要的代碼連接進可執行程序;動態庫就是在需要調用其中的函數時,根據函數映射表找到該函數然後調入堆棧執行。
做成靜態庫可執行文件本身比較大,但不必附帶動態庫
做成動態庫可執行文件本身比較小,但需要附帶動態庫
鏈接靜態庫,編譯的可執行文件比較大,當然可以用strip命令精簡一下(如:strip libtest.a),但還是要比鏈接動態庫的可執行文件大。程序運行時間速度稍微快一點。
靜態庫是程序運行的時候已經調入內存,不管有沒有調用,都會在內存里頭。靜態庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態庫。
其在編譯程序時若鏈接,程序運行時會在系統指定的路徑下搜索,然後導入內存,程序一般執行時間稍微長一點,但編譯的可執行文件比較小;動態庫是程序運行的時候需要調用的時候才裝入內存,不需要的時候是不會裝入內存的。
動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態庫存在。

三、動態鏈接庫的特點與優勢

首先讓我們來看一下,把庫函數推遲到程序運行時期載入的好處:

1. 可以實現進程之間的資源共享。

什麼概念呢?就是說,某個程序的在運行中要調用某個動態鏈接庫函數的時候,操作系統首先會查看所有正在運行的程序,看在內存里是否已有此庫函數的拷貝了。如果有,則讓其共享那一個拷貝;只有沒有才鏈接載入。這樣的模式雖然會帶來一些「動態鏈接」額外的開銷,卻大大的節省了系統的內存資源。C的標准庫就是動態鏈接庫,也就是說系統中所有運行的程序共享著同一個C標准庫的代碼段。

2. 將一些程序升級變得簡單。用戶只需要升級動態鏈接庫,而無需重新編譯鏈接其他原有的代碼就可以完成整個程序的升級。Windows 就是一個很好的例子。

3. 甚至可以真正坐到鏈接載入完全由程序員在程序代碼中控制。

程序員在編寫程序的時候,可以明確的指明什麼時候或者什麼情況下,鏈接載入哪個動態鏈接庫函數。你可以有一個相當大的軟體,但每次運行的時候,由於不同的操作需求,只有一小部分程序被載入內存。所有的函數本著「有需求才調入」的原則,於是大大節省了系統資源。比如現在的軟體通常都能打開若干種不同類型的文件,這些讀寫操作通常都用動態鏈接庫來實現。在一次運行當中,一般只有一種類型的文件將會被打開。所以直到程序知道文件的類型以後再載入相應的讀寫函數,而不是一開始就將所有的讀寫函數都載入,然後才發覺在整個程序中根本沒有用到它們。

靜態庫:在編譯的時候載入生成目標文件,在運行時不用載入庫,在運行時對庫沒有依賴性。
動態庫:在目標文件運行時載入,手動載入,且對庫有依賴性。

具體在開發中用到哪種庫,我覺得還是根據實際的內存大小,ROM大小,運行的速度等綜合考慮。

熱點內容
為什麼安卓手機下載不了微信 發布:2024-11-19 08:19:37 瀏覽:836
android情景分析 發布:2024-11-19 08:19:36 瀏覽:190
系統存儲設備容量 發布:2024-11-19 08:05:28 瀏覽:994
向外訪問 發布:2024-11-19 07:50:21 瀏覽:555
androidbase64圖片 發布:2024-11-19 07:48:45 瀏覽:727
搭建小說網站國外伺服器 發布:2024-11-19 07:42:49 瀏覽:799
在家如何更改網路密碼 發布:2024-11-19 07:36:21 瀏覽:797
反編譯redis里的數據 發布:2024-11-19 07:31:59 瀏覽:858
android音樂播放器的實現 發布:2024-11-19 07:12:44 瀏覽:969
傳奇世界手游打架腳本 發布:2024-11-19 07:05:43 瀏覽:680