파이썬 프로그램을 다른 PC에서 실행하려면 그 컴퓨터에 파이썬 실행환경(런타임-runtime)이 설치되어 있어야 합니다.
웬만한 리눅스 배포판에는 기본으로 파이썬이 설치되있기 때문에 플랫폼에 따라 빌드해서 실행할 수 있는데 윈도우는 그게 안됩니다. 파이썬이 설치가 안되있는 윈도우에서 실행하기 위해서는 pyinstaller 같은 별도 프로그램이 필요합니다.
공식사이트의 소개는 다음과 같습니다.
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 Python packages such as numpy, matplotlib, PyQt, wxPython, and others.
- PyInstaller는 Python 응용프로그램과 모든 depenency(의존성)를 하나의 패키지로 묶습니다(번들링) 사용자는 파이썬 인터프리터나 모듈을 설치하지 않고도 패키지화된 앱을 실행할 수 있습니다.
- PyInstaller는 Python 3.7 이상을 지원하며 numpy, matplotlib, PyQt, wxPython 등과 같은 많은 주요 Python 패키지가 제대로 작동합니다.
*Python 런타임 + 의존성 라이브러리 등을 패키지로 묶어서 파이썬 인터프리터와 모듈설치 없이 실행할 수 있다는 말입니다. 주요 서드파티의 패키지들까지 (numpy, PyQt 등) 잘 지원하니까 써볼만 합니다. 파일 크기가 조금 큰데 그건 파이썬이 없는 환경에서 실행되도록 하기 위해서 입니다.
*크로스 컴파일러는 아니라고 합니다. 윈도우에서 번들링한 것은 윈도우에서 실행가능하지 리눅스나 맥OS에서 실행 불가합니다. (리눅스와 맥에서도 작동함) 이 포스팅에서는 윈도우의 예제를 실행해봅니다.
터미널에서 pip install로 pyinstaller 를 설치합니다.
pip install -U pyinstaller
간단한 코드를 작성합니다. Hello World 콘솔 출력을 해보겠습니다. 윈도우에서 실행하면 너무 빨리 콘솔창이 닫혀버려서 input()을 넣어줬습니다. 이 파일의 이름을 pyinstaller_ex.py 라고 하겠습니다.
print('Hello World!')
input()
pyinstaller 를 실행합니다.
pyinstaller pyinstaller_ex.py
아래와 같이 dist, build 폴더가 생성됩니다. dist 폴더 안에 pyinstaller_ex 폴더가 생성됩니다. 이 폴더에는 파이썬을 실행하기 위한 dll 파일 등이 들어있는데요. 이 폴더를 압축해서 배포하면 됩니다.
파이썬 3.10.4 버전으로 hello world 를 컴파일해서 압축하니 6메가 정도 나옵니다. 당연히 hello world를 위해서는 너무 많은 용량이지만 이 안에 파이썬이 다 들어있는 거니까 어떻게 보면 가볍다고 할 수도 있습니다.
다음은 하나의 파일로 만드는 방법입니다. --onefile 옵션이나 -F 옵션을 사용합니다.
pyinstaller --onefile pyinstaller_ex.py
요렇게 하면 하나의 파일이 나오는데 역시 6메가 정도가 나왔습니다. 실행은 잘됩니다.
그렇다면 이번엔 tkinter GUI를 한번 만들어 보겠습니다. 적당한 GUI코드를 만듭니다.
import tkinter as tk
def get_text():
print(text_entry1.get())
root = tk.Tk()
root.geometry("320x170")
root.title("pyinstaller-ex")
frame = tk.Frame(root)
frame.pack()
# text entry
text_entry1 = tk.Entry(frame)
text_entry1.insert(0,"first text")
text_entry1.pack(pady = 30)
# button
button = tk.Button(frame, text = 'Get Text', command = get_text)
button.pack()
root.mainloop()
아래와 같은 GUI가 출력됩니다.
원파일로 만들겠습니다. tkinter 는 조금 더 추가되어서 용량이 9메가 정도 나옵니다. 당연한 이야기지만 의존성 라이브러리가 추가될수록 용량은 늘어납니다.
pyinstaller -F pyinstaller_ex.py
세부적인 사항은 다음의 웹사이트를 참고합니다.
PyInstaller Manual — PyInstaller 5.1 documentation