모든 개발 응용 프로그램과 파일이 포함된 워크스테이션 드라이브를 만들고 이를 다양한 Linux 배포판(플러그 앤 플레이)이 있는 여러 장치에서 사용할 생각입니다. 그게 가능합니까?
답변1
예.
그러나 주의할 점이 많습니다. 애플리케이션이 Perl, Python 또는 Posix Shell Script와 같은 해석된 언어로 작성된 경우 애플리케이션이 의존하는 모든 모듈도 애플리케이션과 함께 번들로 제공되는지 확인하기만 하면 됩니다. 특정 기본 플랫폼을 가정하는 구성, 즉 리틀 엔디안 정수를 가정합니다. 그러면 애플리케이션이 인터프리터가 있는 모든 플랫폼에서 실행될 수 있습니다. 애플리케이션이 Java와 같은 가상 머신에서 실행되도록 설계된 바이트 코드로 작성되고 컴파일된 경우 Run Anywhere가 숨겨진 함정 없이 약속된 후에 Java가 작성된다는 가정하에 해석된 언어 애플리케이션과 동일한 제약 조건을 허용할 수 있습니다.
반면, 기계 실행 가능 바이너리로 컴파일된 프로그램은 올바르게 컴파일하기가 훨씬 더 어렵습니다. 여전히 가능하지만 알아야 할 몇 가지 함정이 있으며 대규모 릴리스의 경우 기본적으로 세 가지 방법이 있습니다.
모든 대상이 동일한 프로세서 제품군에 속한다고 가정하면 주요 문제는 호환되지 않는 커널 API, 호환되지 않거나 불완전한 사용자 영역 ABI 및 새로운 프로세서 opcode의 세 가지 범주로 나눌 수 있습니다. 첫 번째는 이해하기 쉽습니다. Linux 커널은 시스템 호출을 자주 추가하며 프로그램이 해당 시스템 호출이 없는 이전 커널에서 새 시스템 호출을 호출하려고 하면 프로그램이 작동하지 않습니다. 해결책은 임의의 대상을 기본 커널로 선택하고 애플리케이션이나 종속성 중 어느 것도 최신 시스템 호출을 사용하지 않도록 하는 것입니다. 세 번째 범주도 이해하기 쉽습니다. 프로세서 제품군의 최신 프로세서에는 이전 버전이 해석할 수 없는 opcode가 있습니다. AVX512 SIMD 벡터 연산과 같은 이러한 최신 연산은 x86_64 플랫폼에 나타나며 실제로 일부 계산 속도를 높일 수 있지만 상대적으로 새로운 연산입니다. 해결책은 간단합니다. 프로그램을 컴파일할 때 구체적으로 대상으로 삼고 싶은 프로세서 버전을 컴파일러에 알리고 이전 범용 프로세서만 대상으로 삼으면 됩니다.
두 번째 범주는 상황이 까다로워지는 부분입니다. 이는 기본 프로그램이 동적으로 연결되어 있기 때문입니다. 이는 결과 바이너리가 불완전함을 의미합니다. 완전한 프로세스 이미지를 생성하기에는 정보 자체가 충분하지 않으며 중간 프로그램은 프로세스를 구축할 때 링크를 본질적으로 완료하기 위해 파일을 해석해야 합니다. 중간 프로그램은 시스템 C 라이브러리의 일부인 동적 링커입니다. 이는 다소 복잡하지만 중요한 문제, 즉 호환되지 않는 libc/동적 링커 문제로 이어집니다. glibc에 대해 빌드하는 경우 프로그램이 다른 libc를 사용하여 실행될 수 있지만 이것이 보장되지는 않습니다. 동적 바이너리에는 실행에 의존하는 라이브러리 목록이 어딘가에 포함되며, 개발 시스템(프로덕션 시스템이 아님)에서 해당 라이브러리를 찾는 경로에 대한 정보도 포함될 수 있습니다. 이 문제는 세 가지 방법 중 하나로 해결될 수 있습니다. 첫 번째는 각 종속성의 복사본과 함께 응용 프로그램을 번들로 묶는 Microsoft 플랫폼 접근 방식입니다. 애플리케이션이 시스템 디렉토리가 아닌 디렉토리에 포함되어 있는 경우 POSIX 쉘 스크립트를 사용하여 동적 링커가 시스템 라이브러리 대신 번들 라이브러리를 찾도록 필요한 경로 변수를 설정할 수 있습니다. 자세한 내용은 ld.so 매뉴얼 페이지를 참조하십시오. 두 번째 해결책은 애플리케이션을 정적으로 연결하는 것입니다. 이렇게 하면 동적 연결과 관련된 문제에 대해 걱정할 필요가 없습니다. 마지막으로, 이 문제를 해결하기 위해 제가 생각할 수 있는 마지막 해결책은 사용자가 자신만의 솔루션을 구축하도록 하는 것입니다. 이는 완성도를 위해 추가되었을 뿐 실제로는 답변이 아닙니다. 번들링 또는 정적 연결 옵션을 유지하세요. 둘 다 장점이 있지만 전자는 동적 연결의 요점 중 하나를 무효화합니다. 즉, 메모리에 라이브러리 복사본을 두어 애플리케이션이 새 라이브러리의 버그 수정을 통해 이점을 얻을 수 있다는 것입니다. 즉, 후자는 서로 다른 라이선스에 따라 코드를 혼합하는 데 문제가 있으므로 두 가지 모두 장단점이 있습니다.