소스에서 PyPy 빌드하기¶
RPython은 Python2 방언이므로 PyPy를 빌드하려면 Python2 인터프리터가 필요합니다. PyPy를 빌드하려면 먼저 미리 빌드된 PyPy2.7을 설치할 것을 권장합니다(PyPy 다운로드 및 설치 참조). CPython2.7로도 PyPy를 빌드할 수 있지만, 실행 시간이 훨씬 오래 걸립니다 – 아키텍처에 따라 두 배에서 세 배가량 걸립니다.
PyPy2.7로 PyPy를 빌드하더라도 변환에는 시간이 오래 걸리고(빠른 머신에서 20분) RAM도 많이 소모됩니다. 32비트 머신에서는 최소 3 GB, 64비트 머신에서는 6GB의 메모리가 필요합니다.
시작하기 전에¶
저희의 일반적인 개발 워크플로는 테스트 주도 개발을 활용하여 전체 변환을 피합니다. PyPy를 개발하는 방법은 here에서 더 자세히 읽어 보실 수 있으며, 최근에 변환된 (제대로 동작하기를 바라는) 바이너리 패키지는 저희 buildbot의 nightly builds에서 받으실 수 있습니다.
테스트를 실행하려면 아래의 빌드 의존성이 필요합니다.
저장소를 복제하십시오¶
PyPy를 직접 컴파일하고 싶거나 수정하고 싶다면 소스 코드 사본을 받아야 합니다. 소스 코드는 downloading them from the download page 방식으로 받거나, git을 사용하여 저장소에서 체크아웃하여 받을 수 있습니다. 현재 개발 버전에 접근하고 싶다면 git을 사용하는 것을 권장합니다.
명령줄, DOS 창 또는 터미널에서 다음 명령을 실행해야 합니다.:
git clone https://github.com/pypy/pypy.git
이 명령은 저장소를 복제하여 pypy라는 디렉터리에 넣으며, pypy/pypy에는 PyPy 소스를, pypy/pypy/doc에는 문서 파일을 받게 됩니다. 저희는 tip이 항상 안정적인 상태를 유지하도록 노력하지만, 가끔 깨져 있을 수도 있습니다. our nightly tests를 확인해 보는 것이 좋습니다. 최소한 {linux64} 테스트를 통과한(success 줄의 + 기호에 해당) 리비전 해시(예: “963e808156b3”)를 찾은 다음, 복제한 저장소에서 다음 명령으로 해당 리비전으로 전환하십시오.:
git checkout XXXXX
여기서 XXXXX는 리비전 해시입니다.
빌드 시 필요한 의존성 설치¶
Note
Windows에서 Python 인터프리터를 변환하는 방법에 관한 몇 가지 도움말은 Windows 문서를 참조하십시오.
호스트 Python2에 CFFI가 설치되어 있어야 합니다. PyPy에서 변환하는 경우에는 CFFI가 이미 설치되어 있습니다. CPython에서 변환하는 경우에는 CFFI를 직접 설치해야 합니다. 예를 들어 python2.7 -mpip install cffi를 사용하여 설치할 수 있습니다.
C 변환 백엔드를 사용하여 Unix에서 PyPy를 빌드하려면 최소한 C 컴파일러와 make가 설치되어 있어야 합니다. 또한 일부 선택적 모듈에는 추가 의존성이 있습니다:
- cffi, ctypes
- libffi, pkg-config
- zlib
- libz
- bz2
- libbz2
- pyexpat
- libexpat1
- _vmprof
- libunwind(선택 사항이며, 런타임에 동적으로 로드됩니다)
PyPy를 빌드하기 전에 이 라이브러리들을 (개발 헤더와 함께) 반드시 설치해 두십시오. 그렇지 않으면 빌드된 바이너리에 이 모듈들이 포함되지 않습니다. 또한 PyPy를 빌드한 후에는 다음 라이브러리들이 있어야 합니다. 그렇지 않으면 해당 CFFI 모듈들이 빌드되지 않습니다(이 모듈들을 빌드하려면 lib_pypy/pypy_tools/build_cffi_imports.py를 실행하거나 다시 실행하면 됩니다. PyPy 전체를 다시 변환할 필요는 없습니다):
- sqlite3
- libsqlite3
- _ssl, _hashlib
- libssl
- curses
- libncurses-dev (PyPy2용) libncursesw-dev (PyPy3용)
- gdbm
- libgdbm-dev
- tk
- tk-dev
- lzma (PyPy3 전용)
- liblzma 또는 libxz, 버전 5 이상
변환되지 않은 테스트를 실행하려면 Boehm 가비지 컬렉터인 libgc 7.4 이상 버전이 필요합니다.
Debian 및 Ubuntu(16.04 이상)에서 빌드에 필요한 모든 의존성을 설치하는 명령은 다음과 같습니다.:
apt-get install gcc make libffi-dev pkg-config zlib1g-dev libbz2-dev \
libsqlite3-dev libncurses5-dev libexpat1-dev libssl-dev libgdbm-dev \
tk-dev libgc-dev \
liblzma-dev libncursesw5-dev # These two are only needed on PyPy3
Fedora에서:
dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \
sqlite-devel ncurses-devel expat-devel openssl-devel tk-devel \
gdbm-devel gc-devel \
xz-devel # For lzma on PyPy3.
SLES11에서:
zypper install gcc make python-devel pkg-config \
zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
libexpat-devel libffi-devel \
xz-devel # For lzma on PyPy3.
(XXX plus the SLES11 version of libgdbm-dev and tk-dev)
Mac OS X에서는 다음과 같습니다:
현재 PyPy는 Apple Silicon(M1, Arm64)과 X86_64에서의 빌드를 모두 지원합니다. 빌드할 때는 arm64 또는 x86_64 중 알맞은 툴체인을 사용해야 합니다. “Fat” universal2 빌드는 지원하지 않습니다.
빌드 시점 의존성은 대부분 Developer Tools와 함께 설치됩니다. tkinter에는 libx11이 필요합니다. 테스트를 위해서는 openssl을 설치해야 하며, brew로 설치한 pypy를 사용하면 변환 속도가 빨라집니다. 아키텍처에 맞는 x86_64 또는 arm64용 brew 명령을 사용해야 한다는 점에 유의하십시오:
xcode-select --install
brew install openssl pypy pkg-config libx11
# expose openssl in the cffi _ssl_build script
export CPPFLAGS=$(pkg-config openssl --cflags-only-I)
export LDFLAGS=$(pkg-config openssl --libs-only-L)
변환에 영향을 줄 환경 변수를 설정하십시오¶
다음 환경 변수를 사용하여 결과를 조정할 수 있습니다.
| 값 | 결과 |
| CC | 사용할 컴파일러 |
| PYPY_MULTIARCH | pypy 3.7+: posix에서는 sys.platform._multiarch에
저장되며, 기본값은 x86_64-linux-gnu입니다. |
| PYPY_USESSION_DIR | 임시 파일을 저장하는 기본 디렉터리이며, 보통 $TMP입니다. |
| PYPY_USESSION_BASENAME | from rpython.tools import udir를 호출할 때마다
$PYPY_USESSION_DIR/usession-$PYPY_USESSION_BASENAME-N
임시 디렉터리를 받게 되며, 여기서 N은 호출할 때마다
증가합니다. |
| PYPY_USESSION_KEEP | 보관할 이전 임시 디렉터리의 개수이며, 이보다 오래된 디렉터리는 삭제됩니다. 기본값은 3입니다. |
변환 실행하기¶
변환을 수행하는 Python에는 CFFI가 필요하므로, virtualenv를 만든 다음 그 안에서 pip install cffi를 실행하는 것이 가장 좋습니다.
일반적으로 pypy/goal 디렉터리에서 변환을 수행하므로, 이후의 모든 명령은 $pwd가 해당 디렉터리라고 가정합니다.
JIT를 포함하여 변환하기:
pypy2.7 ../../rpython/bin/rpython --opt=jit
JIT 없이 변환하기:
pypy2.7 ../../rpython/bin/rpython --opt=2
참고로 이 명령은 targetpypystandalone.py 파일을 통해 pypy를 변환하므로, 이들은 다음의 축약형입니다:
pypy2.7 ../../rpython/bin/rpython <rpython options> targetpypystandalone.py <pypy options>
두 옵션 위치 중 어디에서든 --help를 사용하면 더 많은 도움말을 볼 수 있으며, 더 자세한 정보는 PyPy 설정 옵션 절에서 확인할 수 있습니다.
(여기서 pypy2.7 대신 python2를 사용할 수도 있습니다. 시간은 더 오래 걸리지만 이 방법으로도 동작합니다.)
모든 것이 올바르게 작동하면 다음과 같이 진행됩니다:
- RPython translation chain을 실행하여 PyPy 인터프리터 전체의 데이터베이스를 생성합니다. 이 단계는 현재 단일 스레드로 동작하며 RAM을 많이 사용합니다. 이 단계에서 체인은
PYPY_USESSION_DIR환경 변수로 지정된 디렉터리에 다수의 C 코드 파일과 이를 컴파일하기 위한 Makefile을 생성합니다. - Makefile을 실행하여 실행 파일
pypy-c또는pypy3.XX-c를 생성합니다. 이 단계에서는 머신에서 사용할 수 있는 모든 코어를 활용할 수 있습니다. - 필요한 바이너리를 현재 디렉터리에 복사하십시오.
- 모든 CFFI 기반 표준 라이브러리 모듈에 대해 C 확장 모듈을 생성합니다.
이렇게 만들어진 실행 파일은 대체로 일반 Python 인터프리터처럼 동작하며(PyPy와 CPython의 차이점 참조), 바로 테스트하거나, 새 virtualenv의 기본 인터프리터로 쓰거나, 빌드 머신과 같은 OS를 실행하는 다른 머신에 설치할 수 있는 바이너리로 패키징할 수 있습니다.
4단계는 단지 편의를 위해 수행하는 것일 뿐이며, 어느 단계든 이전 단계를 다시 실행하지 않고 재실행할 수 있다는 점에 유의하십시오.
PyPy 디버그 빌드 만들기¶
make lldebug 또는 make lldebug0 타깃으로 Makefile을 다시 실행하십시오. 그러면 디버거에서 실행하기에 적합한 방식으로 빌드됩니다. 디버그 정보를 추가하기 위한 적절한 컴파일 플래그가 추가되며, lldebug0의 경우 컴파일러 최적화가 완전히 비활성화됩니다. 디버거에서 실행을 멈추면 RPython 변환 단계에서 기계적으로 생성된 매우 장황한 C 코드를 보게 되며, 이 코드를 원래의 RPython 코드와 연관 지으려면 코드를 어느 정도 읽어 보아야 합니다.
표준 라이브러리용 cffi 임포트 라이브러리 빌드¶
여러 표준 라이브러리 모듈은 out-of-line API 모드로 cffi 임포트 라이브러리를 생성하기 위해 별도의 빌드 단계가 필요합니다. 이 작업은 다음 명령으로 수행합니다:
cd pypy/goal
PYTHONPATH=../.. ./pypy-c ../../lib_pypy/pypy_tools/build_cffi_imports.py
패키징(설치 준비)¶
같은 머신에 설치하는 경우라도 PyPy를 시스템 전역에 설치하려면 패키징이 필요합니다. 패키징을 하면 여러 추가 기능이 미리 준비되는데, root로 설치된 PyPy에서는 일반 사용자에게 쓰기 권한이 없으므로 이 기능들을 필요할 때 나중에 준비할 수 없기 때문입니다. 이는 주로 평소라면 처음 임포트될 때 컴파일되는 라이브러리에 해당합니다.
python pypy/tool/release/package.py --archive-name=pypy-VER-PLATFORM
이 작업은 정리되고 준비된 디렉터리 계층과 함께 같은 내용을 담은 .tar.bz2 파일도 만듭니다. 이 결과물이 있는 디렉터리는 화면에 출력됩니다. 그런 다음 파일 계층을 옮기거나 .tar.bz2 파일을 올바른 위치에 풀면 됩니다.
사용자 정의 스크립트는 언젠가는 반드시 낡게 되므로 package.py를 사용할 것을 권장합니다. 그래도 사용자 정의 스크립트를 작성하려는 경우, 놓치기 쉬운 점 하나에 유의하십시오. 일부 모듈은 CFFI로 작성되어 있어 약간의 컴파일이 필요합니다. 이 모듈들을 미리 컴파일하지 않고 root 권한으로 PyPy를 설치하면 일반 사용자에게 오류가 발생합니다.
설치¶
PyPy는 실행 파일의 위치에 따라 라이브러리 위치를 동적으로 찾습니다. 일반적인 PyPy2 설치본의 디렉터리 계층 구조는 다음과 같습니다:
./bin/pypy
./include/
./lib_pypy/
./lib-python/2.7
./site-packages/
PyPy3.8+ 설치는 CPython과 같은 디렉터리 구조를 따릅니다.:
./bin/
./include/pypy3.8/include
./lib/pypy3.8
위에 표시된 계층 구조는 PREFIX 디렉터리를 기준으로 한 상대 경로입니다. PREFIX는 실행 파일이 있는 디렉터리에서 시작하여 lib_pypy와 lib-python/2.7을 포함하는 디렉터리(pypy2의 경우)를 찾을 때까지 파일 시스템을 “거슬러 올라가며” 계산합니다.
유닉스 계열 시스템에서 PyPy를 시스템 전역에 설치하려면 전체 디렉터리 계층을 별도의 위치(예: /opt/pypy)에 두고, pypy 실행 파일을 가리키는 심볼릭 링크를 /usr/bin 또는 /usr/local/bin에 두는 것을 권장합니다.
실행 파일이 적절한 라이브러리를 찾지 못하면 debug: WARNING: library path not found, using compiled-in sys.path를 보고한 다음 정상적으로 계속 진행하려고 시도합니다. 기본 경로를 사용할 수 있다면 대부분의 코드는 문제없이 동작합니다. 그러나 sys.prefix가 설정되지 않은 상태가 되며, 기존 라이브러리 중 일부는 이런 경우가 절대 없다고 가정합니다.