ARM용 크로스 번역(translation)

Note

여기의 정보는 안타깝게도 역사적 가치만 있을 뿐입니다. Scratchbox는 더 이상 작동하지 않습니다. 그러나 chroot와 setarch linux32 pypy rpython/bin/rpython ...를 사용하면 aarch64 머신에서 ARM32의 번역(translation)이 가능한 것으로 보입니다.

여기서는 크로스 컴파일 툴체인을 사용하여 RPython 번역기(translator)로 인터프리터를 ARM 대상으로 번역(translation)하는 데 필요한 설정과 따라야 할 단계를 설명합니다.

ARM용 RPython 프로그램을 번역(translation)하려면 일반적인 번역(translation) 단계를 따라 ARM 기기에서 직접 번역(translation)할 수 있습니다. 하지만 안타깝게도 대부분의 ARM 기기에서는 이것이 실제로 가능하지 않습니다. 대안은 교차 컴파일 툴체인을 사용해 교차 번역(translation)하는 것입니다.

교차 번역(cross-translate)을 하려면 더 강력한(보통 x86) 머신에서 번역(translation)을 실행하고, 크로스 컴파일러를 사용해 생성된 C 코드를 컴파일하여 ARM용 바이너리를 생성합니다. 이 작업을 수행할 때는 몇 가지 제약이 있습니다. 특히 현재는 번역(translation) 호스트 및 대상 플랫폼으로 Linux만 지원합니다(Ubuntu에서 테스트됨). 또한 번역(translation)을 실행하려면 32비트 환경이 필요합니다. 이는 32비트 호스트 또는 32비트 chroot에서 수행할 수 있습니다.

요구 사항

Linux 기반 호스트에서 ARM 기반 Linux 대상으로 크로스 번역(translation)하는 데 필요한 도구는 다음과 같습니다.

  • PyPy(기본 브랜치)의 체크아웃입니다.
  • GCC ARM 크로스 컴파일러(Ubuntu에서는 gcc-arm-linux-gnueabi package임)가 필요하지만, 다른 툴체인도 동작할 것입니다.
  • Scratchbox 2, 크로스 컴파일 엔진(scratchbox2 Ubuntu 패키지)입니다.
  • 32비트 PyPy 또는 Python입니다.
  • 그리고 ARM 기반 chroot를 생성하려면 다음(또는 이에 대응하는) 패키지들이 설치되어 있어야 합니다:
    • debootstrap
    • schroot
    • binfmt-support
    • qemu-system
    • qemu-user-static
  • 위의 종속성들은 일반적인 번역(translation)에 필요한 종속성에 더해 추가로 필요한 것으로, listed here에 나열되어 있습니다.

Qemu 기반 ARM chroot 생성

먼저 PyPy 또는 다른 인터프리터를 번역(translation)하는 데 필요한 패키지와 의존성을 포함하는 rootfs를 생성해야 합니다. 파일이 /srv/chroot/precise_arm에 위치한다고 가정하겠습니다.

다음을 호출하여 rootfs를 생성하십시오:

mkdir -p /srv/chroot/precise_arm
qemu-debootstrap --variant=buildd --arch=armel precise /srv/chroot/precise_arm/  http://ports.ubuntu.com/ubuntu-ports/

다음으로, qemu-arm-static 바이너리를 rootfs에 복사하십시오.

cp /usr/bin/qemu-arm-static /srv/chroot/precise_arm/usr/bin/qemu-arm-static

더 쉬운 설정과 관리를 위해 rootfs를 가리키는 schroot를 생성하겠습니다. /etc/schroot/schroot.conf에 있는 schroot 설정 파일에 (아래와 같은) 설정 블록을 추가해야 합니다.

[precise_arm]
directory=/srv/chroot/precise_arm
users=USERNAME
root-users=USERNAME
groups=users
aliases=default
type=directory

chroot 환경에서 모든 것이 제대로 작동하는지 확인하려면, schroot -c precise_arm을 실행하면 qemu-arm을 사용하여 ARM 바이너리를 실행하는 schroot 환경에서 셸이 시작되어야 합니다. chroot에서 uname -m을 실행하면 armv7l과 같은 결과가 나와야 합니다. 이는 우리가 ARM 시스템을 에뮬레이트하고 있음을 보여줍니다.

apt 소스를 설정하고 다음 패키지들을 설치하려면 root 사용자로 schroot를 시작하십시오:

schroot -c precise_arm -u root
echo "deb http://ports.ubuntu.com/ubuntu-ports/ precise main universe restricted" > /etc/apt/sources.list
apt-get update
apt-get install libffi-dev libgc-dev python-dev build-essential libncurses5-dev libbz2-dev

이제 모든 종속성이 준비되었으므로 schroot 환경을 종료할 수 있습니다.

scratchbox2 설정하기

scratchbox를 설정하려면 이전에 만든 rootfs의 루트 디렉터리로 cd해야 합니다. 거기서 sb2 설정 도구를 호출할 수 있으며, 이 도구는 현재 디렉터리를 scratchbox2 환경의 기본 디렉터리로 사용합니다.

cd /srv/chroot/precise_arm
sb2-init -c `which qemu-arm` ARM `which arm-linux-gnueabi-gcc`

이 작업을 하면 scratchbox 내부에서 이루어진 gcc 호출을 scratchbox 외부의 arm-linux-gnueabi-gcc로 매핑하는, ARM이라는 이름의 scratchbox2 기반 환경이 생성됩니다. 이제 정상 동작하는 크로스 컴파일 툴체인이 갖춰졌으므로, ARM용 프로그램의 크로스 번역(translation)을 시작할 수 있습니다.

번역(translation)

모든 사전 준비 단계를 마쳤으니 이제 ARM용 프로그램을 크로스 번역(translation)할 수 있어야 합니다. 더 큰 프로젝트에 적용하기 전에 이 최소한의 타겟을 사용하여 설정을 테스트할 수 있습니다.

번역기(translator)가 scratchbox 환경을 사용하는 방법을 알 수 있도록, 번역기를 시작하기 전에 두 개의 환경 변수를 설정해야 합니다. rootfs를 가리키도록 SB2 환경 변수를 설정해야 하며, SB2OPT에는 sb2 명령의 명령줄 옵션이 포함되어야 합니다. 우리의 rootfs가 /srv/chroot/precise_arm 폴더에 있고 scratchbox 환경의 이름이 “ARM”이라면, 변수는 다음과 같이 정의됩니다.

export SB2=/srv/chroot/precise_arm
export SB2OPT='-t ARM'

이것이 설정되면 번역기(translator)를 호출할 수 있습니다. 예를 들어 이 파일을 저장하십시오.

def main(args):
    print "Hello World"
    return 0

def target(*args):
    return main, None

그리고 번역기(translator)를 호출합니다

pypy ~/path_to_pypy_checkout/rpython/bin/rpython -O2 --platform=arm target.py

모든 것이 올바르게 작동했다면 이것은 ARM 바이너리를 만들어내야 합니다. 이 바이너리를 ARM chroot에서 또는 ARM 장치에서 실행하면 "Hello World" 출력을 만들어내야 합니다.

JIT을 갖춘 전체 파이썬 PyPy 인터프리터를 번역(translation)하려면 pypy/goal로 이동하여 다음을 호출하면 됩니다.

pypy <path to rpython>/rpython/bin/rpython -Ojit --platform=arm targetpypystandalone.py