make를 사용하여 컴파일: 라이브러리에 링크

make를 사용하여 컴파일: 라이브러리에 링크

저는 애플리케이션용 PHP를 컴파일하기 위해 make를 사용하고 있습니다. 문제는 ldd php를 실행할 때 다음과 같은 내용이 있다는 것입니다.

libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f5b4e661000)

그러나 libk5crypto.so.3은 libk5crypto.so.3.1을 가리키는 기호입니다.

내 PHP가 libk5crypto.so.3.1을 직접 가리키도록 하고 싶습니다.

가능합니까?

편집: 제가 직접 컴파일한 PHP 서버가 포함된 웹 애플리케이션이 있습니다. 나는 그것을 /etc에 설치하고 싶지 않고 단지 내 응용 프로그램에 설치하기를 원합니다.

내 응용 프로그램에는 php, fop, mapserver 등을 저장하는 server라는 폴더가 있습니다.

내 PHP 폴더에는 모든 종속성이 있는 lib 폴더가 있습니다(ldd bin/php).

응용 프로그램을 설치할 때 /etc/ld.so.conf 파일을 수정하여 PHP 서버의 lib 디렉터리를 추가한 다음 ldconfig를 실행합니다.

때때로 이러한 라이브러리는 /usr/lib/x86_64-linux-gnu에 이미 존재하며, PHP는 해당 폴더의 라이브러리 대신 해당 라이브러리를 사용합니다. 이것은 거의 문제가 되지 않지만 때로는 /usr/lib에 동일한 메이저 버전이지만 더 낮은 마이너 버전이 있는 라이브러리가 있습니다. PHP는 /usr/lib에서 이를 가져오려고 시도하지만 PHP가 최신 종속성으로 컴파일되었기 때문에 오류가 발생합니다.

이러한 이유로 나는 libk5crypto.so.3.1을 직접 가리키고 싶습니다.

애플리케이션을 업데이트할 때 PHP를 제거하고 모든 새 라이브러리가 포함된 최신 PHP를 넣었습니다.

또 다른 점은 PHP에게 주어진 디렉토리에서 라이브러리를 찾도록 지시했지만 문제는 컴파일할 때 라이브러리가 어디에 있을지 모른다는 것입니다.

JigglyNaga의 편집자: PHP를 컴파일한 다음 imap 및 기타 확장 기능을 컴파일합니다. 문제는 PHP와 확장에 있습니다. 그래서 imap의 편집이 더 짧아져서 모두 알려드립니다.

root@ubuntu16:~/compilPHP/php-7.2.2/ext/imap# make
/bin/bash /root/compilPHP/php-7.2.2/ext/imap/libtool --mode=compile cc  -I. -I/root/compilPHP/php-7.2.2/ext/imap -DPHP_ATOM_INC -I/root/compilPHP/php-7.2.2/ext/imap/include -I/root/compilPHP/php-7.2.2/ext/imap/main -I/root/compilPHP/php-7.2.2/ext/imap -I/php/include/php -I/php/include/php/main -I/php/include/php/TSRM -I/php/include/php/Zend -I/php/include/php/ext -I/php/include/php/ext/date/lib -I/usr/include/c-client  -DHAVE_CONFIG_H  -g -O2   -c /root/compilPHP/php-7.2.2/ext/imap/php_imap.c -o php_imap.lo
mkdir .libs
cc -I. -I/root/compilPHP/php-7.2.2/ext/imap -DPHP_ATOM_INC -I/root/compilPHP/php-7.2.2/ext/imap/include -I/root/compilPHP/php-7.2.2/ext/imap/main -I/root/compilPHP/php-7.2.2/ext/imap -I/php/include/php -I/php/include/php/main -I/php/include/php/TSRM -I/php/include/php/Zend -I/php/include/php/ext -I/php/include/php/ext/date/lib -I/usr/include/c-client -DHAVE_CONFIG_H -g -O2 -c /root/compilPHP/php-7.2.2/ext/imap/php_imap.c  -fPIC -DPIC -o .libs/php_imap.o
/bin/bash /root/compilPHP/php-7.2.2/ext/imap/libtool --mode=link cc -DPHP_ATOM_INC -I/root/compilPHP/php-7.2.2/ext/imap/include -I/root/compilPHP/php-7.2.2/ext/imap/main -I/root/compilPHP/php-7.2.2/ext/imap -I/php/include/php -I/php/include/php/main -I/php/include/php/TSRM -I/php/include/php/Zend -I/php/include/php/ext -I/php/include/php/ext/date/lib -I/usr/include/c-client  -DHAVE_CONFIG_H  -g -O2   -o imap.la -export-dynamic -avoid-version -prefer-pic -module -rpath /root/compilPHP/php-7.2.2/ext/imap/modules  php_imap.lo -Wl,-rpath,/usr/lib/x86_64-linux-gnu/mit-krb5 -L/usr/lib/x86_64-linux-gnu/mit-krb5 -lc-client -lcrypt -lpam -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto
cc -shared  .libs/php_imap.o  -L/usr/lib/x86_64-linux-gnu/mit-krb5 -lc-client -lcrypt -lpam -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lssl -lcrypto  -Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu/mit-krb5 -Wl,-soname -Wl,imap.so -o .libs/imap.so
creating imap.la
(cd .libs && rm -f imap.la && ln -s ../imap.la imap.la)
/bin/bash /root/compilPHP/php-7.2.2/ext/imap/libtool --mode=install cp ./imap.la /root/compilPHP/php-7.2.2/ext/imap/modules
cp ./.libs/imap.so /root/compilPHP/php-7.2.2/ext/imap/modules/imap.so
cp ./.libs/imap.lai /root/compilPHP/php-7.2.2/ext/imap/modules/imap.la
PATH="$PATH:/sbin" ldconfig -n /root/compilPHP/php-7.2.2/ext/imap/modules

최종 편집: 작동합니다. 만들기 전에 rpath를 변경했습니다. 내보내기 LDFLAGS='-Wl,-rpath,\$${ORIGIN}/../lib' 모든 답변에 진심으로 감사드립니다.

답변1

이것이 가능한지는 잘 모르겠지만, 그렇게 해서는 안 됩니다. 매우 나쁜 생각입니다.

라이브러리 SONAME(libfoo.so.X 항목)는 라이브러리에 정의되어 있습니다. 전체 경로가 PHP 바이너리에 있다고 생각할 수도 있지만 SONAME만 그런 것은 아닙니다. 이것이 출력에 ldd나타나는 이유 입니다 libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3: name libk5crypto.so.3,이 시스템에서, /usr/lib/x86_64-linux-gnu이 디렉터리의 파일로 확인됩니다.

libk5crypto.so.3파일이 항상 이 위치에 있다는 보장은 없습니다. 경로의 일부는 x86_64-linux-gnu전체 다중 아키텍처(예: Red Hat)가 아닌 이중 아키텍처만 지원하는 Debian 또는 그 파생 배포판 중 하나를 실행하고 있음을 완전히 나타냅니다 /usr/lib64. 이는 런타임 동적 링커에 따라 다르며, 해당 구성을 사용하여(일반적으로) 디버그할 수 ldd있는 위치를 찾을 수 있습니다.libk5crypto.so.3/etc/ld.so.conf

SONAME매우 특별한 의미를 가지고 있습니다 . 전체 기술 세부 사항에 관심이 있다면 Ulrich Drepper의 훌륭한 책을 진심으로 추천할 수 있습니다.문서이 주제에 관한 한, 그렇지 않은 경우 .so.3파일 이름의 일부가 인코딩되어 있음을 이해해야 합니다.호환 가능API의 일부입니다. 아이디어는 libk5crypto어떤 이유로 업데이트하면 시스템이 설치된다는 것입니다.새로운예를 들어 libk5crypto.so.3.2심볼릭 링크를 이동하고 마지막으로 이전 라이브러리를 삭제합니다. 즉, 라이브러리가 존재하는 한ABI와 호환 가능, 이에 대해 컴파일된 모든 프로그램은 라이브러리가 업데이트된다는 이유만으로 다시 컴파일할 필요가 없습니다.

그러나 라이브러리의 전체 이름을 바이너리로 인코딩하면 이러한 이점이 완전히 사라지므로 라이브러리를 업그레이드할 때마다 다시 컴파일해야 합니다. 당신은 거의 확실히 이것을 원하지 않습니다.

모든 것을 말하면서 질문은 다음과 같습니다.XY 문제. 정확히 무엇을 달성하려고 합니까?

답변2

다른 답변은 여전히 ​​​​그 자체로 존재할 수 있지만 귀하의 질문 (설명 후)이 다르기 때문에 이것을 다른 답변으로 추가하십시오. 이것이 시스템뿐만 아니라 애플리케이션과 함께 제공되는 라이브러리에 관한 것이라면 상황은 비교할 수 없습니다. 문제를 해결하기 위해 수행해야 할 작업이 거의 완료되었지만 아직은 완료되지 않았습니다. :-)

문제에 대한 해결 방법은 LD_LIBRARY_PATH, , rpath변경된 라이브러리 전송, 여러 컴파일 등 여러 가지가 있습니다. 각각에는 장점과 문제점이 있으므로 설명하겠습니다.

  • LD_LIBRARY_PATH

    이 경로를 따라가면 프로그램을 실행하기 전에 환경 변수를 설정할 수 있습니다. 바이너리 주위에 래퍼 스크립트를 사용해야 할 수도 있습니다. 즉, /path/to/my/php직접 실행하는 대신 먼저 설정하고 실행하는 셸 스크립트를 실행해야 합니다.LD_LIBRARY_PATH/path/to/my/php

    이 접근 방식의 단점은 약간 취약하다는 것입니다.

    • LD_LIBRARY_PATH라이브러리 검색 경로 앞에 추가되지만 대체되지는 않습니다. 즉, 문제의 라이브러리가 시스템 전체에 설치되었지만 어떤 이유로 제공한 라이브러리를 로드할 수 없는 경우 동적 링커는 시스템 제공 라이브러리에 의존합니다.
    • 쉘 스크립트를 호출해야 한다는 요구 사항은 추가 분기/실행 호출이 필요하다는 것을 의미하며, 이로 인해 문제가 발생할 수 있습니다. 이는 쉘 스크립트에서 명령을 사용하여 어느 정도 완화할 수 있지만 exec(스크립트가 php 바이너리로 대체되고 php 프로그램이 상위 프로그램의 올바른 서브루틴이 되도록) 여전히 지저분합니다.

    반면에 저장소 위치에 어느 정도 유연성을 허용합니다(예: 시스템 제공 라이브러리가 어떤 경우에는 충분하다면 디렉터리에서 제거해도 괜찮습니다 LD_LIBRARY_PATH).

  • rpath

    여기서의 아이디어는 gcc -Wl,-rpath,'/path/to/library'라이브러리를 찾을 위치를 컴파일러에게 (를 통해) 정확하게 알려주는 것입니다. 이는 컴파일 타임에 프로그램에 하드코딩되어 있으며, 그러면 동적 링커는 rpath시스템 제공 버전을 포함하여 사용자가 제공하는 라이브러리 외부 버전을 절대적으로 무시합니다. 이렇게 하면 위의 혼란을 피할 수 있지만 LD_LIBRARY_PATH파일 시스템에서 항목을 이동해야 하는 경우 모든 것을 다시 컴파일해야 한다는 단점이 있습니다.

    이는 또한 사용자가 뭔가가 다르게 설치되기를 기대한다면 운이 좋지 않다는 것을 의미합니다. 그들은 그것을 좋아하지 않을 수도 있습니다.

두 방법 모두 ld.so매뉴얼 페이지에 문서화되어 있습니다.

  • 변경된 라이브러리 배송

    여기서의 아이디어는 에 연결하려고 하는 것이 아니라 libk5crypto.so.3에 연결하려는 것 입니다 libmycorp-k5crypto.so.3. 이 경우 동적 링커는 시스템이 제공하는 것을 얻을 가능성이 전혀 없습니다 libk5crypto.so.3. 여기서의 장점은 일단 설치하면 매우 간단하고 우아하다는 점입니다. 단점은 사람들이 변경 사항을 적용했는지 궁금해하기 시작할 수 있고 (그리고 패치를 요청하는 경우) 이를 얻으려면 빌드 시스템을 libk5crypto자세히 조사해야 한다는 것입니다. libk5crypto.so실제로 libmycorp-k5crypto.so라이브러리를 생성합니다. 장기적으로 보기에도 좋지 않을 수 있으므로 이 길을 가기 전에 주의하세요.

  • 여러 번 컴파일

    시스템 전체에 걸쳐 제공되는 라이브러리를 제공하는 대신할 수 있는지원되는 각 배포판에서 애플리케이션을 컴파일하고 라이브러리를 제공하는 대신 각 배포판에 대한 패키지를 제공하기만 하면 됩니다. 그림packagecloud.io이 작업을 더 쉽게 수행하십시오. 시스템에는 주어진 이름을 가진 라이브러리가 하나만 있기 때문에 선택할 수 있는 라이브러리는 하나뿐이며 잘못된 라이브러리를 선택하는 것은 불가능합니다. 단점은 테스트해야 할 항목의 범위가 더 크기 때문에 출시할 때 더 많은 작업을 수행해야 한다는 것입니다(그리고 좋은 테스트 스위트를 보유하는 것이 좋습니다).

    이 접근 방식의 장점은 다른 방법보다 더 적은 양을 제공하므로 지원해야 할 양이 적고 libk5crypto.so더 이상 지원하지 않는 이전 버전을 사용하는 배포판 사용자에게 먼저 업데이트해야 한다고 알릴 수 있다는 것입니다.

관련 정보