Alma8 기반 Docker 컨테이너에 Qt6을 구축했으며 Docker 호스트는 Fedora 35입니다.
어떤 경우에는(아래 설명) 모든 Qt 라이브러리가 로드되지 않습니다 libQt6Core.so[.6[.2.4]]
. 그러나 파일이 존재하고 올바른 디렉토리에서 검색됩니다. libQt6Dbus.so
예를 들어 다른 Qt 라이브러리를 찾아 로드합니다.
광범위한 디버깅, 재구축, 웹 검색을 통해 근본 원인이 무엇인지, 어떻게 해결할 수 있는지에 대한 단서를 얻지 못했습니다.
포지셔닝 문제
문제의 범위를 다음 시나리오로 좁혔습니다.
- 나는 두 개의 최소 가상 머신을 만들었습니다. 하나는 centos7을 사용하고 다른 하나는 alma8을 사용했습니다.
- 공식 저장소에서 Docker를 설치했습니다.
- 두 가상 머신 모두에서 동일한 Docker 이미지를 실행하고 동일한 qt6 패키지를 설치하고 있습니다.
- Docker 호스트가 centos7일 때 충돌이 발생했습니다.
- Docker 호스트가 alma8일 때 작동합니다.
이론과 이슈
- Qt6은 Alma8을 기반으로 구축되었으며 Centos7에서 제공하는 것보다 일부 최신 시스템 라이브러리에 연결되므로 Qt6은 Centos7에서 실행되지 않습니다(완전히 예상된 것이며 괜찮습니다). 하지만 그것은~해야 한다Alma8 Docker 컨테이너 내 어디에서나 실행하세요.
- 컨테이너 이미지는 어디에서나 실행될 수 있어야 하지만 이 경우 호스트 OS의 "무언가"가 컨테이너에 몰래 들어가서 문제를 일으킬 수 있습니다. 두 컨테이너가 정확히 동일한 이미지를 사용하더라도 마찬가지입니다.
문제는 이 "사물"이 무엇이며 어떻게/왜 빌드를 중단시키는가입니다.
내가 시도한 것
libQt6Gui.so
다음을 사용하여 로드할 수 있는지 libQt6Core.so
, libQt6Core.so
가짜로 보이는지 확인했습니다 .
ldd
약간의 차이점이 있습니다LD_DEBUG=libs ldd
(아래 참조).- 자유의 나무아무런 차이도 보이지 않습니다(그러나 멋진 나무입니다 :))
- pyldd(conda-build에서)
readelf -d
나는 또한 다음을 시도했습니다.
- 설정
LD_LIBRARY_PATH
(아무것도 변경하지 않았습니다. 올바른 경로가 항상 검색된다는 것을 알고 있으므로 놀라운 일이 아닙니다) - centos7 호스트가 있는 alma8 컨테이너에 Qt6 빌드(": 파일을 열 수 없습니다"로 빌드 실패
libQt6Core.so.6
, 빌드된 라이브러리와 동일한 오류) - centos7 컨테이너에 Qt6 빌드(아직 수정할 수 없는 다른 문제로 인해 빌드가 실패함)
차이점은 다음과 같습니다.ldd
아래 스크린샷에서는 Centos7 호스트의 Alma8-Docker-Container를 볼 수 있습니다.왼쪽그리고 오른쪽 Alma8 호스트의 *Alma8-Docker-Container.
처음 두 이미지는 결과를 보여줍니다 ldd /opt/emsconda/lib/libQt6Gui.so
. libQt6Core
왼쪽에서는 찾을 수 없지만 오른쪽에서는 찾을 수 있습니다.
두 번째 스크린샷은 다른 Qt 라이브러리를 보여줍니다.예찾아서 로드하세요. 왼쪽의 ICU 라이브러리도 없습니다. 아마도 libQt6Core도 로드될 때만 로드되는 것일까요?
이 스크린샷은 결과를 보여줍니다 LD_DEBUG=libs ldd ...
. 두 경우 모두 libQt6Core
검색이 올바른 위치( /opt/emsconda/lib
)에 있음을 알 수 있습니다. 하지만 올바른 컨테이너에만 로드할 수 있습니다. 또한 왼쪽의 `/opt/emsconda/lib/./를 확인하고(하하)) 조용히 다음 lib로 이동합니다...
오류 메시지를 찾을 수 없습니다. 파일이 열리지 않거나 로드되지 않습니다.
이것 libQt6Core.so
자체를 조사해 보면 단서를 얻을 수 있습니다. 이는 linux-vdso.so.1
.
~에 따르면이 문제, 이 파일은 운영 체제 커널에 의해 사용자 공간에 주입된 가상 라이브러리입니다.
Docker 컨테이너는 자체 커널을 실행하지 않기 때문에 이 파일이 호스트 운영 체제에서 온 것으로 의심됩니다. 어쩌면 centos7 커널이 제공할 수 없는 일부 기능 libQt6Core
에 의존할까요 ? linux-vdso.so.1
나는 전혀 모른다 ...
지금까지 시도한 어떤 것도 오류 메시지를 생성하지 않았기 때문에 실제 문제가 무엇인지, 디버깅 방법을 전혀 모릅니다. 귀하가 제공할 수 있는 팁, 요령 또는 도움을 주시면 감사하겠습니다.
답변1
질문에 답변되었습니다Qt 포럼에서.
요약:
.so
필요한 최소 커널 버전을 나타내는 ABI 태그가 포함되어 있습니다 . 를 통해 이를 확인할 수 있습니다objdump -s -j .note.ABI-tag libQt6Core.so.6.2.4
. 결과는 마지막 세 블록( 내 경우에는0x03
0x11
0x00
->3.17.0
)에 있습니다.- QT는 최신 커널에서만 작동하는 일부 시스템 호출을 사용하기 때문에 이 정보는 의도적으로 여기에 배치됩니다.
- Glibc는 공유 객체를 로드할 때 이 정보를 읽고 이를 현재 커널 버전과 비교합니다. 일치하지 않는 경우 파일이 로드되지 않습니다.
- Docker에는 자체 커널이 없으므로 Docker 호스트의 커널 버전이 비교에 사용됩니다. 따라서 Docker 이미지가 Alma8이더라도 제 경우 커널은 여전히 Centos7 호스트의 이전 v3.10.0입니다.
- 당신은 그것을 사용할 수 있습니다
strip --remove-section=.note.ABI-tag libQt6Core.so.6.2.4
. Qt에는 대체 코드가 있는 것 같으므로 문제가 없어야 합니다.