2012-06-11 4 views
2

набора инструментов у меня есть очень простой helloworld.cpp программуКомпиляция против стандартных библиотек C++ на андроид

#include <iostream> 
using namespace std; 
int main() 
{ 
    cout << "Hello World!"; 
    return 0; 
} 

И я пытаюсь скомпилировать для андроид x86 с кросс-компилятор с инструментарием,:

/Users/me/android-ndk-r8/toolchains/x86-4.4.3/prebuilt/darwin-x86/bin/i686-android-linux-g++ helloworld.cpp -L "/Users/me/android-ndk-r8/sources/cxx-stl/stlport/libs/x86/" -lstlport_static 

Однако я получаю ошибки:

helloworld.cpp:2:20: error: iostream: No such file or directory 

Любая идея, почему?

+0

Я редактировал свой вопрос, потому что это не связанная проблема. –

+1

Похоже, вам нужно также установить свой путь включения. Кроме того, предпочтительнее и лучше поддерживать другой способ построения проектов Android, 'ndk-build'. – jedwards

+0

Как установить путь включения? – MEURSAULT

ответ

6

Проверьте файл documentation.html, прилагаемый к NDK, в разделе «Отдельная инструментальная цепочка». В нем говорится, что если вы вызовете компилятор таким образом, вы не сможете «использовать любой C++ STL». Однако это возможно, так как документация объясняет, если вы сначала создать «настроенную» установку ToolChain, используя что-то вроде следующей команды:

$NDK/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=/tmp/my-android-toolchain --arch=x86 

где $ NDK это путь к каталогу NDK. Обратите внимание на -arch = x86, что означает, что toolchain подготовлен специально для x86 Android. Это подготавливает то, что вам нужно в одном каталоге, включая заголовки и папки STL. Затем вы должны быть в состоянии использовать -lstdC++ компоноваться с STL (статическая версия), то есть что-то вроде:

/tmp/my-android-toolchain/bin/i686-android-linux-g++ helloworld.cpp -lstdc++ 

Для более полного объяснения, обратитесь к документации NDK.

2

Документация NDK не совсем точная, по крайней мере, в настоящее время. Фактически, он указывает, что при использовании предварительно созданной инструментальной цепочки «Вы не сможете использовать с ним STL (STLport или GNU libstdC++)», но это устарело. Я создал небольшую программу приветствия, используя include с той же ошибкой. Это можно решить, не создавая свою собственную инструментальную цепочку, хотя это приятно, если вы не хотите добавлять еще один шаг к процессу настройки и всегда можете использовать последнюю платформу SDK, не создавая новую инструментальную цепочку каждый раз.

NDK поставляется с исходным кодом для нескольких версий стандартных библиотек C++: GAbi ++, STLport и GNU STL. Каждый вкус имеет готовые общие и статические библиотеки. В моем примере ниже будет использоваться stlport.

Чтобы использовать автономный набор инструментов на его месте установки, вы можете сделать что-то вроде этого: экспорт CXX = '$ NDK_ROOT/компилированные инструменты/рычажного линукс-androideabi-4,8/прекомпилированное/Darwin-x86_64/бен/рука -Linux-androideabi-g ++ --sysroot = "$ NDK_ROOT/platform/android-19/arch-arm" '

Это, например, позволит вашему компилятору CXX скомпилировать ARM в системе OS X с использованием платформы SDK уровень 19. Это вы, наверное, уже знали. Кроме того, вы хотите экспортировать свои CC, CPP, LD, AR и RANLIB, если вы его используете. Я также лично создаю envar для READELF.

Для добавления поддержки C++ LIBS, вы могли бы сделать что-то вроде следующим образом: $ CXX helloworld.cpp -I $ NDK_ROOT/источники/CXX-СТЛ/STLport/STLport -L $ NDK_ROOT/источники/CXX-СТЛ/STLport/libs/armeabi -lstlport_shared

Обратите внимание, что это свяжет libstlport_shared.so, который теперь потребуется во время выполнения, поэтому вам может понадобиться добавить относительный путь к указанной выше команде, чтобы поддержать это, в зависимости от вашей структуры APK.Если вы хотите просто проверить это простой случай, вы можете просто запустить это на эмуляторе следующим образом:

adb push a.out /data 
adb push $NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so /data 
adb shell 
# su 
# cd /data 
# chmod 777 a.out 
# ./a.out 

Чтобы избавиться от головной боли борьбы с общими путями библиотеки, вы можете статически связать библиотеку C++ в изменив «-lstlport_shared» на «-lstlport_static». Есть некоторые последствия для этого, как описано в NDK Dev Guide. Самая большая проблема связана с тем, что статическая библиотека связана в нескольких местах, в результате чего: - память, выделенная в одной библиотеке, и освобожденная в другой, приведет к утечке или даже повреждению кучи. - исключения, поднятые в libfoo.so, не могут быть пойманы в libbar.so (и могут просто сбой программы). - буферизация std :: cout не работает должным образом

Полезный инструмент также включен, чтобы узнать, какие зависимости у вашей программы есть, инструмент readelf.

Чтобы посмотреть, что другие общие библиотеки требует ваша программа, вы можете выполнить следующую команду: $ NDK_ROOT/компилированные инструменты/рычажного линукс-androideabi-4,8/прекомпилированное/Darwin-x86_64/бен/рычажного линукс-androideabi-readelf - a a.out | Grep ТРЕБУЕТСЯ

Другие холодные стандартные инструменты: addr2line - преобразования адреса трассировки стека в строке кода нм - Отображение таблицы символов objdump - информация отображается на объекте

Смежные вопросы