Python / 컴파일(Compile)하는 방법, EXE 파일 만드는 방법
Python 코드를 Windows의 EXE 파일로 배포하려면 PyInstaller로 프로그램과 Python 실행 환경, 필요한 라이브러리를 함께 묶을 수 있습니다. py_compile로 만드는 .pyc는 Python용 바이트코드이며 독립적인 Windows EXE가 아닙니다. 먼저 폴더 방식으로 정상 실행을 확인한 뒤 필요하면 단일 EXE 방식으로 바꾸는 순서가 문제를 찾기 쉽습니다.
바이트코드 컴파일과 EXE 패키징의 차이
py_compile은 소스 코드를 바이트코드 파일로 변환합니다. 반면 PyInstaller의 패키징은 인터프리터와 의존 파일을 수집해 실행 가능한 배포물을 만듭니다. 일반적인 Python 프로그램을 C 코드로 바꾸어 네이티브 기계어로 최적화하는 과정과는 다릅니다. EXE로 묶는다고 실행 속도가 자동으로 빨라지거나 소스 내용이 안전하게 비밀화되는 것은 아닙니다.
결과물은 운영체제와 아키텍처에 영향을 받습니다. Windows EXE는 Windows에서 빌드하며, Linux에서 옵션 하나로 Windows EXE를 만드는 교차 컴파일 도구로 생각하면 안 됩니다. 지원 환경과 사용할 패키지의 호환성을 먼저 확인합니다.
Windows에서 작업 폴더와 가상환경 준비
Python 3와 pip가 설치된 Windows의 PowerShell을 사용합니다. 새 작업 폴더를 만들고 그 폴더에서 터미널을 연 뒤 다음 명령을 순서대로 실행합니다. py -3가 인식되지 않으면 설치된 Python 실행 파일의 경로 또는 해당 Python을 가리키는 python 명령으로 첫 줄을 바꿉니다.
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install "pyinstaller==6.22.3"
.\.venv\Scripts\python.exe -m PyInstaller --version
.venv는 이 작업의 가상환경입니다. 이후 명령은 그 안의 Python을 직접 호출하므로 활성화 스크립트나 PowerShell 실행 정책 변경이 필요하지 않습니다. PyInstaller 6.22.3을 지정해 명령의 기준을 맞췄으며, 다른 버전을 선택한다면 Python·패키지 호환성과 옵션을 다시 확인합니다. 설치 로그에 오류가 없고 마지막 명령의 출력이 6.22.3인지 확인합니다.
빌드할 프로그램이 추가 패키지를 사용한다면 같은 가상환경에 프로젝트의 의존성도 설치해야 합니다. 사용하지 않는 패키지가 많은 전역 환경에서 빌드하면 분석 대상과 결과물 관리가 복잡해질 수 있습니다.
전체 예제를 저장하고 바이트코드 생성
작업 폴더에 UTF-8의 hello.py를 만들고 다음 코드를 저장합니다.
print("Hello, packaging!")
Hello, packaging!
먼저 소스 파일을 실행하면 위와 같은 문구가 출력되어야 합니다.
.\.venv\Scripts\python.exe hello.py
바이트코드 컴파일만 확인하려면 다음 명령을 실행합니다.
.\.venv\Scripts\python.exe -m py_compile hello.py
성공하면 보통 별도 출력 없이 __pycache__에 hello.cpython-312.pyc 같은 파일이 생깁니다. 이름의 버전 표시는 사용한 Python에 따라 달라집니다. 이 파일을 EXE로 이름만 바꿔도 독립 실행 파일이 되지 않으며, 바이트코드에는 호환되는 Python 실행 환경이 필요합니다.
폴더 방식으로 빌드하고 배포
작업 폴더에서 다음 두 명령을 차례로 실행합니다. 빌드가 성공한 뒤 실행 명령을 입력합니다.
.\.venv\Scripts\python.exe -m PyInstaller --onedir --name hello-folder hello.py
.\dist\hello-folder\hello-folder.exe
실행 결과는 Hello, packaging!입니다. dist\hello-folder 안에 EXE와 지원 파일이 생기므로 그 폴더 전체를 배포합니다. EXE만 복사하면 필요한 라이브러리를 찾지 못할 수 있습니다. 현재 방식에서는 지원 파일이 _internal 아래에 놓일 수 있으며, 정확한 구성은 패키지와 옵션에 따라 달라집니다.
build에는 중간 작업과 진단 파일이, hello-folder.spec에는 빌드 설정이 기록됩니다. 일반 사용자가 받을 결과물은 dist 쪽이며, build와 .venv를 함께 배포하는 것이 아닙니다. 옵션의 전체 의미는 PyInstaller 사용법을 참고합니다.
하나의 EXE로 묶기
폴더 방식이 정상 작동하면 같은 소스를 단일 파일로 빌드합니다. 예제는 다른 이름을 사용하므로 앞의 폴더 결과와 비교할 수 있습니다.
.\.venv\Scripts\python.exe -m PyInstaller --onefile --name hello-single hello.py
.\dist\hello-single.exe
dist\hello-single.exe 하나로 배포할 수 있고 실행 문구는 동일합니다. 단일 파일은 실행 시 내부 파일을 임시 위치에 풀기 때문에 시작이 더 느릴 수 있습니다. 결과물 크기나 시작 시간을 일률적으로 보장할 수 없으며, 실제 프로그램으로 판단해야 합니다.
이 예제는 콘솔 프로그램이므로 --windowed를 붙이지 않습니다. 그 옵션은 콘솔을 쓰지 않는 GUI 프로그램에 검토할 수 있지만, print()·input() 기반 프로그램에 무조건 붙이면 출력과 입력, 오류 확인이 어려워집니다. 원인을 해결하지 않은 채 관리자 권한 실행이나 보안 프로그램 해제를 기본 해결책으로 삼지 않습니다.
폴더·단일 파일 예제는 Windows에서 Python 3.12.14와 PyInstaller 6.22.3으로 빌드하고 출력을 확인했습니다. 같은 호스트의 콘솔 예제 검증이며, Python이 없는 별도 PC나 GUI 동작까지 확인한 결과는 아닙니다.
텍스트·이미지 같은 데이터 파일 포함
코드가 읽는 데이터는 자동으로 모두 포함된다고 가정하면 안 됩니다. 작업 폴더에 message.txt를 UTF-8로 만들고 Hello from bundled data!를 한 줄로 저장합니다. 같은 위치에 hello_data.py를 다음 전체 코드로 만듭니다.
from pathlib import Path
message = Path(__file__).resolve().with_name("message.txt")
print(message.read_text(encoding="utf-8").strip())
Hello from bundled data!
소스 실행과 아래 빌드 실행에서 예상한 문구가 같아야 합니다. __file__ 기준 경로는 현재 터미널의 폴더에 의존하지 않으며, 번들 내부 파일 위치를 찾는 데 사용할 수 있습니다.
.\.venv\Scripts\python.exe -m PyInstaller --onefile --name hello-data --add-data "message.txt:." hello_data.py
.\dist\hello-data.exe
--add-data "message.txt:."는 파일을 번들의 최상위 위치에 포함합니다. 현재 문서의 구분자는 콜론이며, 오래된 글의 플랫폼별 구분자 예제를 그대로 섞지 않습니다. 데이터 포함 규칙에 맞춰 이미지·설정 등의 위치도 일치시켜야 합니다. 단일 파일의 내부 데이터에 쓴 변경 사항은 실행 종료 후 보존된다고 볼 수 없습니다. 사용자가 저장할 설정·결과는 별도의 쓰기 가능한 사용자 경로에 저장합니다.
실패했을 때와 배포 전 확인
- EXE가 바로 닫히면 더블 클릭 대신 PowerShell에서 실행해 오류를 읽습니다. 먼저 소스 파일 자체가 같은 가상환경에서 실행되는지 확인합니다.
- 모듈을 못 찾으면 해당 환경의 설치 상태와 실제 가져오기 방식을 확인합니다. 동적으로 불러오는 모듈은 추가 수집 설정이 필요할 수 있습니다.
build\이름\warn-이름.txt를 보되 모든 경고가 치명적인 오류인 것은 아닙니다. - 데이터를 못 찾으면
--add-data의 목적 위치와 코드의 경로를 비교합니다. 폴더 방식으로 돌아가 구성 파일과 실행 경로를 확인하면 범위를 좁히기 쉽습니다. - 배포 대상과 같은 운영체제·아키텍처의 환경에서 실제 기능을 확인합니다. 특히 Python이 없는 별도 테스트 환경, 파일 접근, 외부 프로그램 의존성, 사용 패키지의 재배포 조건을 점검합니다.
진단 절차는 PyInstaller 문제 해결 문서를 참고합니다. 빌드 명령과 실행 명령을 구분하고, 문제를 재현하는 소스·패키지 버전·오류 메시지를 함께 기록하면 원인을 좁히는 데 도움이 됩니다.




