Вводная
Для одного из проектов потребовалось заняться доработками оригинального кода Android для создания прошивки под специфичную железку. Версия для сборки была выбрана уже относительно старая AOSP 4.0.4, но на ней базируется стабильная ветка кода от производителя железки, поэтому условие необходимое. Кроме разработки под Android я занимаюсь разработкой iOS приложений, соответственно работаю под Mac OS X и использую Xcode как одну из сред для разработки.
Основной проблемой в моем случае явилось то, что старые версии AOSP ни кем не отслеживаются и новые правки в сборочную систему не вносятся. Поэтому если сборка master’а особой сложности не представляет, то сборка предыдущих версий Android под более свежие версии MacOS требует исправления ряда проблем.
В моем случае рабочее окружение выглядит так:
- AOSP 4.0.4 r1.1 (а так же 4.0.3 и 4.1.1)
- Mac OS X 10.7.5
- Xcode 4.6.3 и command line tools
- GNU Make 3.81
Все основные моменты и сложности сборки AOSP хорошо описаны в официальной документации. Там же указано что для сборки ветки 4.0.x необходимы MacOS 10.5 или 10.6 и рекомендован Xcode 3.14, а в разделе «Known issues» указано что ветка 4.0.x не совместима с MacOS 10.7.
MacOS и Xcode я использую для разработки и откатываться на предыдущие версии крайне не хотелось. К тому же был чисто спортивный интерес разобраться со сборкой без какого-то кардинального изменения окружения.
Решение
Непосредственно все первоначальные шаги для сборки описаны в документации и были выполнены в соответствии с ней: создан case-sensitive disk image, установлены необходимые утилиты, скачан код Android. Далее была запущена сборка с профилем full-eng.
Ниже я привожу тексты ошибок из консоли и методы исправления. В зависимости от версии AOSP и вашего окружения они могут проявляться все или частично. Большинство решений можно найти в интернете, я привожу лишь краткое описание необходимых действий. Кроме AOSP 4.0.4 также были проверены версии 4.0.3 и 4.1.1. Чем новее версия, тем меньше встречалось ошибок, но первые 2 имели место везде.
Запуск сборки для решения проблем с компилятором осуществляется командой приведенной ниже. Здесь важная часть CC=«gcc» CXX=«g++», остальными могут быть стандартные параметры в любом порядке и сочетании.
make CC="gcc" CXX="g++" -j4
По ходу сборки, не считая описанного в документации, возникали следующие проблемы:
Ошибка 1
external/webkit/Source/WebCore/xml/XPathParser.cpp: In member function 'WebCore::XPath::Expression* WebCore::XPath::Parser::parseStatement(const WTF::String&, WTF::PassRefPtr<WebCore::XPathNSResolver>, WebCore::ExceptionCode&)':
external/webkit/Source/WebCore/xml/XPathParser.cpp:480:39: error: too many arguments to function 'int WebCore::XPath::xpathyyparse()'
out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/XPathGrammar.hpp:106:5: note: declared here
make: *** [out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/xml/XPathParser.o] Error 1
Исправление
Применить патч https://bugs.webkit.org/show_bug.cgi?id=92264. Патч ложится с небольшой ошибкой, из-за расхождения контекста, нужно посмотреть rej и удалить пару старых строк, которые не смог убрат патч. Применять патч в директории external/webkit/.
Важно
Во время линковки, на финальной стадии сборки, могут появиться ошибки типа:
prebuilt/darwin-x86/toolchain/arm-linux-androideabi-4.4.x/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/libwebcore.a(CSSParser.o): in function WebCore::CSSParser::parseMediaQuery(WebCore::MediaList*, WTF::String const&):external/webkit/Source/WebCore/css/CSSParser.cpp:621: error: undefined reference to 'cssyyparse(WebCore::CSSParser*)'
В зависимости от того добавляли ли вы изменения в CSSParser. Здесь проявляется некая мистика линковщика (для 4.1.1 версии со сборкой с этими исправлениями таких проблем нет). Для устранения проблемы нужно в CSSParser внести какие-нибудь изменения (считываемые компилятором, т.е. не комментарии). Я менял определение этой функции с cssyyparse(void*) на cssyyparse(WebCore::CSSParser*) или наоборот. Далее запустить пересборку — все пройдет гладко с этого места.
Ошибка 2
host SharedLib: libSR_Recognizer (out/host/darwin-x86/obj/lib/libSR_Recognizer.dylib)
Undefined symbols for architecture i386:
"_canPushAudioIntoRecognizer", referenced from:
_SR_RecognizerAdvanceImpl in RecognizerImpl.o
_detectBeginningOfSpeech in RecognizerImpl.o
...
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
make: *** [out/host/darwin-x86/obj/lib/libSR_Recognizer.dylib] Error 1
Исправление
Перенести определение в файл external/srec/portable/include/PortExport.h из ветки master в нашу.
#if defined(__APPLE_CC__)
#if __APPLE_CC__ >= 5621
#undef PINLINE
#define PINLINE
#endif
#endif
Ошибка 3
host Executable: triangleCM (out/host/darwin-x86/obj/EXECUTABLES/
triangleCM_intermediates/triangleCM)
Undefined symbols:
"__dyld_func_lookup", referenced from:
_promoteLocalToGlobal in libSDL.a(SDL_dlcompat.o)
_dlcompat_init_func in libSDL.a(SDL_dlcompat.o)
...
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [out/host/darwin-x86/obj/EXECUTABLES/
triangleCM_intermediates/triangleCM] Error 1
Исправление
Добавить библиотеку LOCAL_SDL_LDLIBS += /usr/lib/dylib1.o в /development/tools/emulator/opengl/tests/translator_tests/ для GLES_V2/Android.mk и GLES_CM/Android.mk.
Ошибка 4
Разное определение функции strnlen в системе и в локальных файлах. К сожалению для этой ошибки лог не записал, но суть будет понятна при упоминании функции strnlen.
Исправление
Добавить условие для функции strnlen в external/elfutils/config-compat-darwin.h:
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
static inline size_t strnlen (const char *__string, size_t __maxlen)
#endif
Ошибка 5
Выбор версии SDK по версии Mac OS для сборки эмулятора. Аналогично предыдущей ошибке без лога, но упоминание эмулятора qemu в логе укажет сюда.
Исправление
Заменить условие для версии Mac OS external/qemu/Makefile.android:
- ifeq ($(filter 10.5 10.5.%,$(DARWIN_VERSION)),)
+ ifneq ($(filter 10.6 10.6.%,$(DARWIN_VERSION)),)
И добавить подключение библиотек для MacOS:
ifeq ($(HOST_OS),darwin)
QEMU_SYSTEM_LDLIBS += -Wl,-framework,Cocoa,-framework,QTKit,-framework,CoreVideo
+ ifneq ($(filter 10.7 10.7.%,$(DARWIN_VERSION)),)
+ # Lion/XCode4 needs to be explicitly told the dynamic library
+ # lookup symbols in the precompiled libSDL are resolved at
+ # runtime
+ QEMU_SYSTEM_LDLIBS += -undefined dynamic_lookup
+ endif
endif
Ошибка 6
Если у вас операционная система стоит на диске с case-sensitive file system, то может проявиться такая ошибка:
external/qemu/android/camera/camera-capture-mac.m:24:24: error: QTKit/QTkit.h: No such file or directory
Исправление
Суть проблемы проста — опечатка в имени .h файла, вместо большой K напечатна маленькая k. Обычно не проявляется, т.к. MacOS установлена на диске с case-insensitive file system. Исправляет просто заменой на в коде на верное имя файла QTKit.h.
Вывод
Основным выводом можно сделать то, что все-таки собирать Android лучше на Linux системах, либо в виртуальной машине, если вам позволяют мощности. MacOS является в данном случае только лишь альтернативой и, как пишут сами разработчики, при обновлениях сборочной системы не проверяются все версии ОС, а зачастую у них даже нет такой возможности.
Автор: comhot