pyinstaller
python을 실행하기 위해서는 기본적으로 가상환경 내에서 실행해야 한다. 매번 터미널창에서 가상환경에 접속하여 *.py로 실행하기에는 번거롭고 코드 파일 관리가 힘들기 때문에 *.exe를 생성하여 실행하는 방법을 추천한다.
실행 환경
- Windows10
- python 3.7.4 or python 3.8.8
- 두 버전의 python에서 pyinstaller를 실행하였는데 크게 다른 점은 느끼지 못했다. python 버전보다는 외부 라이브러리와 pyinstaller hook의 버전이 가장 까다롭다.
pyinstaller 설치
# (venv) pip install -U pyintaller
# (venv) pip install -U pyinstaller-hooks-contrib
-U
옵션을 통해 해당 라이브러리의 최신 버전을 설치할 수 있다.- 설치한 pyinstaller 버전 : 4.5.1
- 설치한 hook 버전 : 2021.3
실행파일 생성
# (venv) pytinstaller {your_python}.py
- 위의 명령어 한 줄을 통해 python 파일에 대한 exe 파일과 spec 파일이 생성된다
pyinstaller 옵션
아래는 주로 사용하는 옵션이다
--noconfirm
: 별다른 확인 요청 없이 output 경로를 지정한다--clean
: 빌드 전 캐시 및 임시 파일을 삭제한다--distpath {Your_Directory}
: bundle app을 생성할 폴더명. 없으면 자동으로 생성한다--onedir
: 실행파일을 포함한 하나의 bundle 폴더를 생성한다--onefile
: 하나의 실행 파일만 생성-n
: 생성하고자 하는 실행파일 및 spec 파일명--console
or--noconsole
: 콘솔창을 띄울지 설정.no
가 붙으면 콘솔창을 띄우지 않겠다는 의미--paths {Directory}
: 스크립트 내에서 import 할 경로. 구분자는:
로 다중 paths 설정이 가능하다.--key
: 실행파일에 대해 bytecode 암호화에 사용되는 key 값--icon
: 실행파일에 대해 해당 아이콘을 적용한다.
spec 파일을 통해 재빌드하기
이미 실행파일을 생성하였으나 옵션을 변경해야 할 경우가 있다. 이때 실행 명령어를 통해 새로 실행파일을 만들 필요가 없다. 다음은 옵션 변경에 대한 예시 상황이다.
- 파일 실행 시
ModuleNotFoundError
발생 console
에 대한 옵션 변경- 프로그램 이름 변경
- 아이콘 변경
- 라이브러리의 경로 변경
위와 같은 상황에서 옵션을 추가하여 pyinstaller 를 재실행하는 것은 상당히 번거롭지만, spec 파일 수정으로 간단히 재빌드 할 수 있다.
먼저 pyinstaller를 실행한 경로에서 {PROGRAM_NAME}.spec
파일을 찾아 열어본다. spec 파일 내부는 다음과 같다.
# -*- mode: python ; coding: utf-8 -*-
block_cipher = pyi_crypto.PyiBlockCipher(key='{PASSWORD}')
a = Analysis(['{실행하는 파이썬 파일명}.py'],
pathex=['{프로젝트 경로}'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=True,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='{프로그램 파일명}',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None , icon='{아이콘 파일명}')
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='{프로그램 파일명}')
이제 이 파일에서 옵션을 변경해 주면 된다.
예를 들어 파일 실행 시 ModuleNotFoundError
가 발생한 경우, hiddenimports=[]
의 리스트 안에 모듈명을 String으로 넣어 주면 된다.
spec 파일을 수정 후 다시 빌드하려면 다음 명령어 한 줄이면 빌드가 완료된다.
# (venv) pyinstaller -F {PROGRAM_NAME}.spec
에러 발생 대처
-
ModuleNotFound Error
- 대체로
--hidden-import
옵션을 통해 해결이 된다. 말 그대로 해당 파일을 불러오지 못하는 에러이므로 추가적으로 import를 해 주면 내 경우 대부분 해결이 되었다.
- 대체로
-
.dll Error
- .dll 파일의 경로를 찾지 못해서 나는 경우가 많다.
- 따라서 시스템 환경 변수 → PATH 변수 내에 해당하는 .dll 파일이 저장되어 있는 경로를 추가해 주면 된다.
-
라이브러리 호출 에러
- ModuleNotFound 도 아니고 .dll 도 아닌데 라이브러리 호출 부분에서 에러가 발생하는 경우가 있다. 이 경우 해당 라이브러리와 pyinstaller hook 버전이 안 맞을 확률이 높다.
- pyinstaller hook 의 버전 업데이트가 상대적으로 느린 편이기 때문에 라이브러리의 버전을 하나씩 내리면 해결되는 경우가 많다.