.. _building-from-source: 소스에서 PyPy 빌드하기 ====================== RPython은 Python2 방언(dialect)이므로, PyPy 빌드에는 Python2 인터프리터가 필요합니다. PyPy를 빌드하려면 먼저 미리 빌드된 PyPy2.7을 설치하는 것을 권장합니다(:doc:`install` 참조). CPython2.7으로 PyPy를 빌드하는 것도 가능하지만, 실행하는 데 훨씬 더 오래 걸립니다 -- 아키텍처에 따라 2배에서 3배 정도 더 걸립니다. PyPy2.7을 사용하여 PyPy를 빌드하는 경우에도, 변환에는 시간이 오래 걸리며 -- 빠른 머신에서 20분 -- 메모리도 많이 소모합니다. 32비트 머신에서는 **최소** 3GB, 64비트 머신에서는 6GB의 메모리가 필요합니다. 시작하기 전에 ------------- 저희의 일반적인 개발 워크플로는 테스트 주도 개발을 사용함으로써 전체 변환\ 을 피합니다. PyPy 개발 방법에 대한 자세한 내용은 here_\ 를 참고하시기 바라며, 최신 번역(translation)된 (바라건대 작동하는) 바이너리 패키지는 저희 buildbot의 `nightly builds`_\ 에서 확인하실 수 있습니다. .. _here: contributing.html .. _`nightly builds`: https://buildbot.pypy.org/nightly 테스트를 실행하려면 아래의 빌드 의존성이 필요합니다. 저장소를 복제합니다 ------------------- 직접 PyPy를 컴파일하고 싶거나 수정하고 싶다면, 소스 코드 사본을 받아야 합니다. 이는 `downloading them from the download page`_\ 를 하거나, git을 사용하여 저장소에서 체크아웃하는 방법으로 가능합니다. 최신 개발 버전에 접근하고 싶다면 git 사용을 권장합니다. .. _downloading them from the download page: https://www.pypy.org/download.html 명령줄, DOS 박스 또는 터미널에서 다음 명령을 실행해야 합니다:: git clone https://github.com/pypy/pypy.git 이것은 저장소를 클론하여 ``pypy``\ 라는 디렉터리에 배치하며, ``pypy/pypy``\ 에서 PyPy 소스를, ``pypy/pypy/doc``\ 에서 문서 파일을 얻게 됩니다. 저희는 tip이 항상 안정적으로 유지되도록 노력하지만, 가끔 깨질 수 있습니다. `our nightly tests`_\ 를 확인해 보는 것도 좋습니다: 예를 들어 "963e808156b3"처럼 최소한 ``{linux64}`` 테스트를 통과한(``success`` 줄의 ``+`` 기호에 해당) 리비전 해시를 찾은 다음, 클론한 저장소에서 다음을 사용해 이 리비전으로 전환합니다:: git checkout XXXXX 여기서 ``XXXXX``\ 는 리비전 해시입니다. .. _our nightly tests: https://buildbot.pypy.org/summary?branch=main 빌드 타임 의존성 설치 --------------------- .. note:: Windows에서 Python 인터프리터를 번역(translation)하는 방법에 대한 몇 가지 힌트는 :ref:`Windows 문서 `\ 를 참조하십시오. 호스트 Python2에는 CFFI가 설치되어 있어야 합니다. PyPy에서 번역(translation)하는 경우, CFFI는 이미 설치되어 있습니다. CPython에서 번역(translation)하는 경우, 예를 들어 ``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 모듈이 빌드되지 않습니다(이를 빌드하려면 :source:`lib_pypy/pypy_tools/build_cffi_imports.py`\ 를 실행하거나 다시 실행하면 됩니다. 전체 PyPy를 다시 번역(translation)할 필요는 없습니다): sqlite3 libsqlite3 _ssl, _hashlib libssl curses libncurses-dev (PyPy2용) libncursesw-dev (PyPy3용) gdbm libgdbm-dev tk tk-dev lzma (PyPy3 전용) liblzma 또는 libxz, 버전 5 이상 번역(translation)되지 않은 테스트를 실행하려면 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와 함께 설치됩니다. ``libx11``\ 은 ``tkinter``\ 에 필요합니다. ``openssl``\ 은 테스트를 위해 설치되어야 하며, brew로 제공되는 pypy를 사용하면 변환 속도가 빨라집니다. 아키텍처에 맞는 x86_64 또는 arm64 ``brew`` 명령을 사용해야 한다는 점에 유의하십시오: .. code-block:: shell 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입니다. | +------------------------+-----------------------------------------------------------+ 변환을 실행하십시오 ------------------- 번역(translation) 대상 Python은 CFFI가 필요하므로, virtualenv를 만들고 그곳에서 ``pip install cffi``\ 를 실행하는 것이 가장 좋습니다. 저희는 보통 ``pypy/goal`` 디렉터리\ 에서 번역(translation)을 수행하므로, 이어지는 모든 명령어는 ``$pwd``\ 가 그곳에 있다고 가정합니다. JIT를 사용해 번역(translation)하기:: pypy2.7 ../../rpython/bin/rpython --opt=jit JIT 없이 번역(translation):: pypy2.7 ../../rpython/bin/rpython --opt=2 참고로, 이는 ``targetpypystandalone.py`` 파일을 통해 pypy를 번역(translation)하는 것이며, 따라서 이것들은 다음의 축약형입니다:: pypy2.7 ../../rpython/bin/rpython targetpypystandalone.py ``--help``\ 를 통해 두 옵션 위치 모두에서 더 많은 도움말을 확인할 수 있으며, 더 자세한 정보는 :doc:`config/index` 섹션에서 찾을 수 있습니다. (여기서 ``pypy2.7`` 대신 ``python2``\ 를 사용할 수도 있는데, 시간이 더 걸리지만 이 역시 동작합니다.) 모든 것이 올바르게 작동하면 다음과 같이 진행됩니다: 1. RPython `translation chain`_\ 을 실행하여, PyPy 인터프리터 전체의 데이터베이스를 생성합니다. 현재 이 단계는 단일 스레드로 동작하며, RAM을 많이 사용합니다. 이 단계의 일부로, 체인은 ``PYPY_USESSION_DIR`` 환경 변수로 제어되는 디렉터리에 다수의 C 코드 파일과 이를 컴파일할 Makefile을 생성합니다. 2. Makefile을 실행하여 실행 파일 ``pypy-c``\ 나 ``pypy3.XX-c``\ 를 생성합니다. 이 단계는 머신에서 사용 가능한 모든 코어를 활용할 수 있습니다. 3. 필요한 바이너리를 현재 디렉터리로 복사합니다. 4. cffi 기반 stdlib 모듈에 대해 c-확장 모듈을 생성합니다. 생성된 실행 파일은 대부분 일반 Python 인터프리터처럼 동작하며(:doc:`cpython_differences` 참조), 테스트하거나, 새 virtualenv의 기본 인터프리터로 사용하거나, 빌드 머신과 동일한 OS를 실행하는 다른 머신에 설치할 수 있는 바이너리로 패키징하는 데 바로 사용할 수 있습니다. 4단계는 단순히 편의를 위\ 해 수행되는 것이며, 어떤 단계든 이전 단계를 다시 실행하지 않고도 재실행할 수 있습니다. .. _`translation chain`: https://rpython.readthedocs.io/en/latest/translation.html PyPy\ 의 디버그 빌드 만들기 --------------------------- ``Makefile``\ 을 ``make lldebug`` 또는 ``make lldebug0`` 타겟으로 다시 실행하십시오. 그러면 디버거에서 실행하는 것이 의미 있는 방식으로 빌드됩니다. 디버그 정보를 추가하기 위해 적절한 컴파일 플래그가 추가되며, ``lldebug0``\ 의 경우 컴파일러 최적화가 완전히 비활성화됩니다. 디버거에서 멈추면 rpython 변환 단계에서 기계적으로 생성된 매우 장황한 C 코드를 보게 되며, 이를 rpython 코드와 연관지으려면 조금 읽어봐야 합니다. 표준 라이브러리를 위한 cffi 임포트 라이브러리 빌드 -------------------------------------------------- 다양한 표준 라이브러리 모듈은 :ref:`out-of-line API mode `\ 에서 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``\ 는 설정되지 않으며, 일부 기존 라이브러리는 이런 경우가 절대 없다고 가정합니다.