Как я Android под Mac OS X собирал

в 11:41, , рубрики: android, linux, mac os x, xcode, Разработка под android, метки: , , ,

Одной из задач компании, в которой я работаю, является разработка своей модификации Android, с очень сильным перепиливанием кода ОС. Собственно, этой задачей я и занимаюсь. Так сложилось, что все (ну или почти все) сотрудники работают на маках. Я первое время сидел на Linux, писал себе код, компилял-собирал, и т.д. В принципе, ничего сложного в сборке Андроида из исходников нет — настроить среду, выкачать 14 гигов исходников, поставить собираться и 6 часов заниматься своими делами. Но пару недель назад я пересел на MacBook, и тут-то и началось веселье.

Казалось бы, тоже все не так трудно и не сильно отличается от сборки под Линуксом. Однако, давайте пройдемся по шагам с самого начала:
1. Ставим MacPorts. Для меня, как для линуксоида и в прошлом юникс-админа этот шаг все равно был бы обязательным.
2. Ставим нужный софт:

$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg

Кроме того, ставим XCode с сайта Apple.
3. Теперь первое отличие от линукса. По умолчанию в маке используется case-insensitive ФС. Как сказано на сайте source.android.com, исходный код Android содержит файлы, имена которых отличаются только регистром, поэтому нам надо создать case-sensitive ФС, в которой будут лежать исходники. Ну ок, создаем:

$ hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg

Можно также создать функцию для монтирования образа и поместить ее в .bash_profile:

function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }

4. Ну и теперь стандартные шаги для скачивания кода:

$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo
$ sudo mv repo /usr/bin/repo
$ sudo chmod a+x /usr/bin/repo
$ cd /Volumes/android/
$ repo init -u https://android.googlesource.com/platform/manifest -b ics
$ repo sync

Ждем, пока все скачается. Конфигурируем:

$ source build/envsetup.sh
$ lunch

Запускаем сборку (в 4 потока):

$ make -j4 bacon

Уходим куда-нибудь часов этак на шесть.
Приходим, что мы хотим увидеть:

Package complete: /Volumes/android/out/target/product/crespo/update-cm-9.0.0-RC0-crespo-UNOFFICIAL-signed.zip

Что мы видим на самом деле:

CHK     include/linux/version.h
make[1]: `include/asm-arm/mach-types.h' is up to date.
 CHK     include/linux/utsrelease.h
 CALL    scripts/checksyscalls.sh
sed: 4: "/^#define/ { s/[^_]*__ ...": bad flag in substitute command: '}'
 HOSTCC  scripts/mod/mk_elfconfig
scripts/mod/mk_elfconfig.c:4:17: error: elf.h: No such file or directory
scripts/mod/mk_elfconfig.c: In function ‘main’:
scripts/mod/mk_elfconfig.c:9: error: ‘EI_NIDENT’ undeclared (first use
in this function)
scripts/mod/mk_elfconfig.c:9: error: (Each undeclared identifier is
reported only once
scripts/mod/mk_elfconfig.c:9: error: for each function it appears in.)
scripts/mod/mk_elfconfig.c:19: error: ‘ELFMAG’ undeclared (first use
in this function)
scripts/mod/mk_elfconfig.c:19: error: ‘SELFMAG’ undeclared (first use
in this function)
scripts/mod/mk_elfconfig.c:23: error: ‘EI_CLASS’ undeclared (first use
in this function)
scripts/mod/mk_elfconfig.c:24: error: ‘ELFCLASS32’ undeclared (first
use in this function)
scripts/mod/mk_elfconfig.c:27: error: ‘ELFCLASS64’ undeclared (first
use in this function)
scripts/mod/mk_elfconfig.c:33: error: ‘EI_DATA’ undeclared (first use
in this function)
scripts/mod/mk_elfconfig.c:34: error: ‘ELFDATA2LSB’ undeclared (first
use in this function)
scripts/mod/mk_elfconfig.c:37: error: ‘ELFDATA2MSB’ undeclared (first
use in this function)
scripts/mod/mk_elfconfig.c:9: warning: unused variable ‘ei’
make[2]: *** [scripts/mod/mk_elfconfig] Error 1
make[1]: *** [scripts/mod] Error 2
make: *** [scripts] Error 2

Немного погуглив, понимаем, что ошибка связана со сборкой ядра Linux под Mac OS X. Решение достаточно простое — нужно скачать Apple'овский elf.h и поместить его в /usr/include/.
Ок, сделали, поставили собираться дальше.
Приходим через пару часов. Что мы ожидаем увидеть, вы уже знаете. Авотфиг. Вот что мы видим:

host SharedLib: libSR_Recognizer (out/host/darwin-x86/obj/lib/libSR_Recognizer.dylib)
Undefined symbols for architecture i386:
  "_pushAudioIntoRecognizer", referenced from:
      _SR_RecognizerAdvanceImpl in RecognizerImpl.o
      _detectBeginningOfSpeech in RecognizerImpl.o
  "_generatePatternFromFrame", referenced from:
      _SR_RecognizerAdvanceImpl in RecognizerImpl.o
  "_canPushAudioIntoRecognizer", referenced from:
      _SR_RecognizerAdvanceImpl in RecognizerImpl.o
      _detectBeginningOfSpeech in RecognizerImpl.o
  "_generatePatternFromFrameEOI", referenced from:
      _SR_RecognizerAdvanceImpl in RecognizerImpl.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [out/host/darwin-x86/obj/lib/libSR_Recognizer.dylib] Error 1

Ладно, лезем опять в гугл. Находим один-единственный вопрос на stackoverflow, в котором автор топика сам же себе и отвечает. Впрочем, это решение помогло только автору топика, мы же получаем ту же самую ошибку.

Всю ночь гуглим, шаримся по гугл-группам и в итоге находим решение, до которого фиг-знаетт-как вообще додумался его автор. Оказывается, все было предельно просто — нужно было поставить старый XCode, если быть точнее — версии 3.2.4.

Ставим собираться, ложимся, наконец-то, поспать, просыпаемся, и — о чудо — видим:

Package complete: /Volumes/android/out/target/product/crespo/update-cm-9.0.0-RC0-crespo-UNOFFICIAL-signed.zip
MD5 (update-cm-9.0.0-RC0-crespo-UNOFFICIAL-signed.zip) = 88e04596ae327fe5cca9f72d0dd8ec2a

Вот такие вот дела. Очень надеюсь, что данным топиком сэкономлю кому-то пару бессонных ночей.

Автор: RankoR


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js