PyInstaller
PyInstaller freezes (packages) Python applications into stand-alone executables, under Windows, GNU/Linux, Mac OS X, FreeBSD, Solaris and AIX.
Options
-
-F
,--onefile
- Create a one-file bundled executable.
-
--clean
- Clean PyInstaller cache and remove temporary files before building.
Windows And Mac Os X Specific Options
-
-w
,--windowed
,--noconsole
- Windows and Mac OS X: do not provide a console window for standard i/o.
- On Mac OS this also triggers building a Mac OS
.app
bundle. - On Windows this option is automatically set if the first script is a
.pyw
file. - This option is ignored on *NIX systems.
-
-i ICON
,--icon ICON
- ICON is
FILE.ico
orFILE.exe,ID
orFILE.icns
orImage
orNONE
-
FILE.ico
: apply the icon to a Windows executable. -
FILE.exe,ID
: extract the icon with ID from an exe. -
FILE.icns
: apply the icon to the.app
bundle on Mac OS. -
Image
: If an image file is entered that isn’t in the platform format (ico on Windows, icns on Mac), PyInstaller tries to use Pillow to translate the icon into the correct format (if Pillow is installed). -
NONE
to not apply any icon, thereby making the OS show some default (default: apply PyInstaller’s icon).
-
- This option can be used multiple times.
Hide console window
콘솔창이 출력되지 않게 하려면 아래와 같이 명령어에 -w
또는 --windowed
를 추가해줍니다.
Single executable
실행파일 하나만 생성하기 위해서는 아래와 같이 명령어에 -F
또는 –onefile
을 추가합니다.
아이콘 설정
Using Spec Files
사양 파일을 수정하는 것이 유용한 네 가지 경우가 있습니다.
- 앱과 데이터 파일을 묶고 싶을 때.
- PyInstaller가 다른 소스에서 알지 못하는 런타임 라이브러리( .dll또는 파일)를 포함하려는 경우..so
- 실행 파일에 Python 런타임 옵션을 추가하려는 경우.
- 공통 모듈이 병합된 다중 프로그램 번들을 생성하려는 경우.
데이터 폴더 지정
- kivy - Pyinstaller adding data files - Stack Overflow
- Package Data Files to pyinstaller Binaries | by Dinesh Kumar K B | Python in Plain English
multiprocessing in windows
다른플랫폼에서 multiprocessing을 지원하려면 freeze_support
함수를 사용해야한다. 실행하면 windows의 고정 지원에만 영향을 준다고 써있는데... exe파일로 만든 프로그램 실행시 꺼지는 프로세스를 고정한다 생각하면될듯.
UPX 적용 방법
Package Data
Generate Pyinstaller binaries
일반적으로 다음 명령을 사용하여 pyinstaller에서 실행 가능한 하나의 파일을 생성합니다.
pyinstaller 실행 파일에 데이터 파일 추가
실행 파일과 함께 압축해야 하는 응용 프로그램에 대한 도움말 파일이 있다고 가정해 보겠습니다. 애플리케이션은 런타임에 파일을 읽고 사용자에게 표시해야 합니다.
어떻게 하죠? 파일은 패키징하는 동안 애플리케이션의 일부로 존재하지만 바이너리와 함께 패키징되지 않습니다. 따라서 실행 중에 다음과 같은 오류가 발생할 수 있습니다.
FileNotFoundError: [Errno 2] No such file or directory:C:\\Users\\Username\\AppData\\Local\\Temp\\_MEI41602\\help.md
[11200] Failed to execute script
이는 pyinstaller 실행 파일이 XXXX
가 임의의 숫자인 임시 디렉토리 _MEIXXXX
에서 데이터 파일을 찾기 때문입니다. 모든 지원 데이터 파일이 거기에 복사되었는지 확인해야 합니다.
Pyinstaller는 임시 폴더에 데이터 압축을 풀고 이 디렉토리 경로를 MEIPASS
변수에 저장합니다. 이 속성은 부트로더에 의해 sys 환경에서 설정됩니다.
MEIPASS
변수는 프로그램이 번들 모드에서 실행 중인 경우에만 사용할 수 있습니다. 또한 프로그램이 번들에서 실행되는지 소스 코드에서 실행되는지 확인하는 데 도움이 됩니다.
Windows
Here we pass the file path to the add data flag with the path inside the bundle separated by a semi colon.
Linux/Mac
Here we pass the file path to the add data flag with the path inside the bundle separated by a colon.
Spec file
The data files can be added via spec files as well.
datas는 첫 번째 문자열이 기존 파일이 help.md
임을 나타내는 튜플입니다. 해당 파일은 사양 파일의 위치를 기준으로 조회되고 번들 앱의 최상위 수준으로 복사됩니다. 이 경우 도움말 파일은 현재 디렉터리에 있습니다.
이제 도움말 데이터 파일을 pyinstaller 바이너리에 추가했으므로 이를 읽고 사용자에게 표시하는 방법은 무엇입니까?
먼저 소스 코드와 번들 모드 모두에서 도움말 파일을 읽을 수 있는지 확인해야 합니다. 앞서 언급했듯이 프로그램이 소스 코드 또는 pyinstaller에서 실행 중인지 확인할 수 있습니다.
def read_help_file():
# Check if MEIPASS attribute is available in sys else return current file path
bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
path_to_help = os.path.abspath(os.path.join(bundle_dir,'help.md'))
with open(path_to_help, "r+") as help_file:
print(help_file.read())
Troubleshotting
_tkinter.TclError: invalid command name "PyImagingPhoto"
tkinter를 사용할 때 PIL과 같이 사용할 때 다음과 같은 에러 출력:
Traceback (most recent call last):
File "PIL/ImageTk.py", line 181, in paste
_tkinter.TclError: invalid command name "PyImagingPhoto"
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "magic-collection-tracker/test.py", line 22, in <module>
File "magic-collection-tracker/test.py", line 11, in main
File "PIL/ImageTk.py", line 120, in __init__
File "PIL/ImageTk.py", line 185, in paste
ModuleNotFoundError: No module named 'PIL._tkinter_finder'
hiddenimports
를 사용하여 해결하자.
UPX is not available
- (python) pyinstaller 일곱번의 삽질 for uvicorn + FastAPI
- Fix PyInstaller UPX is not available Error - PyInstaller Tutorial
UPX (실행파일 압축) 부터 설치하자.