linux編譯鏈接
靜態庫不能被打包到.o 文件 在C編譯中, 是.c編譯成.o,然後若干個.o打包成.a .a要比.o高一級的。 所以不能產生新的.o 你可以把.a文件解開 成為.o集合 加上你的.o文件, 共同打包成一個新的.a文件 這樣是可行的。
⑵ linux 編譯怎麼連接動態庫
Linux的動態庫文件是以lib字樣開頭的.so文件,編譯鏈接動態庫有兩個要點:一個是需要用-L選項指定動態庫的搜索路徑,這個搜索路徑是需要連接的so文件的大致路徑,比如/usr/openssl/lib;另外還需要用-l(這個是小寫的L)選項指定動態庫的名字,比如下面這條編譯命令:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
⑶ linux下c語言gcc編譯的時候如果不知道.c文件怎麼鏈接的
有以下步驟:
1.源程序的編譯
在Linux下面,如果要編譯一個C語言源程序,我們要使用GNU的gcc編譯器. 下面
我們以一個實例來說明如何使用gcc編譯器.
假設我們有下面一個非常簡單的源程序(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux\n");
}
要編譯這個程序,我們只要在命令行下執行:
gcc -o hello hello.c
gcc 編譯器就會為我們生成一個hello的可執行文件.執行./hello就可以看到程
序的輸出結果了.命令行中 gcc表示我們是用gcc來編譯我們的源程序,-o 選項表示
我們要求編譯器給我們輸出的可執行文件名為hello 而hello.c是我們的源程序文件.
gcc編譯器有許多選項,一般來說我們只要知道其中的幾個就夠了. -o選項我們
已經知道了,表示我們要求輸出的可執行文件名. -c選項表示我們只要求編譯器輸出
目標代碼,而不必要輸出可執行文件. -g選項表示我們要求編譯器在編譯的時候提
供我們以後對程序進行調試的信息.
知道了這三個選項,我們就可以編譯我們自己所寫的簡單的源程序了,如果你
想要知道更多的選項,可以查看gcc的幫助文檔,那裡有著許多對其它選項的詳細說
明.
2.Makefile的編寫
假設我們有下面這樣的一個程序,源代碼如下:
#include "mytool1.h"
#include "mytool2.h"
int main(int argc,char **argv)
{
mytool1_print("hello");
mytool2_print("hello");
}
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif
#include "mytool1.h"
void mytool1_print(char *print_str)
{
printf("This is mytool1 print %s\n",print_str);
}
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif
#include "mytool2.h"
void mytool2_print(char *print_str)
{
printf("This is mytool2 print %s\n",print_str);
}
當然由於這個程序是很短的我們可以這樣來編譯
gcc -c main.c
gcc -c mytool1.c
gcc -c mytool2.c
gcc -o main main.o mytool1.o mytool2.o
這樣的話我們也可以產生main程序,而且也不時很麻煩.但是如果我們考慮一
下如果有一天我們修改了其中的一個文件(比如說mytool1.c)那麼我們難道還要重
新輸入上面的命令?也許你會說,這個很容易解決啊,我寫一個SHELL腳本,讓她幫我
去完成不就可以了.是的對於這個程序來說,是可以起到作用的.但是當我們把事情
想的更復雜一點,如果我們的程序有幾百個源程序的時候,難道也要編譯器重新一
個一個的去編譯?
為此,聰明的程序員們想出了一個很好的工具來做這件事情,這就是make.我們
只要執行以下make,就可以把上面的問題解決掉.在我們執行make之前,我們要先
編寫一個非常重要的文件.--Makefile.對於上面的那個程序來說,可能的一個
Makefile的文件是:
# 這是上面那個程序的Makefile文件
main:main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
gcc -c main.c
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c
有了這個Makefile文件,不過我們什麼時候修改了源程序當中的什麼文件,我們
只要執行make命令,我們的編譯器都只會去編譯和我們修改的文件有關的文件,其
它的文件她連理都不想去理的.
下面我們學習Makefile是如何編寫的.
在Makefile中也#開始的行都是注釋行.Makefile中最重要的是描述文件的依賴
關系的說明.一般的格式是:
target: components
TAB rule
第一行表示的是依賴關系.第二行是規則.
比如說我們上面的那個Makefile文件的第二行
main:main.o mytool1.o mytool2.o
表示我們的目標(target)main的依賴對象(components)是main.o mytool1.o
mytool2.o 當倚賴的對象在目標修改後修改的話,就要去執行規則一行所指定的命
令.就象我們的上面那個Makefile第三行所說的一樣要執行 gcc -o main main.o
mytool1.o mytool2.o 注意規則一行中的TAB表示那裡是一個TAB鍵
Makefile有三個非常有用的變數.分別是$@,$^,$<代表的意義分別是:
$@--目標文件,$^--所有的依賴文件,$<--第一個依賴文件.
如果我們使用上面三個變數,那麼我們可以簡化我們的Makefile文件為:
# 這是簡化後的Makefile
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
main.o:main.c mytool1.h mytool2.h
gcc -c $<
mytool1.o:mytool1.c mytool1.h
gcc -c $<
mytool2.o:mytool2.c mytool2.h
gcc -c $<
經過簡化後我們的Makefile是簡單了一點,不過人們有時候還想簡單一點.這里
我們學習一個Makefile的預設規則
⑷ linux中編譯鏈接出現了錯誤,但本人看不明白,錯誤信息請
首先你要了解編譯的步驟,因為.c或(.cpp文件)文件是分離編譯的,所以每個.c(或.cpp文件)編譯的時候會存在一些對定義在其它.c文件的引用,但是編譯起並不負責重定義這些引用,所以最後還要連接器。連接器把每個.c裡面沒有確定的變數的未定義符號重新定義,最後才產生出一個正確的可執行文件。
但是如果其它文件也沒有定義那些符號的話,則會產生一個連接錯誤,而編譯起顯示的時候多半是說undefined reference.
看你這個程序,應該是某個變數沒有定義,或者是定義域的問題。
⑸ 編譯LINUX內核時為什麼總是要建一個鏈接文件夾,鏈接到內核源碼文件夾
習慣而已。
很多需要內核提供編譯函數、參數支持的軟體,都習慣到固定的地方去尋找內核源代碼。而不是讓你去設置。
相對來說,這樣軟體之間的兼容和交互會更方便。
內核在安裝完後,有的時候他會在 /lib/moles/<Kernel Ver>/ 裡面做一個到內核源代碼地址的鏈接。但這樣如果意外刪掉了源代碼,這個鏈接就會指向錯誤的地方。
所以很多時候,直接去某個特殊位置找源代碼更好,而且有的時候計算機必須先用另外一個內核啟動計算機後給新的內核編譯驅動模塊。這樣的話,因為內核版本不同,會導致不能正確找到目標內核的版本和源代碼位置。
這個時候一個約定俗成的鏈接地址,可以解決很大的問題。
⑹ linux 編譯鏈接
鏈接有問題是找不到庫文件 將庫的路徑加到/etc/ld.so.conf裡面就行了 再ldconfig一下
⑺ linux編譯時怎麼鏈接dl文件
有以下步驟:
1.源程序的編譯
在Linux下面,如果要編譯一個C語言源程序,我們要使用GNU的gcc編譯器.
下面
我們以一個實例來說明如何使用gcc編譯器.
假設我們有下面一個非常簡單的源程序(hello.c):
int
main(int
argc,char
**argv)
{
printf("Hello
Linux\n");
}
要編譯這個程序,我們只要在命令行下執行:
gcc
-o
hello
hello.c
gcc
編譯器就會為我們生成一個hello的可執行文件.執行./hello就可以看到程
序的輸出結果了.命令行中
gcc表示我們是用gcc來編譯我們的源程序,-o
選項表示
我們要求編譯器給我們輸出的可執行文件名為hello
而hello.c是我們的源程序文件.
gcc編譯器有許多選項,一般來說我們只要知道其中的幾個就夠了.
-o選項我們
已經知道了,表示我們要求輸出的可執行文件名.
-c選項表示我們只要求編譯器輸出
目標代碼,而不必要輸出可執行文件.
-g選項表示我們要求編譯器在編譯的時候提
供我們以後對程序進行調試的信息.
知道了這三個選項,我們就可以編譯我們自己所寫的簡單的源程序了,如果你
想要知道更多的選項,可以查看gcc的幫助文檔,那裡有著許多對其它選項的詳細說
明.
2.Makefile的編寫
假設我們有下面這樣的一個程序,源代碼如下:
⑻ linux C語言 編譯鏈接庫的問題
編譯環境和運行環境經常是不同的,在A機編譯,B機運行。
你看到了,編譯時候是 -L指定,運行時是LD_LIBRARY_PATH指定
⑼ linux下gcc編譯時如何連接到mraa庫
-l參數就是用來指定程序要鏈接的庫,-l參數緊接著就是庫名,那麼庫名跟真正的庫文件名有什麼關系呢?就拿數學庫來說,他的庫名是m,他的庫文件名是libm.so,很容易看出,把庫文件名的頭lib和尾.so去掉就是庫名了。當我們自已要用到一個第三方提供的庫名字libtest.so,那麼我們只要把libtest.so拷貝到/usr/lib里,編譯時加上-ltest參數,我們就能用上libtest.so庫了(當然要用libtest.so庫里的函數,我們還需要與libtest.so配套的頭文件)。
放在/lib和/usr/lib和/usr/local/lib里的庫直接用-l參數就能鏈接了,但如果庫文件沒放在這三個目錄里,而是放在其他目錄里,這時我們只用-l參數的話,鏈接還是會出錯,出錯信息大概是:「/usr/bin/ld: cannot find -lxxx」,也就是鏈接程序ld在那3個目錄里找不到libxxx.so,這時另外一個參數-L就派上用場了,比如常用的X11的庫,它在/usr/X11R6/lib目錄下,我們編譯時就要用-L/usr/X11R6/lib -lX11參數,-L參數跟著的是庫文件所在的目錄名。再比如我們把libtest.so放在/aaa/bbb/ccc目錄下,那鏈接參數就是-L/aaa/bbb/ccc -ltest,另外,大部分libxxxx.so只是一個鏈接,以RH9為例,比如libm.so它鏈接到/lib/libm.so.x,/lib/libm.so.6又鏈接到/lib/libm-2.3.2.so,如果沒有這樣的鏈接,還是會出錯,因為ld只會找libxxxx.so,所以如果你要用到xxxx
庫,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一個鏈接就可以了ln -s libxxxx-x.x.x.so libxxxx.so,手工來寫鏈接參數總是很麻煩的,還好很多庫開發包提供了生成鏈接參數的程序,名字一般叫xxxx-config,一般放在/usr/bin目錄下,比如gtk1.2的鏈接參數生成程序是gtk-config,執行gtk-config --libs就能得到以下輸出"-
L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmole -lglib -ldl -lXi -lXext -lX11 -lm",這就是編譯一個gtk1.2程序所需的gtk鏈接參數,xxx-config除了--libs參數外還有一個參數是--cflags用來生成頭文
件包含目錄的,也就是-I參數,在下面我們將會講到。你可以試試執行gtk-config --libs --cflags,看看輸出結果現在的問題就是怎樣用這些輸出結果了,最笨的方法就是復制粘貼或者照抄,聰明的辦
法是在編譯命令行里加入這個`xxxx-config --libs --cflags`,比如編譯一個gtk程序:gcc gtktest.c `gtk-config --libs --cflags`這樣就差不多了。注意`不是單引號,而是1鍵左邊那個鍵。
除了xxx-config以外,現在新的開發包一般都用pkg-config來生成鏈接參數,使用方法跟xxx-config類似,但xxx-config是針對特定的開發包,但pkg-config包含很多開發包的鏈接參數的生成,用pkg-config --list-all命令可以列出所支持的所有開發包,pkg-config的用法就是pkg -config pagName --libs --cflags,其中pagName是包名,是pkg-config--list-all里列出名單中的一個,比如gtk1.2的名字就是gtk+,pkg- config gtk+ --libs --cflags的作用跟gtk-config --libs --cflags是一樣的。比如:gcc gtktest.c `pkg-config gtk+ --libs --cflags`。