您的当前位置:首页正文

把ndk作为独立编译器

2024-11-28 来源:个人技术集锦
USING THE ANDROID TOOLCHAIN AS A STANDALONE COMPILER
使用 Android 工具链作为一个独立编译器
======================================================

WARNING WARNING WARNING WARNING WARNING WARNING WARNINGWARNING
WARNING WARNING WARNING WARNING WARNING WARNING WARNINGWARNING

SUPPORT FOR THIS FEATURE IS STILL IN BETA
AND ONLY APPLIES TO arm-linux-androideabi-4.4.3
支持这个功能仍旧在 beta 版且仅适用于 arm-linux-androideabi-4.4.3

IF YOU ENCOUNTER A PROBLEM WITH THE METHODS DESCRIBEDHERE,<wbr></wbr>
PLEASE CONTACT THE SUPPORT FORUM ATandroid-ndk@googlegroups.com
如果你在这里遇到一个用此方法描述的问题,请在支持论坛联系

WARNING WARNING WARNING WARNING WARNING WARNING WARNINGWARNING
WARNING WARNING WARNING WARNING WARNING WARNING WARNINGWARNING

It is now possible to use thetoolchain<wbr></wbr>
provided with the Android NDK as a standalonecompiler.<wbr></wbr>
使用 Android NDK 提供的工具链作为一个独立编译器现在是可能的。

This can be useful if you already have your own buildsystem,<wbr></wbr>
and only need to ability to invoke the cross-compiler to addsupport to Android for it.
如果你早已有你自己的生成系统的话,这可是有用的,
并且仅需要调用交叉编译器的能力来为它添加对 Android 的支持。
注:比如你有自己搭建的其它平台系统交叉编译环境的话。

A typical use case if invoking the 'configure' script of anopen-source library<wbr></wbr>
that expects a cross-compiler in the CC environmentvariable.
一个典型用例,假如调用一个开源库的 configure 脚本,要求一个交叉编译器在 CC 环境变量里。

This document explains how to do that:
本文档说明如何去做:

1/ Selecting your sysroot:
<wbr><wbr>选择你的 sysroot :</wbr></wbr>
--------------------------
注:我们可以在调用 gcc 时,给予 --sysroot=新路径,
  如此 gcc 就会改以 新路径 为参考目录,去搜寻所需的子例程和库等。
  ld 必需要在 configure 时,给予 --sysroot=新目录,
  新目录可以是任意目录,可以不是实际安装位置,主要目的是让 ld 启用 --sysroot 功能。

The first thing you need to know is which Android native APIlevel you want to target.
首先你需要知道你想要挑出哪个 Android 本地 API 级别 。

Each one of them provides a different variousAPIs,<wbr></wbr>
which are documented underdoc/STABLE-APIS.html,<wbr></wbr>
and correspond to the sub-directories of $NDK/platforms.
它们的每一个提供一个不同的多方面的 API ,是记录于 doc/STABLE-APIS.html 中,
并且对应于 $NDK/platforms 的子目录。

This allows you to define the path to your'sysroot',<wbr></wbr>
a GCC term for a directory containing the system headers andlibraries of your target.
这允许你来定义你的 sysroot 目录,一个 GCC 项包含你目标系统头文件和库的一个目录。

Usually, this will be something like:
通常,这将是有点像:

<wbr><wbr>SYSROOT=$NDK/platforms/android-&lt;level&gt;/arch-&lt;arch&gt;/</wbr></wbr>

Where <level> is the API levelnumber,<wbr></wbr>
and <arch> is the architecture("arm" being currently supported).<wbr></wbr>
<level> 是 API级别号,<arch> 是体系结构 (arm 是当前支持的)。

For example, if you're targetting Android 2.1 (a.k.a. Froyo),you would use:
例如,如果你是把 Android 2.1 作为目标(又叫做:Froyo),你将使用:

<wbr><wbr>SYSROOT=$NDK/platforms/android-8/arch-arm</wbr></wbr>


2/ Invoking the compiler (the hard way):
<wbr><wbr>调用编译器(难做的方式):</wbr></wbr>
----------------------------------------

Invoke the compiler using the --sysroot option to indicatewhere the system
files for the platform you're targetting are located. Forexample, do:
调用编译器使用 --sysroot 选项来指出你作为目标平台的系统文件位置。例如,给予:

<wbr><wbr> exportCC="$NDK/toolchains/&lt;name&gt;/prebuilt/&lt;system&gt;/bin/&lt;prefix&gt;gcc--sysroot=$SYSROOT"</wbr></wbr>
<wbr><wbr> $CC -o foo.o -cfoo.c</wbr></wbr>

Where <name> is the toolchain'sname, <system> is the host tag foryour system,
and <prefix> is atoolchain-specific prefix.<wbr></wbr>
<name> <wbr>工具链的名字<wbr></wbr></wbr>
<system> 你系统的主机标签
<prefix> 工具链特定的前缀

For example, if you are on Linux using the NDK r5 toolchain,you would use:
例如,假设你是在 Linux 上使用 NDK r5 工具链,你将使用:

<wbr><wbr> exportCC="$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc--sysroot=$SYSROOT"</wbr></wbr>

As you can see, this is rather verbose, but it works!
正如你所见,这是相当冗长,但它工作!

3/ Invoking the compiler (the easy way):
<wbr><wbr>调用编译器(容易的方式)</wbr></wbr>
----------------------------------------

The NDK allows you to create a "customized" toolchaininstallation to make life easier.<wbr></wbr>
NDK 允许你创建一个 定制的 工具链设置使生活更轻松。

For example, consider the following command:
例如,考虑如下命令:

<wbr>$NDK/build/tools/make-standalone-toolchain.sh --platform=android-5--install-dir=/tmp/my-android-toolchain</wbr>

This will create a directory named /tmp/my-android-toolchaincontaining a
copy of the android-5/arch-arm sysroot, and of the toolchainbinaries.
这将创建一个名为 /tmp/my-android-toolchain 的目录,
包含一个 android-5/arch-arm sysroot 和工具链二进制文件的拷贝。

You can later use it directly with something like:
你可以之后直接使用它,有点像这样:

<wbr><wbr>exportPATH=/tmp/my-android-toolchain/bin:$PATH</wbr></wbr>
<wbr><wbr>exportCC=arm-linux-androideabi-gcc</wbr></wbr>

Note that without the --install-diroption,<wbr></wbr>
make-standalone-toolchain.sh will create a/tmp/ndk/<toolchain-name>.tar.bz2 intarball.<wbr></wbr>
注意不用 --install-dir 选项,make-standalone-toolchain.sh 将用 tarball创建一个/tmp/ndk/<toolchain-name>.tar.bz2。

This allows you to archive and redistribute the binarieseasily.
这允许你容易地压缩和重新发行二进制文件。

Use --help for more options and details.
使用 --help 得到更多选项和细节。

IMPORTANT:<wbr></wbr>
重点:

The toolchain binaries do not depend or contain host-specificpaths,
in other words, they can be installed in anylocation,<wbr></wbr>
or even moved if you need to.
工具链二进制文件不依赖或包含宿主专一性的路径,
换句话说,它们可以安装在任意位置,或甚至移到你需要的地方。

NOTE:<wbr></wbr>
提示:

You can still use the --sysroot option with the newtoolchain,<wbr></wbr>
but it is now simply optional!
你可以依旧使用 --sysroot 选项用以新工具链,但是它现在只不过可选了!

4/ ABI Compatibility:
<wbr><wbr>ABI 兼容性:</wbr></wbr>
---------------------

The machine code generated by the toolchain should becompatible with
the official Android 'armeabi' ABI (seedocs/CPU-ARCH-ABIS.html) by default.
默认情况下,通过工具链产生的机器代码将兼容官方的 Android armeabiABI<wbr></wbr>
(参见 docs/CPU-ARCH-ABIS.html)。

It is recommended to use the -mthumb compiler flag to forcethe generation
of 16-bit Thumb-1 instructions (the default being 32-bit ARMones).
推荐使用 -mthumb 编译标志来强制 16位 Thumb-1 指令的产生 (默认是 32位 ARM)。

If you want to target the 'armeabi-v7a'ABI,<wbr></wbr>
you will need ensure that the following two flags are beingused:
如果你想要把 armeabi-v7a ABI 作为目标,你将需要确保如下两个标志是已使用:

<wbr> CFLAGS='-march=armv7-a-mfloat-abi=softfp'</wbr>

Note:<wbr></wbr>
提示:

The first flag enables Thumb-2instructions,<wbr></wbr>
and the second one enables H/W FPUinstructions<wbr></wbr>
while ensuring that floating-point parameters are passed incore registers,<wbr></wbr>
which is critical for ABIcompatibility.<wbr></wbr>
第一个标志启用 Thumb-2 指令,且第二个标志启用硬件浮点单元指令,
在确保浮点参数用内核寄存器传递时 ABI 兼容性是关键的。

Do *not* use these flags separately!
不要分开使用这些标志!

If you want to use NEON instructions, you will need one morecompiler flag:
如果你想要使用 NEON 指令,你将需要一个编译器标志:

<wbr> CFLAGS='-march=armv7-a -mfloat-abi=softfp-mfpu=neon'</wbr>

Note that this forces the use of VFPv3-D32, as per the ARMspecification.
注意这个标志强制 VFPv3-D32 的使用,依据 ARM 规范。

Also, is *required* to use the following linker flags thatroutes around
a CPU bug in some Cortex-A8 implementations:
同样,需要使用如下链接器标志在某些 Cortex-A8 实现中绕过一个 CPU 问题:

<wbr> LDFLAGS='-Wl,--fix-cortex-a8'</wbr>

If none of the above makes sense toyou,<wbr></wbr>
it's probably better not to use the standalonetoolchain,<wbr></wbr>
and stick to the NDK build systeminstead,<wbr></wbr>
which will handle all the details for you.
如果上述的对你毫无感觉,或许最好不使用独立工具链,固守 NDK 生成系统,它将为你处理全部细节。

5/ Warnings and Limitations:
<wbr><wbr>警告和限制:</wbr></wbr>
--------------------------

5.1/ Windows support:
<wbr><wbr><wbr>Windows 支持:</wbr></wbr></wbr>
- - - - - - - - - - -

The Windows binaries do *not* depend onCygwin.<wbr></wbr>
Windows 二进制文件不依赖 Cygwin 。

The good news is that they are thusfaster,<wbr></wbr>
the bad news is that they do not understand the Cygwin
path specification like /cygdrive/c/foo/bar (instead ofC:/foo/bar).
好消息是它们因此更快,坏消息是它们不能理解 Cygwin 路径规范,
像 /cygdrive/c/foo/bar (代替 C:/foo/bar)。

The NDK build system ensures that all paths passed to thecompiler from Cygwin
are automatically translated,<wbr></wbr>
and deals with other horrors for you.<wbr></wbr>
NDK 生成系统确保全部路径从 Cygwin 传递到编译器是自动地翻译了,并且为你处理其它令人讨厌的事。

If you have a custom build system,<wbr></wbr>
you may need to deal with the problem yourself.
如果你有一个自定义生成系统,你可能需要自己去处理问题。

NOTE:<wbr></wbr>
注意:

There is no plan to support Cygwin / MSys at themoment,<wbr></wbr>
but contributions are welcome.<wbr></wbr>
目前没有计划去支持 Cygwin 或 MSys ,但是欢迎贡献。

Contact the android-ndk forum for details.
联系 android-ndk 论坛了解细节。

5.2/ wchar_t support:
<wbr><wbr><wbr>wchar_t 支持:</wbr></wbr></wbr>
- - - - - - - - - - -

As documented,<wbr></wbr>
the Android platform did not really support wchar_t untilAndroid 2.3.<wbr></wbr>
正如记载的,Android 平台不真正地支持 wchar_t 直到 Android 2.3 。

What this means in practical terms is that:
在实际中这意味着:

<wbr> - If your target platform is android-9 orhigher,<wbr></wbr></wbr>
<wbr><wbr> the size of wchar_t is 4bytes,<wbr></wbr></wbr></wbr>
<wbr><wbr> and most wide-charfunctions are available in the C library</wbr></wbr>
<wbr><wbr> (with the exception ofmulti-byte encoding/decoding functions and wsprintf/wsscanf).</wbr></wbr>
<wbr><wbr> 如果你的目标平台是 android-9或更高的话,wchar_t 是 4 字节大小,</wbr></wbr>
<wbr><wbr> 那么在 C库中有大部分的宽字符函数是可用的。</wbr></wbr>

<wbr> - If you target any prior APIlevel,<wbr></wbr></wbr>
<wbr><wbr> the size of wchar_t willbe 1 byte and none of the wide-char functions will workanyway.</wbr></wbr>
<wbr><wbr> 如果你把任何之前 API级别作为目标的话,wchar_t 的大小将是 1 字节,</wbr></wbr>
<wbr><wbr>那么不论以何种方式没有宽字符函数将工作。</wbr></wbr>

We recommend any developer to get rid of any dependencies onthe wchar_t type
and switch to better representations.<wbr></wbr>
我们推荐任何的开发者从任何的 wchar_t 类型依赖中摆脱,然后转变为更好的表示。

The support provided in Android is only there to help youmigrate existing code.
Android 提供的支持是仅在这里帮助你迁移现存代码。

5.3/ Exceptions, RTTI and STL:
<wbr><wbr><wbr>例外,运行时信息和 STL :</wbr></wbr></wbr>
- - - - - - - - - - - - - - -

The toolchain binaries *do* support C++ exceptions and RTTI bydefault.
在默认情况下工具链二进制文件支持 C++ 例外和运行时信息。

They are enabled by default,<wbr></wbr>
so use -fno-exceptions and -fno-rtti if you want to disablethem<wbr></wbr>
when building sources with them (e.g. to generate smallermachine code).
它们默认是启用的,所以如果你想要禁用它们在生成源文件时使用 -fno-exceptions 和 -fno-rtti。
(例如:产生更小机器代码)

NOTE:<wbr></wbr>
注意:

You will need to explicitely link with libsupc++ if you usethese features.<wbr></wbr>
如果你使用这些功能的话,你将需要显示链接 libsupc++ 。

To do this, use -lsupc++ when linking binaries, as in:
要这样做,在链接二进制文件时使用 -lsupc++ ,如用:

<wbr><wbr>arm-linux-androideabi-g++ .... -lsupc++</wbr></wbr>

The toolchain also comes with a working GNU libstdc++implementation,<wbr></wbr>
which provides a working C++ Standard Template Libraryimplementation.<wbr></wbr>
工具链同样带来一个有效的 GNU libstdc++ 实现,提供有效的 C++ 标准模板库实现。

You will need to explicitely link against -lstdc++ to useit.
你将需要显示链接 -lstdc++ 来使用它。

Proper toolchain configuration to avoid these explicit linkflags is planned for the future.
对于将来严格意义上的工具链配置避免这些显示链接标志是有计划的。

显示全文