ฉันจะเชื่อมโยงไปยังเวอร์ชัน glibc เฉพาะได้อย่างไร


111

เมื่อฉันรวบรวมบางสิ่งบนพีซี Ubuntu Lucid 10.04 ของฉันมันจะเชื่อมโยงกับ glibc Lucid ใช้ glibc 2.11 เมื่อฉันเรียกใช้ไบนารีนี้บนพีซีเครื่องอื่นที่มี glibc รุ่นเก่าคำสั่งล้มเหลวโดยบอกว่าไม่มี glibc 2.11 ...

เท่าที่ฉันรู้ glibc ใช้การกำหนดเวอร์ชันสัญลักษณ์ ฉันบังคับให้ gcc เชื่อมโยงกับเวอร์ชันสัญลักษณ์เฉพาะได้หรือไม่

ในการใช้งานจริงของฉันฉันพยายามรวบรวม gcc cross toolchain สำหรับ ARM


58
นี่เป็นหนึ่งในปัญหาลินุกซ์ที่น่ารำคาญจริงๆเช่นวิธีแก้ปัญหาคือ "คุณไม่ควรทำอย่างนั้น" ซึ่งแน่นอนว่า "ยังใช้ไม่ได้และยังไม่มีใครแก้ไข"
Timmmm

4
มีคนบ่นเรื่อง DLL hell บน Windows ฉันจำได้ว่าผู้สนใจรักลินุกซ์บางคนพยายามหยิบยกสิ่งนั้นมาเป็นตัวอย่างที่น่ากลัวโดยเฉพาะจากโลก Windows เมื่อฉันพบกับการพัฒนา Linux ครั้งแรกในช่วงทศวรรษที่ผ่านมาสิ่งที่ฉันทำคือการฝังใบหน้าของฉันไว้ในมือ
0xC0000022L

คำตอบ:


70

คุณถูกต้องใน glibc นั้นใช้การกำหนดเวอร์ชันสัญลักษณ์ หากคุณมีความอยากรู้อยากเห็นสัญลักษณ์เวอร์ชันการดำเนินการแนะนำใน 2.1 glibc อธิบายไว้ที่นี่และเป็นส่วนขยายของสัญลักษณ์โครงการเวอร์ชันของดวงอาทิตย์ที่อธิบายไว้ที่นี่

ทางเลือกหนึ่งคือการเชื่อมโยงไบนารีของคุณแบบคงที่ นี่อาจเป็นตัวเลือกที่ง่ายที่สุด

คุณยังสามารถสร้างไบนารีของคุณในสภาพแวดล้อมการสร้าง chroot หรือใช้cross-compiler แบบเก่า glibc- new => glibc

ตามhttp://www.trevorpounds.comบล็อกโพสต์การเชื่อมโยงไปยังสัญลักษณ์เวอร์ชันเก่า (glibc)เป็นไปได้ที่จะบังคับให้สัญลักษณ์ใด ๆ เชื่อมโยงกับสัญลักษณ์ที่เก่ากว่าตราบเท่าที่มันถูกต้องโดยใช้.symverหลอกเดียวกัน-op ที่ใช้สำหรับการกำหนดสัญลักษณ์ตามเวอร์ชันในตอนแรก ตัวอย่างต่อไปนี้คัดลอกมาจากบล็อกโพสต์

ตัวอย่างต่อไปนี้ใช้ประโยชน์จาก realpath ของ glibc แต่ตรวจสอบให้แน่ใจว่าเชื่อมโยงกับเวอร์ชัน 2.2.5 ที่เก่ากว่า

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>

__asm__(".symver realpath,realpath@GLIBC_2.2.5");
int main()
{
    const char* unresolved = "/lib64";
    char resolved[PATH_MAX+1];

    if(!realpath(unresolved, resolved))
        { return 1; }

    printf("%s\n", resolved);

    return 0;
}

18
glibc ไม่สนับสนุนการเชื่อมโยงแบบคงที่ - โปรแกรม glibc ที่เชื่อมโยงแบบสแตติกไม่สามารถใช้งานได้กับระบบที่มีเวอร์ชัน libc ต่างกัน
จำ Monica

5
glibc ของlibc.aยังคงอยู่ glibc สนับสนุนในบางกรณีถึงแม้ว่ามันจะไม่แนะนำ (Drepper) คุณจะมีปัญหากับโปรแกรมที่ไม่สำคัญโดยเฉพาะอะไรก็ตามที่ใช้ NSS (วิธีแก้ปัญหาในFAQ )
mr.spuratic

20

การเชื่อมโยงกับ-static เมื่อคุณเชื่อมโยงด้วย-staticตัวเชื่อมโยงจะฝังไลบรารีไว้ในไฟล์ปฏิบัติการดังนั้นไฟล์ปฏิบัติการจะมีขนาดใหญ่ขึ้น แต่สามารถทำงานบนระบบที่มี glibc เวอร์ชันเก่ากว่าได้เนื่องจากโปรแกรมจะใช้ไลบรารีของตัวเองแทนที่จะเป็นของระบบ .


55
บ่อยครั้งเหตุผลที่คุณต้องการทำสิ่งนี้เนื่องจากคุณกำลังแจกจ่ายแอปพลิเคชันแบบปิด ในกรณีนี้มักไม่ได้รับอนุญาตให้เชื่อมโยงแบบคงที่เนื่องจากเหตุผลด้านการอนุญาตให้ใช้สิทธิ์ (การทำเช่นนี้จะทำให้คุณต้องปล่อยซอร์สโค้ดทั้งหมดของคุณ) ดังนั้นคุณต้องระมัดระวังกับ -static
Malvineous

3
ในขณะเดียวกันอย่างน้อยก็สามารถใช้ musl-libc ได้ แต่ด้วยโปรแกรม C ++ สิ่งต่างๆอาจมีความซับซ้อนมากขึ้นดังนั้นการระบุเวอร์ชันสัญลักษณ์อาจจำเป็น
0xC0000022L

16

การตั้งค่า 1: รวบรวม glibc ของคุณเองโดยไม่ต้องใช้ GCC โดยเฉพาะและใช้งานได้

เนื่องจากดูเหมือนว่าจะเป็นไปไม่ได้ที่จะทำเพียงแค่แฮ็กการกำหนดเวอร์ชันสัญลักษณ์เราไปอีกขั้นหนึ่งแล้วรวบรวม glibc ด้วยตัวเอง

การตั้งค่านี้อาจใช้งานได้และรวดเร็วเนื่องจากไม่ได้ทำการคอมไพล์ใหม่ทั้ง GCC toolchain เพียงแค่ glibc

แต่มันไม่น่าเชื่อถือที่จะใช้วัตถุรันไทม์โฮสต์ C เช่นcrt1.o, crti.oและcrtn.oการให้บริการโดย glibc สิ่งนี้กล่าวถึงที่: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_locationวัตถุเหล่านั้นทำการตั้งค่า แต่เนิ่นๆที่ glibc อาศัยอยู่ดังนั้นฉันจะไม่แปลกใจถ้าสิ่งต่างๆล้มเหลวอย่างยอดเยี่ยม และวิธีที่ละเอียดอ่อนอย่างน่ากลัว

สำหรับการตั้งค่าที่เชื่อถือได้มากขึ้นโปรดดูการตั้งค่า 2 ด้านล่าง

สร้าง glibc และติดตั้งในเครื่อง:

export glibc_install="$(pwd)/glibc/build/install"

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j `nproc`
make install -j `nproc`

การตั้งค่า 1: ตรวจสอบการสร้าง

test_glibc.c

#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>

atomic_int acnt;
int cnt;

int f(void* thr_data) {
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
    }
    return 0;
}

int main(int argc, char **argv) {
    /* Basic library version check. */
    printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());

    /* Exercise thrd_create from -pthread,
     * which is not present in glibc 2.27 in Ubuntu 18.04.
     * /programming/56810/how-do-i-start-threads-in-plain-c/52453291#52453291 */
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);
    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

รวบรวมและเรียกใช้ด้วยtest_glibc.sh:

#!/usr/bin/env bash
set -eux
gcc \
  -L "${glibc_install}/lib" \
  -I "${glibc_install}/include" \
  -Wl,--rpath="${glibc_install}/lib" \
  -Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
  -std=c11 \
  -o test_glibc.out \
  -v \
  test_glibc.c \
  -pthread \
;
ldd ./test_glibc.out
./test_glibc.out

โปรแกรมแสดงผลลัพธ์ตามที่คาดไว้:

gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674

คำสั่งที่ดัดแปลงมาจากhttps://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_locationแต่--sysrootทำให้ล้มเหลวด้วย:

cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install

ฉันจึงลบมันออก

lddเอาต์พุตยืนยันว่าlddและไลบรารีที่เราเพิ่งสร้างขึ้นนั้นถูกใช้งานจริงตามที่คาดไว้:

+ ldd test_glibc.out
        linux-vdso.so.1 (0x00007ffe4bfd3000)
        libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
        libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
        /home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)

gccรวบรวมการแก้ปัญหาการส่งออกที่แสดงให้เห็นว่าวัตถุรันไทม์โฮสต์ของฉันถูกนำมาใช้ซึ่งจะไม่ดีตามที่กล่าวไว้ก่อนหน้านี้ แต่ผมไม่ทราบว่าวิธีการทำงานรอบ ๆ เช่นจะมี:

COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o

การตั้งค่า 1: แก้ไข glibc

ตอนนี้เรามาแก้ไข glibc ด้วย:

diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
@@ -16,11 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */

+#include <stdio.h>
+
 #include "thrd_priv.h"

 int
 thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
 {
+  puts("hacked");
   _Static_assert (sizeof (thr) == sizeof (pthread_t),
                   "sizeof (thr) != sizeof (pthread_t)");

จากนั้นคอมไพล์ใหม่และติดตั้ง glibc ใหม่แล้วคอมไพล์ใหม่และรันโปรแกรมของเราใหม่:

cd glibc/build
make -j `nproc`
make -j `nproc` install
./test_glibc.sh

และเราเห็นการhackedพิมพ์ไม่กี่ครั้งตามที่คาดไว้

สิ่งนี้เป็นการยืนยันเพิ่มเติมว่าเราใช้ glibc ที่เรารวบรวมไม่ใช่โฮสต์จริงๆ

ทดสอบบน Ubuntu 18.04

การตั้งค่า 2: การตั้งค่าที่เก่าแก่ของ crosstool-NG

นี้เป็นทางเลือกที่จะติดตั้ง 1 และมันคือการติดตั้งที่ถูกต้องที่สุดที่ผมเคยประสบความสำเร็จมาจนถึงขณะนี้: ทุกอย่างถูกต้องเท่าที่ผมสามารถสังเกตรวมทั้งรันไทม์ C วัตถุเช่นcrt1.o, และcrti.ocrtn.o

ในการตั้งค่านี้เราจะรวบรวมเครื่องมือ GCC เฉพาะเต็มรูปแบบที่ใช้ glibc ที่เราต้องการ

ข้อเสียเพียงอย่างเดียวของวิธีนี้คือการสร้างจะใช้เวลานานขึ้น แต่ฉันจะไม่เสี่ยงกับการตั้งค่าการผลิตที่มีอะไรน้อยกว่านี้

crosstool-NGเป็นชุดของสคริปต์ที่ดาวน์โหลดและรวบรวมทุกอย่างจากแหล่งที่มาสำหรับเรารวมถึง GCC, glibc และ binutils

ใช่ระบบการสร้าง GCC นั้นแย่มากจนเราต้องมีโครงการแยกต่างหากสำหรับสิ่งนั้น

การตั้งค่านี้ไม่สมบูรณ์แบบเนื่องจากcrosstool-NG ไม่รองรับการสร้างไฟล์ปฏิบัติการโดยไม่มี-Wlแฟล็กพิเศษซึ่งรู้สึกแปลก ๆ เนื่องจากเราได้สร้าง GCC ขึ้นมาเอง แต่ดูเหมือนว่าทุกอย่างจะได้ผลดังนั้นนี่เป็นเพียงความไม่สะดวกเท่านั้น

รับ crosstool-NG และกำหนดค่า:

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j `nproc`
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig

ตัวเลือกบังคับเพียงตัวเดียวที่ฉันเห็นคือทำให้ตรงกับเวอร์ชันเคอร์เนลของโฮสต์ของคุณเพื่อใช้ส่วนหัวเคอร์เนลที่ถูกต้อง ค้นหาเวอร์ชันเคอร์เนลของโฮสต์ของคุณด้วย:

uname -a

ซึ่งแสดงให้ฉันเห็น:

4.15.0-34-generic

ดังนั้นในmenuconfigฉัน:

  • Operating System
    • Version of linux

ดังนั้นฉันจึงเลือก:

4.14.71

ซึ่งเป็นเวอร์ชันแรกที่เท่ากันหรือเก่ากว่า จะต้องเก่ากว่าเนื่องจากเคอร์เนลเข้ากันได้แบบย้อนกลับ

ตอนนี้คุณสามารถสร้างด้วย:

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

และตอนนี้รอประมาณสามสิบนาทีถึงสองชั่วโมงเพื่อรวบรวม

การตั้งค่า 2: การกำหนดค่าเพิ่มเติม

สิ่ง.configที่เราสร้างขึ้น./ct-ng x86_64-unknown-linux-gnuมี:

CT_GLIBC_V_2_27=y

หากต้องการเปลี่ยนแปลงให้menuconfigทำ:

  • C-library
  • Version of glibc

บันทึก.configและดำเนินการต่อด้วยการสร้าง

หรือถ้าคุณต้องการที่จะใช้แหล่ง glibc ของคุณเองเช่นการใช้ glibc จากคอมไพล์ล่าสุดดำเนินการเช่นนี้ :

  • Paths and misc options
    • Try features marked as EXPERIMENTAL: ตั้งค่าเป็นจริง
  • C-library
    • Source of glibc
      • Custom location: บอกว่าใช่
      • Custom location
        • Custom source location: ชี้ไปที่ไดเร็กทอรีที่มีแหล่งข้อมูล glibc ของคุณ

ที่ glibc ถูกโคลนเป็น:

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28

การตั้งค่า 2: ทดสอบดู

เมื่อคุณสร้าง toolchain ที่คุณต้องการแล้วให้ทดสอบด้วย:

#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
  x86_64-unknown-linux-gnu-gcc \
  -Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
  -Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
  -v \
  -o test_glibc.out \
  test_glibc.c \
  -pthread \
;
ldd test_glibc.out
./test_glibc.out

ดูเหมือนว่าทุกอย่างจะทำงานเหมือนใน Setup 1 ยกเว้นว่าตอนนี้มีการใช้วัตถุรันไทม์ที่ถูกต้อง:

COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o

การตั้งค่า 2: ความพยายามรวบรวมข้อมูล glibc ใหม่อย่างมีประสิทธิภาพล้มเหลว

ดูเหมือนว่าจะเป็นไปไม่ได้กับ crosstool-NG ดังที่อธิบายไว้ด้านล่าง

หากคุณเพิ่งสร้างใหม่

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

จากนั้นการเปลี่ยนแปลงของคุณในตำแหน่งแหล่งที่มา glibc ที่กำหนดเองจะถูกนำมาพิจารณา แต่จะสร้างทุกอย่างตั้งแต่เริ่มต้นทำให้ไม่สามารถใช้การพัฒนาซ้ำได้

ถ้าเราทำ:

./ct-ng list-steps

มันให้ภาพรวมที่ดีของขั้นตอนการสร้าง:

Available build steps, in order:
  - companion_tools_for_build
  - companion_libs_for_build
  - binutils_for_build
  - companion_tools_for_host
  - companion_libs_for_host
  - binutils_for_host
  - cc_core_pass_1
  - kernel_headers
  - libc_start_files
  - cc_core_pass_2
  - libc
  - cc_for_build
  - cc_for_host
  - libc_post_cc
  - companion_libs_for_target
  - binutils_for_target
  - debug
  - test_suite
  - finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.

ดังนั้นเราจะเห็นว่ามีขั้นตอน glibc พันกับขั้นตอน GCC หลายสะดุดตาที่สุดlibc_start_filesมาก่อนซึ่งมีแนวโน้มที่ขั้นตอนที่แพงที่สุดร่วมกับcc_core_pass_2cc_core_pass_1

ในการสร้างเพียงขั้นตอนเดียวก่อนอื่นคุณต้องตั้งค่าตัวเลือก "บันทึกขั้นตอนกลาง" ใน.configการสร้างขั้นต้น:

  • Paths and misc options
    • Debug crosstool-NG
      • Save intermediate steps

จากนั้นคุณสามารถลอง:

env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j`nproc`

แต่น่าเสียดายที่+จำเป็นตามที่ระบุไว้ที่: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536

อย่างไรก็ตามโปรดสังเกตว่าการรีสตาร์ทในขั้นตอนกลางจะรีเซ็ตไดเร็กทอรีการติดตั้งเป็นสถานะที่มีในระหว่างขั้นตอนนั้น กล่าวคือคุณจะมี libc ที่สร้างขึ้นใหม่ - แต่ไม่มีคอมไพเลอร์สุดท้ายที่สร้างขึ้นด้วย libc นี้ (และด้วยเหตุนี้จึงไม่มีไลบรารีคอมไพเลอร์เช่น libstdc ++ เช่นกัน)

และโดยพื้นฐานแล้วยังคงทำให้การสร้างใหม่ช้าเกินไปที่จะเป็นไปได้สำหรับการพัฒนาและฉันไม่เห็นวิธีที่จะเอาชนะสิ่งนี้ได้โดยไม่ต้องแก้ไข crosstool-NG

นอกจากนี้การเริ่มต้นจากlibcขั้นตอนนี้ดูเหมือนจะไม่ได้คัดลอกแหล่งที่มาอีกCustom source locationเลยทำให้วิธีนี้ใช้ไม่ได้

โบนัส: stdlibc ++

โบนัสหากคุณสนใจไลบรารีมาตรฐาน C ++: จะแก้ไขและสร้างซอร์สไลบรารีมาตรฐาน GCC libstdc ++ C ++ ใหม่ได้อย่างไร


musl-libcเป็นอีกทางเลือกหนึ่งที่เกี่ยวข้องกับรันไทม์ C
0xC0000022L

0

ในความคิดของฉันยังไม่ได้กล่าวถึงวิธีแก้ปัญหาที่ขี้เกียจที่สุด (โดยเฉพาะอย่างยิ่งหากคุณไม่ได้พึ่งพาคุณสมบัติ C / C ++ ที่มีเลือดออกล่าสุดหรือคุณสมบัติคอมไพเลอร์ล่าสุด) ดังนั้นนี่คือ:

เพียงสร้างระบบด้วย GLIBC ที่เก่าที่สุดที่คุณยังต้องการสนับสนุน

จริงๆแล้วสิ่งนี้ทำได้ง่ายมากในปัจจุบันด้วยเทคโนโลยีเช่น chroot หรือ KVM / Virtualbox หรือนักเทียบท่าแม้ว่าคุณจะไม่ต้องการใช้ Distro แบบเก่าโดยตรงบนพีซีเครื่องใดก็ตาม โดยละเอียดในการสร้างไบนารีแบบพกพาสูงสุดของซอฟต์แวร์ของคุณฉันขอแนะนำให้ทำตามขั้นตอนเหล่านี้:

  1. เพียงแค่เลือกพิษของ sandbox / virtualization / ... อะไรก็ได้และใช้มันเพื่อรับ Ubuntu LTS เสมือนรุ่นเก่าและคอมไพล์ด้วย gcc / g ++ ที่มีอยู่ตามค่าเริ่มต้น ซึ่งจะ จำกัด GLIBC ของคุณโดยอัตโนมัติเฉพาะที่มีอยู่ในสภาพแวดล้อมนั้น

  2. หลีกเลี่ยงการขึ้นอยู่กับ libs ภายนอกนอกเหนือจากพื้นฐาน: เช่นคุณควรเชื่อมโยงสิ่งต่างๆของระบบระดับพื้นดินแบบไดนามิกเช่น glibc, libGL, libxcb / X11 / wayland things, libasound / libpulseaudio อาจเป็น GTK + หากคุณใช้สิ่งนั้น แต่ควรเชื่อมโยงภายนอกแบบคงที่ libs / จัดส่งให้ถ้าคุณทำได้ โดยเฉพาะอย่างยิ่ง libs ที่มีอยู่ในตัวส่วนใหญ่เช่นตัวโหลดรูปภาพตัวถอดรหัสมัลติมีเดีย ฯลฯ อาจทำให้เกิดการแตกหักน้อยลงใน Distros อื่น ๆ (อาจเกิดการแตกหักได้เช่นหากมีอยู่ที่ใดที่หนึ่งในเวอร์ชันหลักอื่นเท่านั้น) หากคุณจัดส่งแบบคงที่

ด้วยวิธีการดังกล่าวคุณจะได้รับไบนารีที่เข้ากันได้กับ GLIBC โดยไม่ต้องปรับแต่งสัญลักษณ์ใด ๆ ด้วยตนเองโดยไม่ต้องทำไบนารีแบบคงที่อย่างสมบูรณ์ (ซึ่งอาจทำให้โปรแกรมที่ซับซ้อนมากขึ้นเนื่องจาก glibc เกลียดสิ่งนั้นและอาจทำให้เกิดปัญหาการออกใบอนุญาตสำหรับคุณ) และไม่มีการตั้งค่า เพิ่ม toolchain ที่กำหนดเองสำเนา glibc ที่กำหนดเองหรืออะไรก็ตาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.