Distcc/Cross-Compiling

From Gentoo Wiki
< Distcc
Jump to:navigation Jump to:search
This page is a translated version of the page Distcc/Cross-Compiling and the translation is 80% complete.
Outdated translations are marked like this.


이 안내서에서는 distcc에서의 다른 프로세서 아키텍처간 크로스컴파일 설정 방법을 보여줍니다.

distcc로 크로스컴파일

도입부

distcc는 네트워크에 연결한 다양한 컴퓨터에게 덩치가 큰 프로그램을 컴파일하도록 일감을 공유하는 도구입니다. 같은 프로세서 아키텍처로 만들어진 같은 툴체인을 네트워크에 연결한 여러대의 머신이 사용하면 distcc 설정을 따로 할 필요가 없습니다.

이 안내서는 다양한 아키텍처를 대상으로 컴파일 하도록 distcc를 설정하는 방법의 절차를 담고 있습니다.

필요한 유틸리티 이머지

먼저 컴파일 과정에 관여할 모든 머신에 crossdev를 이머지해야 합니다. crossdev는 크로스 아키텍처 툴체인을 쉽게 빌드할 수 있게 만든 툴입니다. 사용 방법은 상당히 간단합니다. crossdev -t sparc 명령을 실행하면 스파크 아키텍처를 대상으로 하는 크로스 툴체인을 만듭니다. 여기에 binutils, gcc, glibc, linux-headers가 들어갑니다.

보조 머신에 적당한 크로스 툴체인을 이머지해야합니다. 도움이 필요하면 crossdev --help를 실행하십시오.

크로스 툴체인을 최상의 상태로 만들려면 도우미 머신에 빌드할 정확한 버전의 크로스 개발 꾸러미를 만들 스크립트를 마련했습니다(스크립트는 대상 머신에서 실행합니다).

코드 교차 개발도구를 세밀하게 조절하는 스크립트
#! /bin/bash
A="sys-devel/binutils" ; B=`equery l $A` ; BINUTILS_VER=`echo $B | cut -d- -f3-`
A=`/usr/bin/gcc-config -c` ; B=`echo $A | cut -d- -f5` ; GCC_VER=`equery l sys-devel/gcc | grep $B | cut -d- -f3-`
KERNEL_VER=`uname -r | sed s/-gentoo//`
A="sys-libs/glibc" ; B=`equery l $A` ; LIBC_VER=`echo $B | cut -d- -f3-`
echo "crossdev --b =$BINUTILS_VER --g =$GCC_VER --k =$KERNEL_VER --l =$LIBC_VER -t `uname -m`"

그 다음, 컴파일 과정에 관여하는 모든 머신에 distcc를 이머지해야 합니다. 이 과정에서는 머신이 이머지를 실행하게끔해서 크로스 컴파일러로 무장할 수 있도록 합니다. distcc 설정 및 사용법에 대해 더 많이 알아보고 싶다면 젠투 distcc 문서를 살펴보십시오.

참고
crossdev 현재 버전은 컴파일러 도구 안정 버전 설치 목적(예: crossdev -t i686-pc-linux-gnu --stable --ex-gcc --ex-gdb --portage --pretend)으로 -S (--stable) 플래그를 지니고 있습니다. 이 옵션이 없으면 crossdev는 최신 시험버전 컴파일러 도구 꾸러미를 설치합니다! 그렇지 않으면, 위 스크립트는 꾸러미 도구의 개별 버전 또는 헤더를 가림 해제하기 전까지 더 이상 필요하지 않습니다.

아키텍처별 참고

참고
컴파일 대상 머신의 /etc/make.conf에서 CHOST 값을 찾아 아키텍처 이름을 확인하십시오. crossdev -t 옵션에 아키텍처 이름을 붙이면 crossdev에선 아무 생각 없이 추측하여 /usr 에 있는 폴더 이름에 붙은 아키텍처 이름(예 /usr/i686-pc-linux-gnu/, /usr/i686-linux-gnu/, ...)을 사용하려 컴파일 도구를 설치합니다. 이 문제를 해결하려면 crossdev --clean에 붙여넣을 아키텍처/폴더 이름을 지정하여 설치 제거를 하고나 시스템에서 폴더를 직접 삭제하십시오.

인텔 x86 하위 아키텍처

x86에 대해 각기 다른 하위 아키텍처(예: i586, i686)간에 크로스 컴파일링을 수행한다면, CHOST로 바라는대로의 완전한 크로스 툴체인을 만들어야 합니다. 그렇지 않으면 컴파일이 실패합니다. 왜냐하면 실제로는 i586과 i686 두 아키텍처를 "x86"으로 간주함에도 불구하고 CHOST값은 다릅니다. 크로스 툴 체인을 빌드할때 염두에 두시기 바랍니다. 예를 들어 대상 머신이 i586이라면 i686 도우미 머신에 i586 크로스 툴체인을 설치해야 함을 의미합니다.

스파크

crossdev -t sparc를 실행하면 다음 오류중 하나로 실패합니다:

코드 crossdev -t sparc를 실행할 때 나타나는 오류
linker with -z relro support required
support for the tls_model attribute is required
this configuration requires -mlong-double-128 support

여기서 문제가 있다면 다음 명령을 대신 사용하십시오:

user $crossdev --lenv "CC=sparc-unknown-linux-gnu-gcc" -t sparc-unknown-linux-gnu

올바르게 크로스컴파일 하도록 distcc 설정

참고
The workaround as described in this section is not needed any more since distcc-3.2, as the functionality for replacing the calls to the compiler with the full compiler name has since then been implemented in distcc itself.

기본 distcc 설정에는, 크로스 컴파일이 제대로 동작하지 "않습니다".이 문제는 완전한 컴파일러 이름(예:sparc-unknown-linux-gnu-gcc) 대신에 gcc를 호출하기 때문입니다. 부분부분 쪼갠 컴파일 작업물을 distcc 도우미 머신으로 보내면 새로 만든 윤기가 좔좔 흐르는 크로스 컴파일러가 아닌 자체 컴파일러를 호출합니다.

다행스럽게도 다른 해결책이 있긴 합니다. emerge를 실행할 머신의 몇가지 심볼릭 링크와 래퍼 스크립트가 있습니다. 예로서 제가 가진 스팍 머신을 사용하도록 하겠습니다. sparc-unknown-linux-gnu를 아래서 보는 곳마다, (예를 들어 AMD64 머신에 대해 x86_64-pc-linux-gnu라고 하는 것처럼) 자체 CHOST 값을 넣으려 할 것입니다. distcc를 처음 emerge할 때, /usr/lib/distcc/bin 디렉터리는 다음과 같은 모습을 띱니다:

참고
다음 절차는 emerge를 실행하는 머신에서만 수행합니다. 다른 도우미 머신에서 아래 과정을 밟지 마십시오.
root #cd /usr/lib/distcc/bin
root #ls -l
total 0
lrwxrwxrwx  1 root root 15 Dec 23 20:13 c++ -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Dec 23 20:13 cc -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Dec 23 20:13 g++ -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Dec 23 20:13 gcc -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-c++ -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-g++ -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-gcc -> /usr/bin/distcc

여러분이 실행할 명령입니다:

root #rm c++ g++ gcc cc

다음 이 머신에 새 스크립트를 만들겠습니다. 여러분 취향에 맞는 편집기를 여시고 다음 텍스트를 만들 파일에 넣은 다음에 sparc-unknown-linux-gnu-wrapper라고 저장하십시오. 기억하셔야 할 것은 emerge를 실행할 머신의 CHOST가 값을 바꾸려는 CHOST(이 경우 sparc-unknown-linux-gnu)입니다.

코드 새 래퍼 스크립트
#!/bin/bash
exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-g${0:$[-2]} "$@"

다음 실행 스크립트를 만들고 적당한 심볼릭 링크를 만들도록 하겠습니다:

root #chmod a+x sparc-unknown-linux-gnu-wrapper
root #ln -s sparc-unknown-linux-gnu-wrapper cc
root #ln -s sparc-unknown-linux-gnu-wrapper gcc
root #ln -s sparc-unknown-linux-gnu-wrapper g++
root #ln -s sparc-unknown-linux-gnu-wrapper c++

끝났다면 /usr/lib/distcc/bin은 다음과 같은 모양새를 띱니다:

root #ls -l
total 4
lrwxrwxrwx  1 root root 25 Jan 18 14:20 c++ -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx  1 root root 25 Jan 18 14:20 cc -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx  1 root root 25 Jan 18 14:20 g++ -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx  1 root root 25 Jan 18 14:20 gcc -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx  1 root root 15 Nov 21 10:42 sparc-unknown-linux-gnu-c++ -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Nov 21 10:42 sparc-unknown-linux-gnu-g++ -> /usr/bin/distcc
lrwxrwxrwx  1 root root 15 Jul 27 10:52 sparc-unknown-linux-gnu-gcc -> /usr/bin/distcc
-rwxr-xr-x  1 root root 70 Jan 18 14:20 sparc-unknown-linux-gnu-wrapper
참고
With new distcc versions, the following steps are unnecessary—you can emerge distcc on the client with the crossdev USE flag set instead to achieve the same result.

다음 심볼릭 링크를 중복적용할 distcc 꾸러미를 업그레이드 하고 나서도 래퍼를 계속 존재하게 내버려 둘 지 확인하려 할 것입니다. 다음처럼 /etc/portage/bashrc 파일을 편집하면 원하는대로 할 수 있습니다:

파일 /etc/portage/bashrc
case ${CATEGORY}/${PN} in
'"`UNIQ--pre-00000009-QINU`"'
			if [ "${EBUILD_PHASE}" == "postinst" ]; then
				/usr/local/sbin/distcc-fix &
			fi
		;;
esac

이 파일을 만드십시오:

파일 /usr/local/sbin/distcc-fix
#!/bin/bash	                
 
sleep 20
# change TUPLE to match your machine
TUPLE="sparc-unknown-linux-gnu"
cd /usr/lib/distcc/bin
rm cc c++ gcc g++ ${TUPLE}-wrapper
echo '#!/bin/bash' > ${TUPLE}-wrapper
echo "exec ${TUPLE}-g\${0:\$[-2]}" "\"\$@\"" >> ${TUPLE}-wrapper
chmod 755 ${TUPLE}-wrapper
ln -s ${TUPLE}-wrapper cc
ln -s ${TUPLE}-wrapper c++
ln -s ${TUPLE}-wrapper gcc
ln -s ${TUPLE}-wrapper g++

If you ARE using clang:

파일 /usr/local/sbin/distcc-fix
#!/bin/bash	                
#clang aware, now your >chromium-65 ebuilds will use distcc just like before ;) 
sleep 20
# We extract $TUPLE from make.conf to avoid editing the script for each architecture.
TUPLE=$(portageq envvar CHOST)
GCC_VER=$(gcc-config -c|cut -d "-" -f5)
CLANG_VER=$(clang --version|grep version|cut -d " " -f3|cut -d'.' -f1,2)
cd /usr/lib/distcc/bin
rm cc c++ gcc g++ gcc-${GCC_VER} g++-${GCC_VER} clang clang++ clang-${CLANG_VER} clang++-${CLANG_VER} ${TUPLE}-wrapper ${TUPLE}-clang-wrapper 
echo '#!/bin/bash' > ${TUPLE}-wrapper
echo "exec ${TUPLE}-g\${0:\$[-2]}" "\"\$@\"" >> ${TUPLE}-wrapper
echo '#!/bin/bash' > ${TUPLE}-clang-wrapper
echo "exec ${TUPLE}-\$(basename \${0}) \"\$@\"" >> ${TUPLE}-clang-wrapper
chmod 755 ${TUPLE}-wrapper
chmod 755 ${TUPLE}-clang-wrapper
ln -s ${TUPLE}-wrapper cc
ln -s ${TUPLE}-wrapper c++
ln -s ${TUPLE}-wrapper gcc
ln -s ${TUPLE}-wrapper g++
ln -s ${TUPLE}-wrapper gcc-${GCC_VER}
ln -s ${TUPLE}-wrapper g++-${GCC_VER}
ln -s ${TUPLE}-clang-wrapper clang
ln -s ${TUPLE}-clang-wrapper clang++
ln -s ${TUPLE}-clang-wrapper clang-${CLANG_VER}
ln -s ${TUPLE}-clang-wrapper clang++-${CLANG_VER}

적당한 퍼미션을 부여하십시오:

root #chmod 755 /usr/local/sbin/distcc-fix

축하합니다. 이제 (원하는 대로) 동작하도록 cross-distcc를 설정했습니다.

동작 원리

distcc를 호출하면, 어떤 머신(예:i686-pc-linux-gnu-gcc, sparc-unknown-linux-gnu-g++, 등)이 보조 머신을 호출했는지 찾고, distcc가 보조 머신에 컴파일 일감을 던지면, 호출한 이름에 따라 전달합니다. 다른 보조 머신의 distcc 데몬은 같은 이름의 바이너리를 찾습니다. gcc만을 찾는다면, 보조 머신의 자체 컴파일러 같은 gcc를 그냥 찾습니다. emerge를 실행하는 머신과 아키텍처가 다르다면 컴파일러 전체 이름을 보냈을 경우에 (예: sparc-unknown-linux-gnu-gcc) 혼동하지 않습니다.

문제 해결

이 부분은 크로스 컴파일 작업 수행시 distcc를 사용하면서 부딪힐 수 있는 일반적인 많은 문제를 다룹니다.

Remote host distccd COMPILE ERRORS

원격 호스트의 /var/log/distccd.log 파일에서 COMPILE ERRORS 메시지를 받았다면, 올바른 아키텍처 이름(crossdev -t $TARGET)을 지정하는 방법을 언급한 참고를 살펴보세요.

다른 해결책이 있다면 crossdev --clean 옵션으로 crossdev 컴파일 도구를 설치 제거하고 다시 설치하거나, /usr/$TARGET가 없는지 확인하고 크로스 컴파일러를 완전히 다시 설치하는 방법입니다.

원격 호스트의 /usr/$TARGET/etc/portage/make.conf 파일을 편집하여 CFLAGS 변수의 내용이 컴파일을 수행하는 모든 컴퓨터 또는 호스트와 유사한지 확인하는 방법이 현명할 수 있습니다.

Failed to exec $TARGET-uknown-linux-gnu-gcc: 그런 파일이나 디렉터리가 없습니다

래퍼 스크립트는 올바른 권한을 부여함에도 실행에 실패할 수 있습니다:

코드 Error message from wrapper
distcc[6195] (dcc_execvp) ERROR: failed to exec i686-unknown-linux-gnu-gcc: No such file or directory

이 문제를 해결하려면 래퍼 스크립트 이름이 완전한 대상 아키텍처의 이름인지 확인하십시오:

user $ls -alh /usr/lib/distcc/bin/c++
/usr/lib/distcc/bin/c++ ->./i686-pc-linux-gnu-wrapper

See also

  • Crossdev — a set of bash scripts that utilize emerge to provide a system integrated cross-compilation capability.

This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Andrew Gaffney, Joshua Saddler
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.