ndk-build는 의존성이 여러개인 외부 라이브러리를 손쉽게(?) 빌드하기 어렵다. 이 경우 ndk-build를 사용하는 대신에 AOSP를 소스 트리를 그대로 가져와서 arm_aosp-eng를 빌드한 후에 external/ 하위에 외부 라이브러리를 빌드하면 여러모로 편리하다. 또한 이렇게 하는 경우에 ndk-build와는 다르게 라이브러리 뿐만 아니라 apk 패키지도 같이 빌드할 수 있는 장점도 있다.

기존에는 AOSP 트리 대신에 CyanogenMod 킷캣 소스트리를 사용하고 있었는데 킷캣의 경우 arm64 및 x86_64를 지원하지 않아서 롤리팝 소스트리를 가져다가 빌드 환경을 재구성 하였다.

(AOSP 마쉬멜로우 트리의 경우 전체 빌드는 문제 없이 잘 되었으나, 이를 사용하려 하니 하위 호환성을 무시하고 과감하게 없애버린 몇몇 라이브러리 등등이 문제가 되어 롤리팝 소스트리를 선택하였다)

아무튼 이러한 이유로 AOSP 트리를 받아서 롤리팝을 다음과 같이 컴파일 하였다.

$ repo init -u https://android.googlesource.com/platform/manifest -b android-5.1.1_r38
$ repo sync
$ . build/envsetup.sh
$ lunch aosp_arm-eng
$ make -j4
...

보통은 이렇게 하면 아무런 문제 없이 전체 빌드가 되는데, 우분투 16.04 환경에서 빌드하다고 못보던 오류가 떴다.

해당 오류를 구글로 검색해보니 대략 다음과 같은 내용을 찾을 수 있었다.

http://stackoverflow.com/questions/36048358/building-android-from-sources-unsupported-reloc-43

https://android-review.googlesource.com/#/c/223100/

롤리팝부터는 clang을 host 바이너리 빌드하는 경우에 사용하게 되는데, 이 경우 clang은 자체적으로 내장된 as를 사용하는 대신에 별도의 gcc 툴체인의 as도 같이 사용하고 있다. 그런데 clang에 -B 옵션으로 툴체인의 경로를 지정하지 않는 경우, 툴체인의 as를 사용하는 대신에 host에 이미 설치된 as를 이용해 컴파일 된다. host의 as가 버전이 낮은 경우에는 별 문제가 되지 않는데 최신의 배포판을 사용하는 경우에는 host의 as 버전이 높고,  gcc 툴체인의 ld는 높은 버전으로 컴파일된 오브젝트의 relocation 타입을 인식하지 못하는 문제가 발생하는 것이다.

우분투 16.04를 사용하는 경우 host의 as 버전 (binutils 2.26.1)

$ as -v
GNU assembler version 2.26.1 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.26.1

툴체인의 as 버전 (gcc 4.6 + binutils 2.23.2)

$ prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/bin/x86_64-linux-as -v
GNU assembler version 2.23.2 (x86_64-linux) using BFD version (GNU Binutils) 2.23.2

위와 같이 툴체인의 as 버전이 host의 as 버전보다 낮다.

일단 위 링크에 써있듯이 -B 옵션을 build/core/clang/HOST_clang_common.mk에 추가하고 다시 컴파일 하였다. (stackoverflow 링크에 나와있듯이 롤리팝의 경우에는 다른 옵션을 건드리지 말고 패치를 수동으로 추가)

  -B$($(clang_2nd_arch_prefix)HOST_TOOLCHAIN_FOR_CLANG)/x86_64-linux/bin

주의해야 할 것은 이 경우 이미 컴파일 된 오브젝트 파일을 모두 지워줘야 한다는 점이다. 따라서 out/host/* 파일을 지워주고 make -j4 로 재빌드 한다.

by dumpcookie 2017. 2. 26. 21:25

PC를 한대 업그레이드 하고, 기존에 잘 쓰던 PC에 우분투 리눅스를 설치해서 개발용 빌드머신으로 활용하게 되었습니다. AOSP 마쉬멜로우를 테스트삼아 빌드하는데 시스템이 중간에 알 수 없는 이유로 죽는겁니다.

  1. 한참 컴파일 잘 하다가 시스템의 로드가 높아지면 갑자기 죽음.
  2. make -j2 등으로 시스템의 로드를 낮춰보면 시스템은 거의 죽지 않음.

지금은 문제 없이 잘 사용하고 있어서 위 두가지 항목으로 간단히 정리했지만, 당시에는 당황해서 상당한 삽질했던 것을 생각하면.... 아무튼 기억나는대로 다시 적어보면 다음과 같습니다.

  1. 메모리 문제는 아닌가? - 메모리 테스트 하고, 메모리를 하나씩 빼고 다시 컴파일을 해봄 - 여전히 시스템의 로드가 올라가면 죽음.
  2. 시스템 파워의 문제는 아닌가? - 시스템 파워를 좀 더 새것으로 잠시 교체해봄 - 여전히 죽음
  3. 커널이 맞지 않는가? - 커널을 좀 더 최신으로 바꿔봐도 시스템의 로드가 상당히 올라가면 여전히 죽음.

여기까지 테스트를 하니 벌써 반나절 이상을 소요... 일단 컴파일은 make -j2 등으로 로드를 낮춰서 컴파일을 하였고, 마지막으로 의심이 부분은 CPU 쿨링이었습니다. 쿨러는 사제 쿨러가 아닌 기본 쿨러를 쓰고 있었고, 먼지 청소를 하기 위해서 쿨러를 떼어내다가 서멀 구리스가 일부 제거되어 쿨러와 CPU의 밀착이 잘 되지 않고 있던 상태였던 것을 기억해 내었습니다. 메인보드가 구형이기는 하였지만 자동으로 오버클럭 기능을 제공하는 그러한 기종이었는데 펌웨어도 좀 더 안정성 있다고 써있는 최신으로 업그레이드 하고, 메인보드 모델명으로 검색을 해보니 바이오스에서 자동 오버클럭 기능(?)을 모두 꺼버리라는 내용이 보이더군요. 시스템의 로드가 올라가다가 죽는 현상과도 연관이 있는 것 같아서 이 기능을 끄고, 비교적 저렴한 서멀 구리스를 하나 구입하였습니다. 거의 하루를 이 삽질로 낭비...

몇일 뒤에도 시스템의 로드가 올라가면 여전히 죽는 현상이 있었으나, 배송되어 날아온 서멀구리스를 꼼꼼히 바르고 CPU 재 장착... make -j4 등등의 작업을 하니 그 뒤로는 시스템이 단 한번도 알 수 없는 이유로 죽지 않고 있습니다.

시스템이 알 수 없는 원인으로 죽거나 알 수 없는 오류가 자주 날 때에 살펴보아야 할 것을 나름 정리해보면

  1. 랜덤하게 시스템이 죽는 경우 - 경험상 거의 100% 메모리 문제. 메모리 문제의 경우에는 파일이 알 수 없는 원인으로 랜덤하게 망가지기도 한다.
  2. 랜덤하게 파일이 망가지는 경우 - 시스템이 죽지 않는 경우에도 컴파일 할 때마다 다른 곳에서 랜덤하게 컴파일이 멈추고 오류가 나는 현상도 보이며, 파일이 이상하게 깨지는 경우가 목격된다. - 이 경우도 메모리 문제일 확률이 높은데, 메모리 문제로 추측되면 memory 테스트를 해보라.
  3. 하드디스크가 이상이 있는 경우 - 컴파일시 이상한 지연 현상이 있으며 시스템이 이상하게 한참을 기다린다면 dmesg로 커널 로그를 살펴보자. I/O 오류가 간간히 보이고 하드디스크에서 이상한 끼릭끼릭 소리가 난다면 100% 하드디스크 교체 타이밍. 새 하드 디스크를 사서 신속하게 교체해야 하고, 데이터를 옮겨야 한다. 잘 하면 데이터를 그대로 살릴 수 있다.
  4. 컴퓨터가 어느날 갑자기 부팅이 안될 때 - 이 경우에는 여러가지 원인 일 수 있으나, 일단 HDD등의 기기는 무조건 분리하고 컴퓨터 청소등을 실시해보자. 파워에서 이상한 냄새가 난다거나 하면 파워의 문제일 수 있다. 메인보드의 콘덴서가 모두 정상적인지도 살펴보자. 콘덴서가 부풀어 오르거나 했을 경우는 메인보드 문제. (몇년간 잘 쓰던 컴퓨터가 갑자기 부팅이 안되어 컴퓨터 청소하고 재 연결하고 다시 켜는 과정에서 파워가 갑자기 번쩍 하면서..  메인보드가 타고, HDD도 칩이 타서 모두 날려버린 경험을 했던...ㅠ)


by dumpcookie 2017. 2. 25. 00:21
| 1 |