본문 바로가기
Python

pyinstaller, bootloader는 무엇인가?

by ahsung 2023. 1. 24.

pyinstaller는 무엇인가?

python3는 현대 대표적인 인터프리터 언어로 작성(개발)된 프로그램을 실행시키기 위해서는 개발 환경과 동일하거나 호환 가능한 버전의 인터프리터 프로그램과 개발하면서 사용한 파이썬 패키지가 추가로 필요합니다.

 

pyinstaller는 다른 컴퓨팅 시스템에서도 파이썬 프로그램을 쉽게 배포할 수 있도록 실행에 필요한 모든 것들을 "패키징" 합니다.

pyinstaller는 CPU가 바로 이해할 수 있는 기계어로의 "컴파일"이 아닌 실행 환경의 "패키징"임을 명심해야합니다.

그렇기 때문에 인터프리터 언어로서 실행 속도 개선을 기대할 수 없습니다.
파이썬의 실행속도를 개선하고 싶은 경우, cython등을 사용해서 속도 개선을 원하는 모듈, 로직등은 컴파일언어로 작성후 공유 라이브러리로 컴파일하고 파이썬에서 로드하여 사용해야합니다.

 

 

 

 

pyinstaller의 동작방식 (pyinstaller bootloader의 오해)

pyinstaller의 사용법은 해당 글에서 다루지 않습니다. - 사용법

 

Using PyInstaller — PyInstaller 5.7.0 documentation

UPX is a free utility for compressing executable files and libraries. It is available for most operating systems and can compress a large number of executable file formats. See the UPX home page for downloads, and for the list of supported file formats. Wh

pyinstaller.org

pyinstaller는 최초로 실행되는 main 스크립트를 분석하여 필요한 패키지들과 라이브러리를 추적합니다.

main 스크립트의 import된 패키지를 따라가며 추적하고 파이썬의 빌트인 패키지와 cython등을 사용하는 패키지들은 OS의 기본 라이브러리 혹은 추가로 설치된 라이브러리를 사용할 것입니다. (+ 현재 가상환경의 파이썬 인터프리터)

pyinstaller는 OS 플랫폼에서 기본적으로 찾을 수 있다고 생각하는 라이브러리는 패키징하지 않습니다. ( /lib or /usr/lib)

/usr/lib 중에서는 추가로 설치된 라이브러리가 있을 수 있습니다. (버전이 다르거나)
혹은 OS의 메이저 버전이 다른 경우 사용하는 C 표준라이브러리인 glibc 버전이나 POSIX 인터페이스 호환성 차이가 클 수 있습니다.
최소 OS의 메이저버전은 같아야 pyinstaller로 패키징한 프로그램을 배포해도 호환성이 높음

ex) centos7에서 pyinstaller를 통해 패키징한 패키지는 특정 glibc 버전의 시스템콜을 사용할 수 있고 centos5에는 해당 시스템콜이 구현되지 않아 실행에 실패할 수 있음

 

pyinstaller를 사용하면서 정식 docs를 보면 bootloader라는 용어가 자주 나옵니다.

 

PyInstaller Manual — PyInstaller 5.7.0 documentation

PyInstaller bundles a Python application and all its dependencies into a single package. The user can run the packaged app without installing a Python interpreter or any modules. PyInstaller supports Python 3.7 and newer, and correctly bundles many major P

pyinstaller.org

결론부터 말하면 pyinstaller의 bootloader는 우리가 흔히아는 bios -> OS를 부팅하는 프로그램인 bootloader가 아닙니다. ㅎㅎ..

 

pyinstaller는 파이썬 프로그램을 OS가 바로 실행할 수 있는 형태의 "바이너리 실행파일"로 컴파일 하는 것이 아니기 때문에 실행 환경을 누군가가 셋팅해주어야합니다. (바이너리 실행파일은 OS의 로더가 프로그램을 RAM으로 올려 프로세스화하고 OS에 따라 필요한 환경 변수, 프로세스 argument등을 넘겨줍니다.)

pyinstaller의 bootloader는 패키징된 정보를 분석하여 python의 코드를 실행하기 위한 모든 것들을 준비합니다.

bootloader는 패키징의 결과물중 실행파일 안에 포함되어 있으며 실행파일을 실행하게되면 bootloader가 실행되고 환경변수, 필요한 패키지(혹은 라이브러리) 압축해제, 동적 라이브러리 로드등 실행에 필요한 모든 것을 setup하고 자식 프로세스로 실제 파이썬 프로그램을 실행합니다.

 

 

 

 

pyinstaller의 패키징 방식

23/01/24일자 기준 pyinstaller는 one-file과 one-dir 모드 두가지 패키징 방식을 지원합니다.

 

one-dir 모드는 하나의 디렉토리 안에 파이썬 프로그램을 실행시키기 위한 모든 파일들을 생성합니다.

bootloader가 포함된 실행 파일과 프로그램 실행에 필요한 공유 라이브러리들로 구성되어 있습니다. 다른 시스템으로 배포를 원할 경우 디렉토리를 통째로 배포해야하며 디렉토리 내부에서 상대적 path를 사용하고 있으므로 내부 구성이나 위치가 달라지면 안됩니다.

 

one-file 모드는 말 그대로 하나의 파일 형태로 패키징을 합니다. 하나의 파일이기 때문에 one-dir보다 배포가 간편하고 내부 구성이 달라질 걱정은 없습니다.

간혹 one-file 모드가 하나의 "실행파일"로 구성되었기 때문에 컴파일된 실행파일로서 더 빠르다고 착각할 수 있습니다.

일반적인 "실행파일"의 경우, 프로세스가 실행되면서 동적 라이브러리를 로드(동적 링킹)하고 정적 라이브러리와 컴파일된 오브젝트들이 하나의 파일안에 이미 "정적 링킹"되어 있지만 pyinstaller가 만든 "실행파일"은 bootloader를 실행시키는 로직과 그외 필요한 패키지와 라이브러리가 압축되어 들어있을 뿐입니다. (바이너리 코드들이 링킹된 것이 아님!, 그래서 pyinstaller는 컴파일이 아닌 "패키징"을 한다고 표현함)

one-file의 결과물로 나온 "실행파일"을 실행하면 패키징된 파일들을 압축 해제하여 one-dir모드에서 나오는 결과물을 생성하고 프로그램을 실행시킵니다. 오히려 one-file 모드는 프로그램을 실행시킬 때마다 압축해제 과정이 있어 로드 타임이 더욱 오래 걸립니다.

(정확하게는 pyinstaller bootloader가 셋업하는 시간이 오래걸림)

 

one-file은 사실상 매번 새로운 공유 라이브러리를 생성과 삭제를 시도하기 때문에 디스크 -> 메모리 캐싱도 되지 않아 매번 압축해제에 걸리는 시간과 디스크를 다시 읽어야하는 번거로움으로 시간이 더 걸릴 수 있습니다.

 

 

 

 

 

댓글