이 문서는 다음 환경에서 발생하는 링크 에러를 해결하기 위한 현실적인 우회책을 설명합니다.
- OS: Ubuntu 24.04 (glibc 2.39 계열)
- EDA: Cadence Xcelium 24.09 (또는 비슷한 버전)
- 툴체인: Xcelium에 번들된
cdsgcc/gcc/9.3(binutils 2.34 포함)
증상은 대략 이런 형태입니다:
ld: /lib/x86_64-linux-gnu/libm.so.6: unknown type [0x13] section `.relr.dyn'
ld: skipping incompatible /lib/x86_64-linux-gnu/libm.so.6 when searching for /lib/x86_64-linux-gnu/libm.so.6
ld: cannot find /lib/x86_64-linux-gnu/libm.so.6
ld: /lib/x86_64-linux-gnu/libmvec.so.1: unknown type [0x13] section `.relr.dyn'
ld: skipping incompatible /lib/x86_64-linux-gnu/libmvec.so.1 when searching for /lib/x86_64-linux-gnu/libmvec.so.1
ld: cannot find /lib/x86_64-linux-gnu/libmvec.so.1
collect2: error: ld returned 1 exit status
주로 xmsc_run 이 librun.so 같은 DPI 공유 라이브러리를 생성할 때 터집니다.
한 줄로 요약하면:
옛날 binutils(2.34)
ld가 최신 glibc(2.39)의.relr.dyn섹션을 이해 못해서 링크에 실패하는 상황
조금 더 풀어 설명하면:
-
Ubuntu 24.04의 glibc 2.39는
- 새로운 relocation 형식인 SHT_RELR /
.relr.dyn섹션을 사용합니다.
- 새로운 relocation 형식인 SHT_RELR /
-
Cadence에 번들된
cdsgcc/gcc/9.3안의ld(binutils 2.34)는- 이 섹션 타입(0x13, SHT_RELR)을 모릅니다.
- 그래서 “unknown type [0x13] section
.relr.dyn” 경고 후 라이브러리를 “incompatible”로 취급하고 버립니다.
-
결국
libm.so.6/libmvec.so.1를 찾지 못했다며 링크가 깨지고, 그 여파로librun.so빌드가 실패합니다.
이걸 “glibc를 다운그레이드”하거나 “LD_LIBRARY_PATH로 다른 libc를 끼워 넣어서” 해결하려 하면, bash / python / ls 등 시스템 전체가 GLIBC 버전 mismatch 지옥에 빠지기 때문에 절대 권장되지 않습니다.
우리가 실제로 성공했던 전략은 아주 좁은 지점을 정확히 우회하는 방식입니다:
Xcelium이 사용하는
ld만 “시스템 ld(2.42)”로 바꿔치기하고, 나머지 환경은 그대로 둔다.
즉,
-
/usr/bin/ld(Ubuntu 24.04 기본 binutils 2.42)는- glibc 2.39와 같이 배포된 것이므로
.relr.dyn을 이해합니다.
- glibc 2.39와 같이 배포된 것이므로
-
Cadence의
cdsgcc디렉토리 안에 있는ld실행 파일을- wrapper 스크립트로 바꿔서
- 내부적으로 항상
/usr/bin/ld를 호출하게 만듭니다.
-
이 과정에서:
LD_LIBRARY_PATH에서 Cadence 자체cdsgcc/gcc/9.3/install/lib64경로만 제거해- 오래된
libctf등과의 버전 충돌도 피합니다.
중요한 점:
- 시스템의 glibc / binutils / 패키지는 건드리지 않습니다.
- LD_LIBRARY_PATH, LIBRARY_PATH를 전역으로 바꾸지 않습니다.
- 오직 Cadence 내부
ld파일 2개만 수정합니다.
lsb_release -a # Ubuntu 24.04.x 인지 확인
ldd --version # glibc version, 보통 첫 줄에 2.39처럼 나옴
ld --version # GNU ld (GNU Binutils for Ubuntu) 2.42 ... 이런 식보통 Xcelium 설치 경로 아래에 다음 두 디렉토리가 있습니다:
# 예시 (사용자 환경에 맞게 경로 확인)
cd /home/<user>/cadence/installs/XCELIUM2409
ls tools/cdsgcc/gcc/9.3/bin
ls tools.lnx86/cdsgcc/gcc/9.3/bin둘 다 안에 gcc, g++, ld 등이 있을 겁니다.
아래는 위험하지 않은 순서로 정리한 단계입니다. (시스템 전역 환경 변수는 건드리지 않습니다.)
이전에 LD_LIBRARY_PATH, LIBRARY_PATH 등을 만졌었다면, 새로운 쉘에서 시작하거나 한 번 정리해 줍니다:
unset LD_LIBRARY_PATH
unset LIBRARY_PATH
unset XCELIUM_COMPAT_ROOT이후:
which ld
ld --version
# → /usr/bin/ld, GNU ld 2.42 ... 가 나오는지 확인- 디렉토리 이동:
cd /home/<user>/cadence/installs/XCELIUM2409/tools.lnx86/cdsgcc/gcc/9.3/bin- 기존 ld 백업:
[ -f ld ] && mv ld ld.cadence-2.34주의:
ld.cadence-2.34라는 이름은 예시입니다. 다른 이름을 쓰셔도 되지만, 나중에 복구할 때를 위해 “원본 ld”라는 걸 알아볼 수 있게 두는 게 좋습니다.
- 새로운
ldwrapper 스크립트 생성:
cat > ld << 'EOF'
#!/bin/sh
# Xcelium ld wrapper - delegate to system /usr/bin/ld on Ubuntu 24.04
# and drop Cadence's internal cdsgcc runtime lib dir from LD_LIBRARY_PATH
# to avoid libctf / glibc version conflicts.
if [ -n "$LD_LIBRARY_PATH" ]; then
CLEAN=$(printf '%s\n' "$LD_LIBRARY_PATH" | tr ':' '\n' \
| grep -v 'cdsgcc/gcc/9\.3/install/lib64' \
| paste -sd:)
export LD_LIBRARY_PATH="$CLEAN"
fi
exec /usr/bin/ld "$@"
EOF
chmod +x ld- 동작 확인:
./ld --version
# 여기서 "GNU ld (GNU Binutils for Ubuntu) 2.42 ..."가 나오면 성공위와 거의 똑같이 한 번 더 합니다:
cd /home/<user>/cadence/installs/XCELIUM2409/tools/cdsgcc/gcc/9.3/bin
[ -f ld ] && mv ld ld.cadence-2.34
cat > ld << 'EOF'
#!/bin/sh
# Xcelium ld wrapper - delegate to system /usr/bin/ld on Ubuntu 24.04
# and drop Cadence's internal cdsgcc runtime lib dir from LD_LIBRARY_PATH.
if [ -n "$LD_LIBRARY_PATH" ]; then
CLEAN=$(printf '%s\n' "$LD_LIBRARY_PATH" | tr ':' '\n' \
| grep -v 'cdsgcc/gcc/9\.3/install/lib64' \
| paste -sd:)
export LD_LIBRARY_PATH="$CLEAN"
fi
exec /usr/bin/ld "$@"
EOF
chmod +x ld
./ld --version
# 마찬가지로 GNU ld 2.42 출력 확인이제 Xcelium이 내부적으로 어느 쪽 경로의 ld를 사용하더라도,
실제로는 이 wrapper를 거쳐 시스템 /usr/bin/ld(2.42)가 호출되게 됩니다.
이제 기존 프로젝트 디렉토리에서, 환경 변수는 건드리지 않고 원래 순서를 그대로 실행합니다.
예시 (사용자 환경 기준):
cd ~/Work_MPC/MPCs_Generate_IP/ni710AE-3x4/build/logical/testbench/oob_testbench/verilog
# 1) Arm/Xcelium 환경 설정
csh
source oob_sourceme
# 2) bash로 돌아오기 (필요시)
bash
# 3) 원래 시뮬레이션 명령
make all SIM=ius CONFIG=`pwd`/../../../ni700_ni710AE_1기대되는 변화:
- 예전의
unknown type [0x13] section '.relr.dyn',skipping incompatible /lib/x86_64-linux-gnu/libm.so.6같은 에러는 사라집니다. - 대신, 만약 RTL/UVM/VIP 자체의 문제나 테스트 실패가 있다면, 이제 그쪽 에러/경고가 보이기 시작할 수 있습니다. (이 경우 링크 문제는 해결된 것이고, 그 다음 “순수 verification 이슈”를 보면 됩니다.)
혹시 이 방법이 특정 시스템에서 문제를 일으키거나, Xcelium을 다른 버전으로 업그레이드하면서 원상태로 되돌리고 싶다면:
각 디렉토리에서:
cd /home/<user>/cadence/installs/XCELIUM2409/tools.lnx86/cdsgcc/gcc/9.3/bin
rm -f ld
[ -f ld.cadence-2.34 ] && mv ld.cadence-2.34 ld
cd /home/<user>/cadence/installs/XCELIUM2409/tools/cdsgcc/gcc/9.3/bin
rm -f ld
[ -f ld.cadence-2.34 ] && mv ld.cadence-2.34 ld이렇게 하면 Cadence 설치 당시 상태로 ld가 복구됩니다.
다른 시스템에서 똑같은 문제를 만났을 때, 아래 방법들은 강력히 비추천입니다:
-
glibc 패키지를 시스템에 다운그레이드 설치 (
apt install libc6=...)- Ubuntu 전체를 망가뜨릴 수 있습니다.
-
LD_LIBRARY_PATH에 다른 glibc/libm 경로를 넣어서 시스템 전체를 그걸 쓰게 하기
- 실제로까지 해보셨듯이, bash/python/ls/code 등 대부분 명령이 “GLIBC_x.y not found” 에러를 뿜으며 사실상 아무 것도 못하게 됩니다.
-
/lib/x86_64-linux-gnu/libc.so.6, libm.so.6를 직접 덮어쓰기
- 거의 100% OS 재설치 각입니다.
이 가이드는 Cadence 내부의 ld만 살짝 우회하는 방식이라,
최소한의 리스크로 문제 지점을 우회하는 쪽에 가깝습니다.
다른 머신/계정/설치 위치에 적용할 때는 다음만 바꿔주면 됩니다:
-
Xcelium 설치 루트 경로:
/home/<user>/cadence/installs/XCELIUM2409
이 부분을 그 시스템에 맞는 경로로 변경.
-
cdsgcc 버전:
- 위 예시는
gcc/9.3기준입니다. - 만약
gcc/11.2같은 디렉토리라면,cdsgcc/gcc/11.2/bin처럼 경로를 맞춰주면 됩니다. grep -R 'cdsgcc'나find ... -name 'ld'로 실제 위치를 찾을 수 있습니다.
- 위 예시는
-
필요하다면
grep -v 'cdsgcc/gcc/9\.3/install/lib64'부분의 버전 문자열도 맞게 수정- 예: 11.2라면
'cdsgcc/gcc/11\.2/install/lib64'.
- 예: 11.2라면