1 回答

TA貢獻(xiàn)1943條經(jīng)驗(yàn) 獲得超7個(gè)贊
在 GNU/Linux 上,幾乎所有的 Go 可執(zhí)行文件都屬于這些類別:
那些包括應(yīng)用程序、Go 運(yùn)行時(shí)和 glibc(的一部分)的靜態(tài)鏈接副本。
那些只包含應(yīng)用程序和 Go 運(yùn)行時(shí)的靜態(tài)鏈接,沒有 glibc。
那些只包括應(yīng)用程序和 Go 運(yùn)行時(shí)、靜態(tài)鏈接和動態(tài)鏈接到 glibc 的。
不幸的是,與 Go 相關(guān)的工具通常會混淆這些鏈接模式。依賴 glibc 的主要原因是應(yīng)用程序使用主機(jī)名和用戶查找(功能如getaddrinfo
和getpwuid_r
)。?CGO_ENABLED=0
從src/os/user/cgo_lookup_unix.go
(使用 glibc)等實(shí)現(xiàn)切換到src/os/user/lookup_unix.go
(不使用 glibc)。非 glibc 實(shí)現(xiàn)不使用 NSS,因此提供的功能有些有限(通常不會影響不在 LDAP/Active Directory 中存儲用戶信息的用戶)。
在您的情況下,設(shè)置CGO_ENABLED=0
將您的應(yīng)用程序從第三類移至第二類。(還有其他與 Go 相關(guān)的工具可以構(gòu)建第一種應(yīng)用程序。)非 NSS 查找代碼不是很大,因此二進(jìn)制大小的增加并不顯著。由于 Go 運(yùn)行時(shí)已經(jīng)靜態(tài)鏈接,靜態(tài)鏈接減少的開銷甚至可能導(dǎo)致可執(zhí)行文件大小的凈減少。
這里要考慮的最重要的問題是 NSS、線程和靜態(tài)鏈接在 glibc 中并不是那么好。所有的 Go 程序都是多線程的,(靜態(tài))將 glibc 鏈接到 Go 程序中的原因正是訪問 NSS 函數(shù)。因此,將 Go 程序靜態(tài)鏈接到 glibc 始終是錯誤的做法。它基本上總是?有問題。即使 Go 程序不是多線程的,使用 NSS 函數(shù)的靜態(tài)鏈接程序在運(yùn)行時(shí)也需要與構(gòu)建時(shí)使用的 glibc版本完全相同,因此此類應(yīng)用程序的靜態(tài)鏈接會降低可移植性。
所有這些都是第一類 Go 應(yīng)用程序如此糟糕的原因。使用 生成靜態(tài)鏈接的應(yīng)用程序CGO_ENABLED=0
沒有這些問題,因?yàn)檫@些應(yīng)用程序(第二類)不包含任何 glibc 代碼(以用戶/主機(jī)查找功能的功能減少為代價(jià))。
如果你想創(chuàng)建一個(gè)需要 glibc 的可移植二進(jìn)制文件,你需要動態(tài)鏈接你的應(yīng)用程序(第三種),在你想要支持的最舊的 glibc 系統(tǒng)上。然后應(yīng)用程序?qū)⒃谠?glibc 版本和所有更高版本上運(yùn)行(目前,Go 沒有正確鏈接 libc,所以即使是 glibc 也沒有很強(qiáng)的兼容性保證)。發(fā)行版通常與 ABI 兼容,但它們具有不同版本的 glibc。glibc 竭盡全力確保動態(tài)鏈接到舊版本 glibc 的應(yīng)用程序?qū)⒗^續(xù)在新版本的 glibc 上運(yùn)行,但反之則不然:一旦您將應(yīng)用程序鏈接到特定版本的 glibc,它可能會獲得功能(符號)在舊版本上不可用,因此該應(yīng)用程序?qū)o法與那些舊版本一起使用。
- 1 回答
- 0 關(guān)注
- 151 瀏覽
添加回答
舉報(bào)