✅ PyInstaller 로 .exe 만들기 간단 요약 (윈도우 기준)
1️⃣ venv 활성화
radioEnv\Scripts\activate
2️⃣ PyInstaller 설치
pip install pyinstaller
3️⃣ 빌드 실행
pyinstaller main.py --onefile --noconsole
--onefile → 하나의 .exe 파일
--noconsole → 콘솔창 없이 실행 (원하면 제거 가능)
4️⃣ 생성된 .exe 위치
dist/main.exe
5️⃣ .exe, config/, sounds/, modules/ 폴더만 함께 압축해 배포
예시)
📁 Buffer_Radio_Package/
├─ main.exe
├─ modules/ ✅ 꼭 포함 (전체 코드)
├─ config/
│ └─ config.txt
├─ sounds/
│ ├─ time_signal_beep.mp3
│ └─ tuning/
├─ cache/ (비워서 배포 가능)
├─ logs/ (자동 생성됨)
추가로
FileNotFoundError: 설정 파일을 찾을 수 없습니다: C:\Users\000\AppData\Local\Temp\_MEIxxxxx\...\config\config.txt
위와같이 설정파일을 찾을 수 없다는 경로 문제가 발생할 때, 프로그램 진입 방식에 따라 경로를 다르게 처리할 수 있도록 수정해야 한다.
CONFIG_PATH = os.path.join(os.path.dirname(__file__), '..', 'config', 'config.txt')
→ ✅ 이건 소스 코드가 직접 실행될 때는 정상이지만,
→ ❌ .exe 파일이 실행되는 임시 경로에서는 config/ 디렉토리가 존재하지 않아 오류 발생.
아래와 같이 코드를 수정해야한다.
[ PyInstaller 빌드시 config 디렉토리도 포함 + 상대경로 수정]
import sys
import os
def get_base_path():
if getattr(sys, 'frozen', False):
# exe 상태일 경우
return sys._MEIPASS
else:
# 스크립트 상태일 경우
return os.path.dirname(__file__)
CONFIG_PATH = os.path.join(get_base_path(), 'config', 'config.txt')
✅ os.path.dirname (), os.path.abspath () 차이점 요약
함수설명예시 결과
os.path.dirname(path) | 주어진 경로에서 디렉토리 경로만 추출 | 'C:/Users/user/Desktop/file.txt' → 'C:/Users/user/Desktop' |
os.path.abspath(path) | 주어진 상대경로를 절대경로로 변환 | '../config/config.txt' → 'C:/Users/user/Buffer_radio/config/config.txt' |
✅ 예시로 비교해볼게요:
🔸 1. os.path.dirname(__file__)
# 현재 파일의 디렉토리 경로만 가져옴 print(os.path.dirname(__file__))
C:/Users/skfka/Buffer_radio/modules
🔸 2. os.path.abspath(__file__)
# 현재 파일의 전체 경로를 절대경로로 변환 print(os.path.abspath(__file__))
C:/Users/skfka/Buffer_radio/modules/config_loader.py
✅ sys._MEIPASS란?
PyInstaller로 .exe 빌드된 프로그램에서, 내부 리소스가 임시 폴더에 압축 해제된 위치를 의미하는 특수 경로입니다.
즉,
- PyInstaller가 .exe 실행 시, 내부에 포함된 config/, sounds/, modules/ 등의 리소스를
- 자동으로 Temp/_MEIxxxx/ 디렉토리에 풀어놓고 실행합니다.
- 그 경로가 sys._MEIPASS 입니다.
📌 예시 비교
.py 직접 실행 | os.path.dirname(__file__) → 실제 폴더 경로 |
.exe 실행 (PyInstaller) | sys._MEIPASS → 내부 압축해제된 Temp 경로 (예: C:\Users\user\AppData\Local\Temp\_MEI12345) |
✅ 그래서 우리가 이렇게 처리하는 이유는?
def get_base_path(): if getattr(sys, 'frozen', False): return sys._MEIPASS else: return os.path.dirname(__file__)
✔ .exe 상태인 경우 → sys._MEIPASS
✔ .py 상태인 경우 → os.path.dirname(__file__)
→ 두 상황 모두에서 경로가 정상 동작하도록 보장해주는 코드입니다.
📦 실제 활용 예
CONFIG_PATH = os.path.join(get_base_path(), 'config', 'config.txt')
→ .exe가 어디서 실행되든, config.txt를 정확히 찾아냅니다.
✅ 요약
sys._MEIPASS | PyInstaller 실행 시 내부 리소스 경로 (Temp 폴더) |
getattr(sys, 'frozen', False) | 현재 실행 환경이 PyInstaller인지 확인하는 방법 |
목적 | .exe에서도 경로 오류 없이 파일 접근 가능하도록 |
728x90
'개발로그 > Python' 카테고리의 다른 글
윈도우 환경에서 10시간 이상 프로그램을 동작하게 해보자. (0) | 2025.03.27 |
---|---|
pyinstaller 반드시 추가해야할 필수 옵션 리스트 (0) | 2025.03.26 |
pyinstaller 패키지가 자꾸 누락될 때, (0) | 2025.03.25 |
pyinstaller 빌드 한 번 해보자... 준비사항 (0) | 2025.03.24 |
anaconda + python 완전히 지우는 방법. (0) | 2025.03.22 |
없어져라! SSL 문제 해결을 위한 실전 대응 북 (0) | 2025.03.16 |
random.choice()와 random.shuffle()은 비슷해 보이지만 목적이 완전히 다르다 (0) | 2025.03.15 |
Preload + On-demand + Fallback 구조 (캐싱전략에 관하여, 용어설명) 메모 (0) | 2025.03.12 |
댓글