這個過程如下
1. 下載源文件、補丁和建立編譯的目錄
2. 建立內核頭文件
3. 建立二進制工具(binutils)
4. 建立初始編譯器(bootstrap gcc)
5. 建立c庫(glibc)
6. 建立全套編譯器(full gcc)
下載源文件、補丁和建立編譯的目錄
1. 選定軟體版本號
選擇軟體版本號時,先看看glibc源代碼中的INSTALL文件。那裡列舉了該版本的glibc編譯時所需的binutils 和gcc的版本號。例如在 glibc-2.2.3/INSTALL 文件中推薦 gcc 用 2.95以上,binutils 用 2.10.1 以上版本。
我選的各個軟體的版本是:
linux-2.4.21+rmk2
binutils-2.10.1
gcc-2.95.3
glibc-2.2.3
glibc-linuxthreads-2.2.3
如果你選的glibc的版本號低於2.2,你還要下載一個叫glibc-crypt的文件,例如glibc-crypt-2.1.tar.gz。 Linux 內核你可以從www.kernel.org 或它的鏡像下載。
Binutils、gcc和glibc你可以從FSF的FTP站點ftp://ftp.gun.org/gnu/ 或它的鏡像去下載。在編譯glibc時,要用到 Linux 內核中的 include 目錄的內核頭文件。如果你發現有變數沒有定義而導致編譯失敗,你就改變你的內核版本號。例如我開始用linux-2.4.25+vrs2,編譯glibc-2.2.3 時報 BUS_ISA 沒定義,後來發現在 2.4.23 開始它的名字被改為 CTL_BUS_ISA。如果你沒有完全的把握保證你改的內核改完全了,就不要動內核,而是把你的 Linux 內核的版本號降低或升高,來適應 glibc。
Gcc 的版本號,推薦用 gcc-2.95 以上的。太老的版本編譯可能會出問題。Gcc-2.95.3 是一個比較穩定的版本,也是內核開發人員推薦用的一個 gcc 版本。
如果你發現無法編譯過去,有可能是你選用的軟體中有的加入了一些新的特性而其他所選軟體不支持的原因,就相應降低該軟體的版本號。例如我開始用 gcc-3.3.2,發現編譯不過,報 as、ld 等版本太老,我就把 gcc 降為 2.95.3。太新的版本大多沒經過大量的測試,建議不要選用。
2. 建立工作目錄
首先,我們建立幾個用來工作的目錄:
在你的用戶目錄,我用的是用戶liang,因此用戶目錄為 /home/liang,先建立一個項目目錄embedded。
$pwd
/home/liang
$mkdir embedded
再在這個項目目錄 embedded 下建立三個目錄 build-tools、kernel 和 tools。
build-tools-用來存放你下載的 binutils、gcc 和 glibc 的源代碼和用來編譯這些源代碼的目錄。
kernel-用來存放你的內核源代碼和內核補丁。
tools-用來存放編譯好的交叉編譯工具和庫文件。
$cd embedded
$mkdir build-tools kernel tools
執行完後目錄結構如下:
$ls embedded
build-tools kernel tools
3. 輸出和環境變數
我們輸出如下的環境變數方便我們編譯。
$export PRJROOT=/home/liang/embedded
$export TARGET=arm-linux
$export PREFIX=$PRJROOT/tools
$export TARGET_PREFIX=$PREFIX/$TARGET
$export PATH=$PREFIX/bin:$PATH
如果你不慣用環境變數的,你可以直接用絕對或相對路徑。我如果不用環境變數,一般都用絕對路徑,相對路徑有時會失敗。環境變數也可以定義在.bashrc文件中,這樣當你logout或換了控制台時,就不用老是export這些變數了。
體系結構和你的TAEGET變數的對應如下表
你可以在通過glibc下的config.sub腳本來知道,你的TARGET變數是否被支持,例如:
$./config.sub arm-linux
arm-unknown-linux-gnu
在我的環境中,config.sub 在 glibc-2.2.3/scripts 目錄下。
網上還有一些 HOWTO 可以參考,ARM 體系結構的《The GNU Toolchain for ARM Target HOWTO》,PowerPC 體系結構的《Linux for PowerPC Embedded Systems HOWTO》等。對TARGET的選取可能有幫助。
4. 建立編譯目錄
為了把源碼和編譯時生成的文件分開,一般的編譯工作不在的源碼目錄中,要另建一個目錄來專門用於編譯。用以下的命令來建立編譯你下載的binutils、gcc和glibc的源代碼的目錄。
$cd $PRJROOT/build-tools
$mkdir build-binutils build-boot-gcc build-gcc build-glibc gcc-patch
build-binutils-編譯binutils的目錄
build-boot-gcc-編譯gcc 啟動部分的目錄
build-glibc-編譯glibc的目錄
build-gcc-編譯gcc 全部的目錄
gcc-patch-放gcc的補丁的目錄
gcc-2.95.3 的補丁有 gcc-2.95.3-2.patch、gcc-2.95.3-no-fixinc.patch 和gcc-2.95.3-returntype-fix.patch,可以從 http://www.linuxfromscratch.org/ 下載到這些補丁。
再將你下載的 binutils-2.10.1、gcc-2.95.3、glibc-2.2.3 和 glibc-linuxthreads-2.2.3 的源代碼放入 build-tools 目錄中
看一下你的 build-tools 目錄,有以下內容:
$ls
binutils-2.10.1.tar.bz2 build-gcc gcc-patch
build-binutls build-glibc glibc-2.2.3.tar.gz
build-boot-gcc gcc-2.95.3.tar.gz glibc-linuxthreads-2.2.3.tar.gz
建立內核頭文件
把你從 www.kernel.org 下載的內核源代碼放入 $PRJROOT /kernel 目錄
進入你的 kernel 目錄:
$cd $PRJROOT /kernel
解開內核源代碼
$tar -xzvf linux-2.4.21.tar.gz
或
$tar -xjvf linux-2.4.21.tar.bz2
小於 2.4.19 的內核版本解開會生成一個 linux 目錄,沒帶版本號,就將其改名。
$mv linux linux-2.4.x
給 Linux 內核打上你的補丁
$cd linux-2.4.21
$patch -p1 < ../patch-2.4.21-rmk2
編譯內核生成頭文件
$make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
你也可以用 config 和 xconfig 來代替 menuconfig,但這樣用可能會沒有設置某些配置文件選項和沒有生成下面編譯所需的頭文件。推薦大家用 make menuconfig,這也是內核開發人員用的最多的配置方法。配置完退出並保存,檢查一下的內核目錄中的 include/linux/version.h 和 include/linux/autoconf.h 文件是不是生成了,這是編譯 glibc 是要用到的,version.h 和 autoconf.h 文件的存在,也說明了你生成了正確的頭文件。
還要建立幾個正確的鏈接
$cd include
$ln -s asm-arm asm
$cd asm
$ln -s arch-epxa arch
$ln -s proc-armv proc
接下來為你的交叉編譯環境建立你的內核頭文件的鏈接
$mkdir -p $TARGET_PREFIX/include
$ln -s $PRJROOT/kernel/linux-2.4.21/include/linux $TARGET_PREFIX/include/linux
$in -s $PRJROOT/kernel/linux-2.4.21/include/asm-arm $TARGET_PREFIX/include/asm
也可以把 Linux 內核頭文件拷貝過來用
$mkdir -p $TARGET_PREFIX/include
$cp -r $PRJROOT/kernel/linux-2.4.21/include/linux $TARGET_PREFIX/include
$cp -r $PRJROOT/kernel/linux-2.4.21/include/asm-arm $TARGET_PREFIX/include
建立二進制工具(binutils)
binutils是一些二進制工具的集合,其中包含了我們常用到的as和ld。
首先,我們解壓我們下載的binutils源文件。
$cd $PRJROOT/build-tools
$tar -xvjf binutils-2.10.1.tar.bz2
然後進入build-binutils目錄配置和編譯binutils。
$cd build-binutils
$../binutils-2.10.1/configure --target=$TARGET --prefix=$PREFIX
--target 選項是指出我們生成的是 arm-linux 的工具,--prefix 是指出我們可執行文件安裝的位置。
會出現很多 check,最後產生 Makefile 文件。
有了 Makefile 後,我們來編譯並安裝 binutils,命令很簡單。
$make
$make install
看一下我們 $PREFIX/bin 下的生成的文件
$ls $PREFIX/bin
arm-linux-addr2line arm-linux-gasp arm-linux-objmp arm-linux-strings
arm-linux-ar arm-linux-ld arm-linux-ranlib arm-linux-strip
arm-linux-as arm-linux-nm arm-linux-readelf
arm-linux-c++filt arm-linux-obj arm-linux-size
我們來解釋一下上面生成的可執行文件都是用來干什麼的
add2line - 將你要找的地址轉成文件和行號,它要使用 debug 信息。
Ar-產生、修改和解開一個存檔文件
As-gnu 的匯編器
C++filt-C++ 和 java 中有一種重載函數,所用的重載函數最後會被編譯轉化成匯編的標號,c++filt 就是實現這種反向的轉化,根據標號得到函數名。
Gasp-gnu 匯編器預編譯器。
Ld-gnu 的連接器
Nm-列出目標文件的符號和對應的地址
Obj-將某種格式的目標文件轉化成另外格式的目標文件
Objmp-顯示目標文件的信息
Ranlib-為一個存檔文件產生一個索引,並將這個索引存入存檔文件中
Readelf-顯示 elf 格式的目標文件的信息
Size-顯示目標文件各個節的大小和目標文件的大小
Strings-列印出目標文件中可以列印的字元串,有個默認的長度,為4
Strip-剝掉目標文件的所有的符號信息
建立初始編譯器(bootstrap gcc)
首先進入 build-tools 目錄,將下載 gcc 源代碼解壓
$cd $PRJROOT/build-tools
$tar -xvzf gcc-2.95.3.tar.gz
然後進入 gcc-2.95.3 目錄給 gcc 打上補丁
$cd gcc-2.95.3
$patch -p1< ../gcc-patch/gcc-2.95.3.-2.patch
$patch -p1< ../gcc-patch/gcc-2.95.3.-no-fixinc.patch
$patch -p1< ../gcc-patch/gcc-2.95.3-returntype-fix.patch
echo timestamp > gcc/cstamp-h.in
在我們編譯並安裝 gcc 前,我們先要改一個文件 $PRJROOT/gcc/config/arm/t-linux,把
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC
這一行改為
TARGET_LIBGCC2-CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h
你如果沒定義 -Dinhibit,編譯時將會報如下的錯誤
http://www.cnblogs.com/gcc-2.95.3/gcc/libgcc2.c:41: stdlib.h: No such file or directory
http://www.cnblogs.com/gcc-2.95.3/gcc/libgcc2.c:42: unistd.h: No such file or directory
make[3]: *** [libgcc2.a] Error 1
make[2]: *** [stmp-multilib-sub] Error 2
make[1]: *** [stmp-multilib] Error 1
make: *** [all-gcc] Error 2
『貳』 SUSE Linux 11下glibc依賴問題
0.以下在系統CentOS 6.3 x86_64上操作
1.試圖運行程序,提示"libc.so.6: version `GLIBC_2.14' not found",原因是系統的glibc版本太低,軟體編譯時使用了較高版本的glibc引起的:
[cpp]view plain
[ghui@StuOSbin]$pwd
/var/VMdisks/cross/mingw32/bin
[ghui@StuOSbin]$ls
lreleaseQtCore4.dllQtNetwork4.dllQtSql4.dllQtXml4.dll
mocQtDeclarative4.dllQtOpenGL4.dllQtSvg4.dllrcc
phonon4.dllQtGui4.dllQtScript4.dllQtTest4.dlluic
qmakeQtMultimedia4.dllQtScriptTools4.dllQtWebKit4.dll
[ghui@StuOSbin]$./qmake
./qmake:/lib64/libc.so.6:version`GLIBC_2.14'notfound(requiredby./qmake)
2.查看系統glibc支持的版本:
[cpp]view plain
[ghui@StuOSbin]$strings/lib64/libc.so.6|grepGLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_PRIVATE
[cpp]view plain
[ghui@StuOSbin]$rpm-qa|grepglibc
glibc-static-2.12-1.80.el6_3.6.x86_64
glibc-headers-2.12-1.80.el6_3.6.x86_64
glibc-common-2.12-1.80.el6_3.6.x86_64
glibc-devel-2.12-1.80.el6_3.6.x86_64
glibc-static-2.12-1.80.el6_3.6.i686
glibc-devel-2.12-1.80.el6_3.6.i686
glibc-2.12-1.80.el6_3.6.i686
glibc-2.12-1.80.el6_3.6.x86_64
3.可以看到最高只支持2.12版本,所以考慮編譯解決這個問題:
a. 到下載最新版本,我這里下載了glibc-2.14.tar.xz這個版本,解壓到任意目錄准備編譯
b.這里解壓到/var/VMdisks/glibc-2.14/
[cpp]view plain
[ghui@StuOSbin]$cd/var/VMdisks/glibc-2.14/
[[email protected]]$pwd
/var/VMdisks/glibc-2.14
[[email protected]]$ls
abilistconfig.h.inintlREADME.libm
abi-tagsconfig.logioresolv
aclocal.m4config.make.inlibc-abisresource
aoutconfigurelibidnrt
argpconfigure.inlibioRules
assertconformLICENSESscripts
autom4te.cacheCONFORMANCElocalesetjmp
bitsCOPYINGlocaledatashadow
BUGSCOPYING.LIBloginshlib-versions
buildcppflags-iterator.mkmachsignal
CANCEL-FCT-WAIVEcryptMakeconfigsocket
CANCEL-FILE-WAIVEcsuMakefilesoft-fp
catgetsctypeMakefile.instdio-common
ChangeLogdebugMakerulesstdlib
ChangeLog.1direntmallocstreams
ChangeLog.10dlfcnmanualstring
ChangeLog.11elfmathsunrpc
ChangeLog.12extra-lib.mkmiscsysdeps
ChangeLog.13extra-moles.mkNAMESPACEsysvipc
ChangeLog.14FAQNEWStermios
ChangeLog.15FAQ.innistest-skeleton.c
ChangeLog.16gmonNOTEStime
ChangeLog.17gnulibnptltimezone
ChangeLog.2grpnptl_dbtls.make.c
ChangeLog.3gshadownscdversion.h
ChangeLog.4hesiodnssVersions.def
ChangeLog.5hurdo-iterator.mkwcsmbs
ChangeLog.6iconvpowctype
ChangeLog.7iconvdataposixWUR-REPORT
ChangeLog.8includePROJECTS
ChangeLog.9inetpwd
confINSTALLREADME
c.在glibc源碼目錄建立構建目錄,並cd進入構建目錄
[cpp]view plain
[[email protected]]$mkdirbuild
[cpp]view plain
[[email protected]]$cdbuild
d.運行configure配置,make && sudo make install
[cpp]view plain
[ghui@StuOSbuild]$../configure--prefix=/opt/glibc-2.14
[ghui@StuOSbuild]$make-j4
[ghui@StuOSbuild]$sudomakeinstall
[sudo]passwordforghui:
4.臨時修改環境變數
[cpp]view plain
[ghui@StuOSbin]$exportLD_LIBRARY_PATH=/opt/glibc-2.14/lib:$LD_LIBRARY_PATH
[cpp]view plain
[[email protected]]$cd/var/VMdisks/cross/mingw32/bin/
[cpp]view plain
[ghui@StuOSbin]$./qmake
Usage:./qmake[mode][options][files]
QMakehastwomodes,
someheuristics,.Normallyyou
shouldn'tneedtospecifyamode,
modeforqmake,
...
此時運行正常,問題解決。
By ghui
00:10 - 2013-01-04
『叄』 Linux中如何升級glibc
從www.kernel.org/pub/linux/glibc/下載glibc的軟體包,用rpm命令安裝即可。
『肆』 linux編譯glibc,一直報錯
redhat的gcc可能打過patch,glibc編譯未必能成功
參考lfs的做法:編譯binutils和gcc,用它們來編譯glibc
『伍』 哪位大神簡要介紹一下Linux如何安全升級glibc我在debian下成功編譯了新版本的glibc
你可以借鑒一下gentoo的升級思路,因為gentoo都是源代碼編譯的
首先編譯核心工具組(gcc, ld, binutils),注意使用靜態編譯(--disable-shared),安裝到指定的位置(--with-sysroot --with-local-prefix)
然後chroot到那個位置編譯glibc並安裝
然後使用新的glibc靜態編譯核心工具組,chroot回去,覆蓋安裝回原來的地方
用此工具組再次本地編譯glibc
『陸』 Linux開發必知內容整理 | libc、glibc和glib的關系
在進行Linux開發不可避免的要調用一些系統的API,我們經常開到的概念有諸如glibc、libc和glib等等。那麼這些系統庫之前的關系是什麼樣的呢?下面我帶大家了解一下這些庫之前的共同點和差異,希望對以後的編程開發提供幫助。
glibc 和 libc 都是 Linux 下的C函數庫。libc是Linux下的ANSI C函數庫;glibc 是 Linux 下的 GUN C函數庫。
那麼ANSI C和GNU C有什麼區別呢?
ANSI C函數庫是基本的C語言函數庫,包含了C語言最基本的庫函數。這個庫可以根據頭文件劃分為 15 個部分,其中包括:
GNU C函數庫是一種類似於第三方插件的東西。由於 Linux 是用C語言寫的,所以Linux的一些操作是用C語言實現的。因此,GUN 組織開發了一個 C 語言的庫以便讓我們更好的利用 C 語言開發基於 Linux 操作系統的程序。不過現在的不同的 Linux 的發行版本對這兩個函數庫有不同的處理方法,有的可能已經集成在同一個庫里了。
查看當前系統的 glibc 版本的方法:
通過執行libc.so.6
切換到libc.so.6所在的目錄,執行如下命令。
執行ldd命令
錯誤觀點: GLib 前面有個"g",所以認為glib是GNU的東東;同時認為glibc是 GLib 的一個子集。其實,glib和glibc 基本上沒有太大聯系,可能唯一的共同點就是,其都是C編程需要調用的庫而已。
GLib 是Gtk+庫和Gnome的基礎。 GLib 是一個跨平台的、用C語言編寫的五個底層庫的集合,為GNOME所使用。其支持的平台包括Linux、Unix和Windows 等。 GLib 為許多標準的、常用的C語言結構提供了相應的替代物。GLib中包含了近二十種實用功能,從簡單的字元處理到初學者很難理解的XML解析功能。
官方說明
關於Glib的官方說明:
關於Glibc的官方說明
libc 實際上是一個泛指。凡是符合實現了C標准規定的內容,都是一種 libc 。
glibc是GNU組織對libc的一種實現。它是unix/linux的根基之一。
微軟也有自己的libc實現,叫msvcrt 。
嵌入式行業里還常用uClibc ,是一個迷你版的libc 。
『柒』 linux下如何編譯源碼包或者說是安裝
1、安裝編碼源碼的編譯工具,一般是需要安裝gcc
yum install gcc
2、把源碼解壓
tar zxvf uname.tar.gz
3、進入解壓的目錄執行
./configure
make
make install
完成編譯安裝