《LinuxFromScratch》第三部分:構建LFS系統第六章:安裝基本的系統軟體-6.9.Glibc-2.21

行者武松發表於2017-11-08

           Glibc 軟體包包含了主要的 C 函式庫。這個庫提供了分配記憶體、搜尋目錄、開啟關閉檔案、讀寫檔案、操作字串、模式匹配、基礎演算法等基本程式。

大概編譯時間:
16.3 SBU
所需磁碟空間:
1.1 GB

6.9.1. 安裝 Glibc

[Note]

注意

有些 LFS 之外的軟體包會建議安裝 GNU libiconv 來轉換不同編碼的文字。根據專案主頁(http://www.gnu.org/software/libiconv/)上的說法“這個庫會提供函式
iconv() 的實現,應用於那些沒有這個函式的系統,或者函式實現中不支援
Unicode 轉換的系統。”
Glibc 提供了函式 iconv() 的實現而且支援 Unicode 轉換,所以對於
LFS 系統來說並不需要 libiconv 庫。

有些 Glibc 程式會用到和 FHS 不相容的 /var/db 目錄來儲存它們的執行時資料。打上如下的補丁讓這些程式在 FHS 相容的位置儲存它們的執行時資料。

patch -Np1 -i ../glibc-2.21-fhs-1.patch

Glibc 的編譯系統是自包含的,可以完美安裝,儘管編譯器的配置檔案和連結器仍然指向 /tools。這在 Glibc 安裝前沒法調整,因為如果調整的話 Glibc 的 autoconf 測試將會提示錯誤,不符合我們實現一個乾淨構建的目標。

修正軟體包裡的一個會影響到 32 位架構系統的正規表示式:

sed -e `/ia32/s/^/1:/` 
    -e `/SSE2/s/^1://` 
    -i  sysdeps/i386/i686/multiarch/mempcpy_chk.S

Glibc 文件裡建議在 Glibc 原始碼目錄之外的特定編譯目錄下編譯:

mkdir -v ../glibc-build
cd ../glibc-build

配置 Glibc 準備編譯:

../glibc-2.21/configure    
    --prefix=/usr          
    --disable-profile      
    --enable-kernel=2.6.32 
    --enable-obsolete-rpc

新出現的 configure 選項引數的含義:

--enable-obsolete-rpc

安裝 NIS 和 RPC 相關的標頭檔案,預設是不安裝的;重新編譯 Glibc 時以及一些 BLFS 軟體包需要這些標頭檔案。

編譯軟體包:

make
[Important]

重要

在本小節裡,執行 Glibc 的測試套件是很關鍵的。在任何情況下都不要跳過這個測試。

通常會有一些測試不能通過,但是一般你可以忽略任何下面列出來的失敗項。現在開始測試編譯結果:

make check

你可能會看到一些失敗的測試項。Glibc 的測試套件對宿主系統有一定的依賴。下面是當前版本 LFS 裡最常見的問題:

  • 測試項 tst/tst-cputimer1rt/tst-cpuclock2 已知是通不過的。具體原因還不清楚,不過一些細微的時間問題可能導致這些測試失敗。

  • 如果你係統的 CPU 不是相對較新的 Genuine Intel 或 Authentic AMD 處理器,數學運算測試有時候會失敗。

  • 因為測試的時候還沒有網路,測試項 posix/tst-getaddrinfo4 和 posix/tst-getaddrinfo5 將總是失敗。

  • 其它已知的在某些架構平臺上會失敗的測試項是 malloc/tst-malloc-usable 和 nptl/tst-cleanupx4。

在安裝 Glibc 時會抱怨找不到 /etc/ld.so.conf 檔案,這只是無關緊要的輸出資訊。下面的方式可以避免這個警告:

touch /etc/ld.so.conf

安裝軟體包:

make install

nscd 安裝配置檔案並建立執行時目錄:

cp -v ../glibc-2.21/nscd/nscd.conf /etc/nscd.conf
mkdir -pv /var/cache/nscd

nscd 安裝系統支援檔案:

install -v -Dm644 ../glibc-2.21/nscd/nscd.tmpfiles /usr/lib/tmpfiles.d/nscd.conf
install -v -Dm644 ../glibc-2.21/nscd/nscd.service /lib/systemd/system/nscd.service

上面的命令並沒有安裝可以讓你的電腦用不同語言響應的語言環境。語言環境並不是必須的,只是如果有些語言環境缺失,後續的測試套件可能會跳過一些重要測試用例。

單獨的語言環境可以用 localedef
程式安裝。例如,下面第一個 localedef
命令將 /usr/share/i18n/locales/cs_CZ 字元無關的語言環境定義和
/usr/share/i18n/charmaps/UTF-8.gz 字元表定義組合在一起,並將結果附加到
/usr/lib/locale/locale-archive 檔案末尾。下面的命令將安裝能完美覆蓋測試所需語言環境的最小集合:

mkdir -pv /usr/lib/locale
localedef -i cs_CZ -f UTF-8 cs_CZ.UTF-8
localedef -i de_DE -f ISO-8859-1 de_DE
localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro
localedef -i de_DE -f UTF-8 de_DE.UTF-8
localedef -i en_GB -f UTF-8 en_GB.UTF-8
localedef -i en_HK -f ISO-8859-1 en_HK
localedef -i en_PH -f ISO-8859-1 en_PH
localedef -i en_US -f ISO-8859-1 en_US
localedef -i en_US -f UTF-8 en_US.UTF-8
localedef -i es_MX -f ISO-8859-1 es_MX
localedef -i fa_IR -f UTF-8 fa_IR
localedef -i fr_FR -f ISO-8859-1 fr_FR
localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro
localedef -i fr_FR -f UTF-8 fr_FR.UTF-8
localedef -i it_IT -f ISO-8859-1 it_IT
localedef -i it_IT -f UTF-8 it_IT.UTF-8
localedef -i ja_JP -f EUC-JP ja_JP
localedef -i ru_RU -f KOI8-R ru_RU.KOI8-R
localedef -i ru_RU -f UTF-8 ru_RU.UTF-8
localedef -i tr_TR -f UTF-8 tr_TR.UTF-8
localedef -i zh_CN -f GB18030 zh_CN.GB18030

另外,安裝適合你自己國家、語言和字符集的語言環境。

或者,也可以一次性安裝在 glibc-2.21/localedata/SUPPORTED 檔案裡列出的所有語言環境(包括以上列出的所有語言環境以及其它更多),執行下面這個非常耗時的命令:

make localedata/install-locales

你需要的語言環境幾乎不大可能沒列在 glibc-2.21/localedata/SUPPORTED 檔案中,但如果真的沒有可以使用 localedef 命令建立和安裝。

6.9.2. 配置 Glibc

儘管 Glibc 在檔案 /etc/nsswitch.conf 丟失或損壞的情況下會建立一個預設的,但是我們需要手動該建立檔案,因為 Glibc 的預設檔案在網路環境下工作時有問題。另外,也需要設定一下時區。

執行下面的命令建立一個新檔案 /etc/nsswitch.conf

cat > /etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns myhostname
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

安裝時區資料:

tar -xf ../tzdata2015a.tar.gz

ZONEINFO=/usr/share/zoneinfo
mkdir -pv $ZONEINFO/{posix,right}

for tz in etcetera southamerica northamerica europe africa antarctica  
          asia australasia backward pacificnew systemv; do
    zic -L /dev/null   -d $ZONEINFO       -y "sh yearistype.sh" ${tz}
    zic -L /dev/null   -d $ZONEINFO/posix -y "sh yearistype.sh" ${tz}
    zic -L leapseconds -d $ZONEINFO/right -y "sh yearistype.sh" ${tz}
done

cp -v zone.tab zone1970.tab iso3166.tab $ZONEINFO
zic -d $ZONEINFO -p America/New_York
unset ZONEINFO

zic 命令的含義:

zic -L /dev/null
...

這會建立沒有時間補償的 posix 時區資料。一般將它們同時放在 zoneinfozoneinfo/posix 目錄下。另外需要將 POSIX 時區資料放到 zoneinfo 目錄下,否則很多測試套件會報錯。在嵌入式平臺,如果儲存空間緊張而且你也不準備更新時區,也可以不用 posix 目錄從而節省 1.9MB,但是一些應用程式或測試套件也許會出錯。

zic -L
leapseconds ...

這會建立包含時間補償的 right 時區資料。在嵌入式平臺,空間比較緊張而且你也不打算更新時區或者不需要準確時間,你可以忽略 right 目錄從而節省 1.9MB。

zic ... -p
...

這會建立 posixrules 檔案。我們使用紐約是因為 POSIX 要求夏令時規則與 US 標準一致。

一種確定本地時區的方式是執行下面的指令碼:

tzselect

在詢問了幾個關於位置的問題後,指令碼會輸出所在時區的名字(比如 America/Edmonton)。在 /usr/share/zoneinfo 檔案中也有其它一些可用時區,比如 Canada/EasternEST5EDT,這些時區並沒有被指令碼列出來但也是可以使用的。

然後執行下面的命令建立 /etc/localtime 檔案:

ln -sfv /usr/share/zoneinfo/<xxx> /etc/localtime

將命令中的 <xxx> 替換成你所在實際時區的名字(比如 Canada/Eastern)。

6.9.3. 配置動態庫載入器

預設情況下,動態庫載入器(/lib/ld-linux.so.2)會搜尋目錄 /lib/usr/lib 查詢程式執行時所需的動態庫檔案。不過,如果庫檔案不在 /lib/usr/lib 目錄下,需要把它所在目錄加到 /etc/ld.so.conf 檔案裡,保證動態庫載入器能找到這些庫。通常有兩個目錄包含額外的動態庫,/usr/local/lib/opt/lib,把這兩個目錄加到動態庫載入器的搜尋路徑中。

執行下面的命令建立一個新檔案/etc/ld.so.conf

cat > /etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib

EOF

如果需要的話,動態庫載入器也可以查詢目錄幷包含裡面配置檔案的內容。通常在這個包含目錄下的檔案只有一行字指向庫目錄。執行下面的命令增加這個功能:

cat >> /etc/ld.so.conf << "EOF"
# Add an include directory
include /etc/ld.so.conf.d/*.conf

EOF
mkdir -pv /etc/ld.so.conf.d

6.9.4. Glibc 軟體包內容

安裝的程式:
catchsegv, gencat, getconf, getent,
iconv, iconvconfig, ldconfig, ldd, lddlibc4, locale, localedef,
makedb, mtrace, nscd, pcprofiledump, pldd, rpcgen, sln,
sotruss, sprof, tzselect, xtrace, zdump, 和 zic
安裝的庫:
ld-2.21.so, libBrokenLocale.{a,so},
libSegFault.so, libanl.{a,so}, libc.{a,so}, libc_nonshared.a,
libcidn.so, libcrypt.{a,so}, libdl.{a,so}, libg.a, libieee.a,
libm.{a,so}, libmcheck.a, libmemusage.so, libnsl.{a,so},
libnss_compat.so, libnss_dns.so, libnss_files.so,
libnss_hesiod.so, libnss_nis.so, libnss_nisplus.so,
libpcprofile.so, libpthread.{a,so}, libpthread_nonshared.a,
libresolv.{a,so}, librpcsvc.a, librt.{a,so}, libthread_db.so,
和 libutil.{a,so}
安裝的目錄:
/usr/include/arpa, /usr/include/bits,
/usr/include/gnu, /usr/include/net, /usr/include/netash,
/usr/include/netatalk, /usr/include/netax25,
/usr/include/neteconet, /usr/include/netinet,
/usr/include/netipx, /usr/include/netiucv,
/usr/include/netpacket, /usr/include/netrom,
/usr/include/netrose, /usr/include/nfs, /usr/include/protocols,
/usr/include/rpc, /usr/include/rpcsvc, /usr/include/sys,
/usr/lib/audit, /usr/lib/gconv, /usr/lib/locale,
/usr/libexec/getconf, /usr/share/i18n, /usr/share/zoneinfo,
/var/cache/nscd, 和 /var/lib/nss_db

簡要介紹

catchsegv

可以在程式因為段錯誤終止的時候建立棧呼叫歷史

gencat

生成訊息條目

getconf

顯示檔案系統相關的系統配置變數的值

getent

獲取系統資料庫的內容

iconv

字符集轉換

iconvconfig

建立 iconv 快速載入模組配置檔案

ldconfig

配置動態連結器的執行時環境

ldd

報告某個程式或動態庫所依賴的動態庫。

lddlibc4

協助 ldd 處理某些目標檔案。

locale

輸出當前語言環境的大量資訊

localedef

編譯語言環境規格

makedb

根據輸入的文字建立簡單資料庫

mtrace

讀取並解析記憶體跟蹤檔案,然後用方便人閱讀的格式顯示一個摘要

nscd

一個後臺服務程式,提供最常用名字服務請求的快取

pcprofiledump

輸出個人電腦分析時生成的資訊

pldd

列出執行中程式正在使用的動態共享目標

rpcgen

生成實現遠端程式呼叫(RPC)協議的 C 語言程式碼

sln

一個靜態連結的 ln 程式

sotruss

跟蹤指定命令裡的動態庫函式呼叫

sprof

讀取並顯示共享目標分析資料

tzselect

詢問使用者該系統的地理位置並給出相應的時區描述

xtrace

跟蹤程式執行過程並列印當前執行的函式

zdump

時區資料輸出工具

zic

時區資料編譯工具

ld-2.21.so

用於動態庫執行的輔助程式

libBrokenLocale

Glibc 內部的一個粗暴破解用來修復損壞程式(比如,一些 Motif 應用)。檢視檔案 glibc-2.21/locale/broken_cur_max.c 裡的註釋來了解更多資訊

libSegFault

段錯誤訊號處理函式,catchsegv會用到

libanl

一個非同步名字查詢庫

libc

主要的 C 庫

libcidn

Glibc 內部用於在函式 getaddrinfo() 中處理國際化域名

libcrypt

密碼學函式庫

libdl

動態連結介面函式庫

libg

不包含函式的一個空庫。以前是 g++ 的執行時庫

libieee

連結該模組會強制使用電氣與電子工程師協會(IEEE) 定義的數學函式錯誤處理規則。預設的是 POSIX.1 錯誤處理。

libm

數學運算函式庫

libmcheck

連結這個庫後會開啟記憶體分配檢查

libmemusage

memusage 命令用它來協助收集應用程式裡記憶體使用資訊

libnsl

網路服務函式庫

libnss

名稱服務切換函式庫,包含了解析主機名、使用者名稱、組名、別稱、服務、協議等等的函式。

libpcprofile

包含一些分析函式,用於跟蹤特定原始碼裡的 CPU 時間佔用情況

libpthread

POSIX 執行緒函式庫

libresolv

包含了建立、傳送和解析網際網路域名伺服器封包的函式

librpcsvc

包含了提供雜項 RPC 服務的函式

librt

包含了實現 POSIX.1b 實時擴充套件裡規定的大部分介面的函式

libthread_db

包含了方便構建多執行緒程式除錯工具的函式

libutil

包含各種 Unix 應用程式中用到的“標準” 函式的程式碼


相關文章