How to create .EXE file in Python using cx_Freeze
파이썬은 웹서버를 할당하거나 소유하고 있는 기기에서 실행하는 용도로 프로그래밍하기에 매우 좋다. 하지만 만든 어플을 친구나 사용자에게 배포하려하면 매우 성가시다.
- "이거 동작하지를 않아. 어떻게 실행하는지 모르겠어"
- "너 Python Interpreter 설치 했어?
- "아니, 그게 뭔데?"
- "너 그걸 설치해야 실행할수 있어. www.python.org 여기서 *.*version을 받아"
- "아 그래? 나 그냥 다른거 사용할께"
보통 이런 상황이 펼쳐진다. 만약 본인이 만든 소프트웨어를 Python을 사용하는 개발자에게 전달하는게 아니라면, 실행가능한 패키지를 선호할 것이다. 추천하는 해결책은 cx_Freeze이다. py2exe와는 조금 다르다. 이것은 교차 플랫폼(cross platform)이다. 윈도우나 OSX, Linux 환경의 패키지를 빌드하는데 사용된다.
이 포스트는 어떻게 3가지 플랫폼환경에서 PyQt4 GUI 어플을 패키지하는지 설명하려 한다. 사용할 샘플 어플은 PyQt4 설명서(www.zetcode.com)에 있는 테트리스 복제(Tetris clone)이다. 이곳(http://zetcode.com/gui/pyqt4/thetetrisgame/)으로 가서 게임의 모든 코드를 복사하고 tetris.py 파일로 저장한다.
아래 명령어로 cz_Freeze를 설치한다.
설치가 완료되면 아래와 같이 확인 할 수 있다.
이제 tetris.py가 저장되어 있는 디렉토리로 이동하고 초기 setup.py을 생성하기 위해 quickstart 명령어를 실행한다.
setup.py는 cx_Freeze에게 어플을 어떻게 패키지할 것인지 설정하는 스크립트로 구성된다. 몇몇 정보를 입력해야 하는데 Python file을 무엇으로 실행할 것인지 스크립트의 이름을 입력한다. 이것은 tetris.py로 입력한다. 이렇게 만들어진 setup.py 아래와 같다.
중요한 코드에 대해서 알아본다.
cx_Freeze는 패키지 어플을 만들 때 뭐가 필요되어지는지 해결하려고 시도하지만, 프로그램에서 다양한 모듈이 Impor(import sys, os 등) 로 사용되었다면 사용자가 직접 특정 구성요소를 입력해야 할수 있다.
"packages"와 "excludes"는 자동으로 생성된 빌드 옵션 사전에 포함된다. 다른 추가적인 주요 요소는 "includes" 와 "include_files"이다. "includes"는 포함 될 필요가 있는 모듈 리스트를 갖고 include_files는 파이썬 파일이 아닌 파일 리스트를 갖는다.(아래 참고)
다음 관심이 갈만한 줄은 아래이다.
setup.py를 좀더 살펴보면 아래 줄을 볼수 있다.
cxFreeze.Excutable class의 경우는 프로그램의 메인 시작 파일을 예로 들어 설명하기로 한다.
일반적으로 하나의 실행파일을 가지지만, 더 많은 실행파일을 가질수도 있다. 이 경우 명령어 도구 모음(a suite of command line tools)을 패킹한다. 사용자가 설정한 빌드 옵션 내용과 프로그램 이름, 버전, 설명등 다른 설정사항을 거쳐 파일의 마지막 부분은 셋업 기능을 호출한다. tetris.py 스크립트를 위해 setup.py를 고칠필요는 없다. set up을 실행하는 것으로 패키지 빌드를 진행할수 있다.
cx_Freeze에 몇몇 드러난 문제점이 있다. 사용자가 빌드 커맨드를 실행할때, 어떤 import들은 정의되지 않았는데도 빌드가 완료될 것이다. 문제가 되지 않는 경우도 있지만, 모든 파일들이 패키지에 확실히 포함되었는지 확인해야만 한다. 빌드 명령어는 플랫폼 폴더에 전부 쏟아 넣는다. Linux를 위한 패키징할때는 a .tar.gz 형식을 추천하지만 OSX와 Windws는 특정 패키징 명령어를 써야한다.
OSX는, a.dmg 또는 a.app 형식의 두가지 빌드 옵션을 갖는다.(아래 참고)
Windows는, a.msi 형식으로 빌드한다.(아래 참고)
안타깝게도, 하나의 플랫폼환경에서 다른 형식의 파일로 빌드하지 못한다. windows는 windows에 맞게 OSX는 OSX에 맞게 빌드할 수있다. 하지만 setup.py파일은 공용된다.
끝내기전에, 패키지된 어플안에 접근파일에 대해서 언급하려 한다. 패키지 파일이 실행될 때, global__file__변수는 적용되지 않는다. 사용자가 os.path.dirname(__file__)를 사용해서 현재 경로에서 잡으려 한다면 동작하지 않을 것이다. os.path.dirname(sys.executable)을 사용해야한다. 다행히, 패키지 어플이 실행될때, sys안에 "frozen" 속성은 가능하다. 사용자는 어플이 실행중이건 아니건 상관없이 파일을 제어하기위해 해당 속성을 사용할 수 있다.
cx_Freeze Documentation은 이 기능을 시작 점으로 명시했다.
사용자는 이 기능을 executable처럼(not in a subdirectory) 사용자 데이터 파일이 저장된 상태에 맞게 약간 수정할 필요가 있다.
파이썬은 웹서버를 할당하거나 소유하고 있는 기기에서 실행하는 용도로 프로그래밍하기에 매우 좋다. 하지만 만든 어플을 친구나 사용자에게 배포하려하면 매우 성가시다.
- "이거 동작하지를 않아. 어떻게 실행하는지 모르겠어"
- "너 Python Interpreter 설치 했어?
- "아니, 그게 뭔데?"
- "너 그걸 설치해야 실행할수 있어. www.python.org 여기서 *.*version을 받아"
- "아 그래? 나 그냥 다른거 사용할께"
보통 이런 상황이 펼쳐진다. 만약 본인이 만든 소프트웨어를 Python을 사용하는 개발자에게 전달하는게 아니라면, 실행가능한 패키지를 선호할 것이다. 추천하는 해결책은 cx_Freeze이다. py2exe와는 조금 다르다. 이것은 교차 플랫폼(cross platform)이다. 윈도우나 OSX, Linux 환경의 패키지를 빌드하는데 사용된다.
이 포스트는 어떻게 3가지 플랫폼환경에서 PyQt4 GUI 어플을 패키지하는지 설명하려 한다. 사용할 샘플 어플은 PyQt4 설명서(www.zetcode.com)에 있는 테트리스 복제(Tetris clone)이다. 이곳(http://zetcode.com/gui/pyqt4/thetetrisgame/)으로 가서 게임의 모든 코드를 복사하고 tetris.py 파일로 저장한다.
아래 명령어로 cz_Freeze를 설치한다.
pip install cx_Freeze
이제 tetris.py가 저장되어 있는 디렉토리로 이동하고 초기 setup.py을 생성하기 위해 quickstart 명령어를 실행한다.
cxfreeze-quickstart
setup.py는 cx_Freeze에게 어플을 어떻게 패키지할 것인지 설정하는 스크립트로 구성된다. 몇몇 정보를 입력해야 하는데 Python file을 무엇으로 실행할 것인지 스크립트의 이름을 입력한다. 이것은 tetris.py로 입력한다. 이렇게 만들어진 setup.py 아래와 같다.
from cx_Freeze import setup, Executable
# Dependencies are automatically detected, but it might need
# fine tuning.
buildOptions = dict(packages = [], excludes = [])
import sys
base = 'Win32GUI' if sys.platform=='win32' else None
executables = [
Executable('tetris.py', base=base)
]
setup(
name='Tetris',
version = '0.1',
description = 'A PyQt Tetris Program',
options = dict(build_exe = buildOptions),
executables = executables
)
중요한 코드에 대해서 알아본다.
buildOptions = dict(packages = [], excludes = [])
build option은 파이썬이 어떤 패키지, 어떤 모듈 그리고 어떤 다른 파일(non-Python files such as assets)을 패키지 어플에 포함하는지 제어한다.cx_Freeze는 패키지 어플을 만들 때 뭐가 필요되어지는지 해결하려고 시도하지만, 프로그램에서 다양한 모듈이 Impor(import sys, os 등) 로 사용되었다면 사용자가 직접 특정 구성요소를 입력해야 할수 있다.
"packages"와 "excludes"는 자동으로 생성된 빌드 옵션 사전에 포함된다. 다른 추가적인 주요 요소는 "includes" 와 "include_files"이다. "includes"는 포함 될 필요가 있는 모듈 리스트를 갖고 include_files는 파이썬 파일이 아닌 파일 리스트를 갖는다.(아래 참고)
buildOptions = dict(packages = [],excludes = [],
includes = ["atexit"],
include_files = ["sqlite.db"])
다음 관심이 갈만한 줄은 아래이다.
base = 'Win32GUI' if sys.platform=='win32' else None
Window, GUI 어플은 다른 파이썬 기반을 요구한다. 해당 어플은 pythonw.exe interpreterd으로 실행되어지거나 명령어로 실행하고 프로그램 수행 동안 실행되는 상태를 유지한다.setup.py를 좀더 살펴보면 아래 줄을 볼수 있다.
executables = [Executable('tetris.py', base=base)]
cxFreeze.Excutable class의 경우는 프로그램의 메인 시작 파일을 예로 들어 설명하기로 한다.
일반적으로 하나의 실행파일을 가지지만, 더 많은 실행파일을 가질수도 있다. 이 경우 명령어 도구 모음(a suite of command line tools)을 패킹한다. 사용자가 설정한 빌드 옵션 내용과 프로그램 이름, 버전, 설명등 다른 설정사항을 거쳐 파일의 마지막 부분은 셋업 기능을 호출한다. tetris.py 스크립트를 위해 setup.py를 고칠필요는 없다. set up을 실행하는 것으로 패키지 빌드를 진행할수 있다.
python setup.py build
이 명령어는 프로젝트 하위에 새로운 'build' 디렉토리를 생성할 것이다. 이후에 exe파일이 담길 폴더가 생성되고 잇따라 사용자의 현재 플랫폼의 이름과 같이 생성된다. 빌드가 중복없이 다양한 플래폼에 대해 수행되어 질수 있도록 이와같이 진행된다.플렛폼 하위 폴더에서 실행 파일을 찾을수 있다.cx_Freeze에 몇몇 드러난 문제점이 있다. 사용자가 빌드 커맨드를 실행할때, 어떤 import들은 정의되지 않았는데도 빌드가 완료될 것이다. 문제가 되지 않는 경우도 있지만, 모든 파일들이 패키지에 확실히 포함되었는지 확인해야만 한다. 빌드 명령어는 플랫폼 폴더에 전부 쏟아 넣는다. Linux를 위한 패키징할때는 a .tar.gz 형식을 추천하지만 OSX와 Windws는 특정 패키징 명령어를 써야한다.
OSX는, a.dmg 또는 a.app 형식의 두가지 빌드 옵션을 갖는다.(아래 참고)
python setup.py bdist_dmg
python setup.py bdist_mac
Windows는, a.msi 형식으로 빌드한다.(아래 참고)
python setup.py bdist_msi
안타깝게도, 하나의 플랫폼환경에서 다른 형식의 파일로 빌드하지 못한다. windows는 windows에 맞게 OSX는 OSX에 맞게 빌드할 수있다. 하지만 setup.py파일은 공용된다.
끝내기전에, 패키지된 어플안에 접근파일에 대해서 언급하려 한다. 패키지 파일이 실행될 때, global__file__변수는 적용되지 않는다. 사용자가 os.path.dirname(__file__)를 사용해서 현재 경로에서 잡으려 한다면 동작하지 않을 것이다. os.path.dirname(sys.executable)을 사용해야한다. 다행히, 패키지 어플이 실행될때, sys안에 "frozen" 속성은 가능하다. 사용자는 어플이 실행중이건 아니건 상관없이 파일을 제어하기위해 해당 속성을 사용할 수 있다.
cx_Freeze Documentation은 이 기능을 시작 점으로 명시했다.
def find_data_file(filename):
if getattr(sys, "frozen", False):
# The application is frozen.
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen.
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
사용자는 이 기능을 executable처럼(not in a subdirectory) 사용자 데이터 파일이 저장된 상태에 맞게 약간 수정할 필요가 있다.
명령어 도구모음 패킹은 어떻게하나요?
답글삭제