CrystaX NDK是Google's Android NDK的一个替代方案.
相比谷歌的NDK, CrystaX NDK在支持相同功能的同时, 提供了一些很棒的新功能和大量的缺陷修复和改进.
CrystaX NDK的主要目的是让Android开发者更高效地运用标准化代码进行native开发.
通过使用那些支持多平台 (IOS, OS X, Windows, Linux 等等) 的标准代码库,CrystaX NDK显著节省了开发时间,不需要再为Android平台做特殊修改(甚至于为Android特殊定制实现那些在其他平台早已实现的功能).
由于Android libc(Bionic)功能有限,版本之间还不尽相同,开发者需要做很多运行时版本检测和兼容性适配的额外工作.
CrystaX NDK提供的libcrystax屏蔽了Android版本兼容性差异,甚至重写了很多libc函数,使得应用程序在所有Android设备上表现一致.
CrystaX NDK的另一个目的是为Android Native开发提供一些很棒的新功能.例如: Objective-C和其他编程语言的支持.
这个项目最初是2009年Dmitry Moskalchuk的个人项目,只是为了添加一些Google Android NDK缺失的C++特性(exceptions,RTTI,C++标准库),后来越加越多, 不断优化,
CrystaX NDK逐步变成了Android native开发的最佳进化.很多开源和商业化项目使用CrystaX NDK进行Android开发和移植.
现在CrystaX NDK提供了大量新功能,使得Android native开发更容易,详见以下关键特性.
- 完整支持宽字符
宽字符是C和C++标准库的一部分,例如C标准库的wcsnlen, wcsncasecmp, wcsncmp
和其他,
C++标准库的wchar_t, std::base_string, std::basic_ostream,
std::basic_regex等等.Android libc (Bionic)对这些支持不足.
CrystaX NDK提供标准化的宽字符支持,包括multibyte-to-wide和反之亦然的转换.
你可以轻松移植已有代码, 或者撰写新代码, 尽情使用宽字符, 字符串, 流以及正则表达式, 不再受限于Android系统.
例子#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <locale.h>
void hello()
{
// C-style
printf("%ls", L"Hello, world!\n"); //=> Hello, world!
// C++-style
std::wcout << L"Hello, world!" << std::endl; //=> Hello, world!
}
void strconv()
{
setlocale(LC_CTYPE, "ru_RU.UTF-8");
std::string hello = "Здравствуй, мир!";
wchar_t buf[128];
mbstowcs(buf, hello.c_str(), hello.size());
std::wstring s(buf);
std::wcout << s << std::endl; //=> Здравствуй, мир!
}
int main()
{
hello();
strconv();
return 0;
}
- 完整支持C locales
Android libc (Bionic) 不支持locales, 所以在native代码中使用本地化输入输出的唯一方法是通过JNI调用Java本地化实现.
显然这种方法增加了显著的运行时开销, 但这是你使用谷歌Android NDK的唯一选择.
CrystaX NDK内置支持locales, 只需简单调用标准的setlocale,
所有后续C标准函数调用都使用设置的locale做输入输出.
CrystaX NDK还支持"locales扩展" (部分
IEEE Std 1003.1, 2013 Edition),
提供很多标准C接口的locale有效的函数,例如printf_l, strftime_l, strfmon_l等等.
例子#include <locale.h>
#include <stdio.h>
#include <time.h>
#include <monetary.h>
void printtime(const char *locale, time_t t)
{
char buf[256];
setlocale(LC_TIME, locale);
strftime(buf, sizeof(buf), "%c", localtime(&t));
printf("TIME (locale "%s"): %s\n", locale, buf);
}
void printmonetary(const char *locale, double v)
{
char buf[256];
setlocale(LC_MONETARY, locale);
strfmon(buf, sizeof(buf), "%.2n", v);
printf("MONETARY (locale "%s"): %s\n", locale, buf);
}
int main()
{
time_t t = (time_t)1411859044;
double v = 13653.6783;
printtime("C", t); /*=> Sun Sep 28 02:04:04 2014 */
printtime("en_US.UTF-8", t); /*=> Sun Sep 28 02:04:04 2014 */
printtime("fi_FI.UTF-8", t); /*=> Su 28 Syy 02:04:04 2014 */
printtime("sv_SE.UTF-8", t); /*=> Sön 28 Sep 02:04:04 2014 */
printtime("no_NO.UTF-8", t); /*=> søn 28 sep 02:04:04 2014 */
printtime("ru_RU.UTF-8", t); /*=> воскресенье, 28 сентября 2014 г. 02:04:04 */
printtime("tr_TR.ISO8859-9", t); /*=> Paz 28 Eyl 02:04:04 2014 */
printtime("zh_CN.UTF-8", t); /*=> 日 9/28 02:04:04 2014 */
printmonetary("C", v); /*=> 13653.68 */
printmonetary("en_US.UTF-8", v); /*=> $13,653.68 */
printmonetary("fi_FI.UTF-8", v); /*=> 13.653,68€ */
printmonetary("sv_SE.ISO8859-1", v); /*=> 13 653,68 kr */
printmonetary("no_NO.ISO8859-15", v); /*=> kr13.653,68 */
printmonetary("ru_RU.UTF-8", v); /*=> 13 653,68 руб. */
printmonetary("tr_TR.UTF-8", v); /*=> L 13.653,68 */
printmonetary("zh_CN.UTF-8", v); /*=> ¥13,653.68 */
return 0;
}
- 完整数学支持, 包括复数和泛型函数库
ISO C标准定义头文件<tgmath.h>和<complex.h>. 在Google's Android NDK中,
<complex.h>始于r10, 仅支持Android 5.0 (android-21), 同时泛型数学函数库完全没有实现.
而CrystaX NDK, 没什么好说的,都完整实现了. 尽情使用!
- 最新工具链
CrystaX NDK包含最新版GCC和Clang编译器. 允许开发人员使用最新语言特性, 例如C++11/C++14.
所有编译器都经过不同程度的优化, 可以针对目标硬件平台生成高效执行代码.
- C++11/C++14支持
- 完整的C++标准库
CrystaX NDK提供完整可用的C++11标准库, 包括std::thread 和 std::mutex,
std::chrono的类和方法, 以及方法std::stol, std::stoul etc.
这些在Google's Android NDK中都缺失.或者严格地说,存在但仅限于实验版的LLMV libc++实现.
CrystaX NDK完整支持C++标准库, 无论你使用GNU libstdc++或LLVM libc++.
另外, LLVM libc++ 在CrystaX NDK中也是第一优先级, 地位等同于GNU libstdc++, 所以你可以自由选择其中之一,默认使用GNU libstdc++.
例子#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <ctime>
long fibonacci(unsigned n)
{
if (n < 2) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
int main()
{
std::mutex outmtx;
auto f = [&](int n) {
std::chrono::time_point<std::chrono::system_clock> start, end;
start = std::chrono::system_clock::now();
long fib = fibonacci(42);
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
std::lock_guard<std::mutex> lock(outmtx);
std::cout << "THREAD #" << n << ": f(42) = " << fib << '\n';
std::cout << "THREAD #" << n << ": finished computation at " << std::ctime(&end_time)
<< "elapsed time: " << elapsed_seconds.count() << "s\n";
};
std::thread t1(f, 1);
std::thread t2(f, 2);
std::thread t3(f, 3);
t1.join();
t2.join();
t3.join();
return 0;
}
- 内置Boost C++库
提供了预编译好的Boost C++库文件. 轻松使用Boost,不用再自己折腾了.更重要的是, Boost C++库跟CrystaX NDK更配!
因为基于更加标准化支持的CrystaX NDK(是的, 这是libcrystax, CrystaX NDK的核心).
例子 如何在Android工程中使用Boost C++库.
- 支持Objective-C and Objective-C++
Google's NDK只支持C C++. CrystaX NDK还支持Objective-C和Objective-C++.
从CrystaX NDK 10.2.0开始, 我们新增支持Objective-C v2 runtime 和初始版本的frameworks (Foundation and CoreFoundation).
这里
是一个小例子, 介绍如何在Android平台使用Objective-C.
简单说明, 只需添加源码文件到Android.mk, LOCAL_SRC_FILES 添加.m (Objective-C) 和.mm (Objective-C++),
添加"APP_OBJC := cocotron" 到 Application.mk.
- 标准C库的大量缺陷修复和功能改进
众所周知Android libc (Bionic)的标准C函数实现有大量bug, 例如strtod,
只对最简单格式的字符串输入有效, 不支持其他标准C定义的规范. 有些缺陷已修复, 有些还未修复.
即使已修复, 也只对后续新版本有效. 开发人员只能自己实现针对已发布版本的适配.
这显著增加了Android原生应用的开发移植时间.
CrystaX NDK在libcrystax中重写了这些有缺陷的函数,而且平台版本无关,对开发人员透明.
开发人员无须关注libcrystax替代Bionic的技术细节, 同时您也无须关注一个缺陷修复是针对哪个Android版本的问题,
我们保证任何缺陷修复都是全部版本生效.
- 未完待续...
CrystaX NDK包含若干开源许可证. 详见每个模块的版权声明文件.
请注意CrystaX NDK发布包中也包括编译器,链接器,文档等的预编译二进制文件.
工具链的源码在GitHub
(你可以使用编译脚本自动下载它).
预编译的GCC和其他二进制文件(GDB, binutils 等等)基于the GNU General Public License (GPL) 或 the GNU Lesser General Public License (LGPL).
详见COPYING和COPYING.LIB,位于 $NDK/toolchains/$tc/prebuilt/$system.
预编译的LLVM/Clang工具链基于
LLVM "BSD" license.
基本上, 授权规则等同于Google's Android NDK - 例如, 允许商业&非商业用途. 唯一区别是CrystaX部分, 基于
BSD 2-clause license.
CrystaX NDK contains code from libc library of FreeBSD project which by-turn contains
code from other projects. Also, several another open-source projects used, such as GNU gcc,
GNU binutils, LLVM clang, LLVM libc++ etc. To see specific authors and/or licenses, look
into appropriate source file. Here is license for those parts which are not derived from
any other projects but written by CrystaX.
Copyright (c) 2011-2024 CrystaX.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY CrystaX ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CrystaX OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of CrystaX.
我们坚持不懈地优化完善CrystaX NDK。但它也并非完美无瑕 - 万物皆如此。如果您发现任何缺陷,请
report it to us提交反馈,我们会尽最大努力修正它。
同时,您可以使用公共讨论组探讨
CrystaX NDK相关问题(例如,当您不确定某些问题是缺陷或特性)。您可以通过网页提交问题,或使用邮件列表:发送电子邮件至
crystax-ndk@googlegroups.com。
这是一个自组织的讨论小组,所以如果您没能即时查看到您发布的内容,请不要担心;请容许我们花一些时间来查看和处理。
最后,如果以上方式无法满足您的需求,您也可以直接联系我们。
如果你不想使用预编译版本, 也可以自己编译.详见以下流程.
配置编译环境
遵循AOSP的标准 (除了Java部分):
警告!!! 编译Windows版本的CrystaX NDK,只支持Linux主机(使用交叉编译). 在Windows主机上编译未经测试和支持.
编译NDK
Thank you for downloading CrystaX NDK
(will start in seconds)!
CrystaX NDK is a fully open source project, free to use in any open-source and commercial environment.
We provide it free for use and don't ask our users to pay in exchange. However, we appreciate your support,
through sending us pull requests,
spreading the news about CrystaX NDK over the world, or just donating:
Who we are
We're a small team of developers who want to make development for Android easier.
Our goal is to create a comprehensive toolkit for native development for Android on C, C++, Objective-C,
and, potentially, in other programming languages already working on modern POSIX systems
(Swift, D, Haskell, Ocaml, Python, Ruby - you name it).
We've already done a lot (as you can see on our main project page),
but we want to do even more. We have a long way to go, but we know how to do it and can clearly see
the steps required to make it happen. You can read more about us here.
Why we need your support
Since we started working on CrystaX NDK, we have funded ourselves without any sponsorship.
That has led us to make money in other ways (such as working as contractors and doing consulting
jobs on other projects) and invest our earnings in the CrystaX NDK project.
Because of this we have only been able to work on NDK part-time, which means it is not
as powerful as it could be.
Having support from the community, we could pay more attention to CrystaX NDK development, without the
distraction on paid contracts. This will speed up CrystaX NDK development as well as
bug fixing and support.
Optionally, sponsors (those who send us $200/month or more) get in exchange a number of perks -
they get priority for consulting or training needs, they can be listed on the front page of the
CrystaX website and mentioned in the project README, etc.
Please read here for more details about
sponsoring options.
WARNING!
When the download is finished, please check that the downloaded file is not corrupted!
The SHA-256 hash must be .
Here is an example of how to check it using OpenSSL:
$ CHECKSUM= && \
FILE= && \
echo "$CHECKSUM $FILE" | sha256sum --check