为 Android 编译 ICU - 'uint64_t' 没有命名类型
Posted
技术标签:
【中文标题】为 Android 编译 ICU - \'uint64_t\' 没有命名类型【英文标题】:Compiling ICU for Android - 'uint64_t' does not name a type为 Android 编译 ICU - 'uint64_t' 没有命名类型 【发布时间】:2012-02-12 07:20:12 【问题描述】:在Linux中尝试使用android-ndk-r7交叉编译ICU时,运行'make'时配置后出现以下错误
__/android-ndk-r7/platforms/android-8/arch-arm/usr/include/sys/types.h:124: error: 'uint64_t' does not name a type
这是由 icu/source/common/unicode/ptypes.h:25 中的 #include
#ifdef __BSD_VISIBLE
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
typedef uint64_t u_int64_t;
#endif
这里的罪魁祸首是 uint64_t,它在 sys/types.h 顶部的#include
#if !defined __STRICT_ANSI__ || __STDC_VERSION__ >= 199901L
# define __STDC_INT64__
#endif
...
#if defined(__STDC_INT64__)
typedef __int64_t int64_t;
typedef __uint64_t uint64_t;
#endif
如果 STRICT_ANSI 或 STDC_VERSION 并因此 STDC_INT64 从未定义,包括 sys/types.h 将抛出错误,因为 uint64_t 从未定义.以后调用 int64_t(发生在 icu 代码中)和 uint64_t 的任何代码也将引发相同的错误。我对此的临时解决方法是在 icu 的 ptypes.h 顶部 #include
【问题讨论】:
【参考方案1】:主要问题是 uint64_t 不是 C99 之前的 C 版本中定义的类型。 定义它的最好方法是告诉 gcc 你想使用哪个标准。
对于 c++,这是通过 -std=gnu++0x
标志。对于 C,这是通过 -std=c99
即添加一行类似
APP_CPPFLAGS= -std=gnu++0x
到您的 Application.mk 文件。
或者,您可以通过#define 破解它;我只是不会分发带有这种 hack 的代码,因为它很脆弱。
【讨论】:
这是正确答案 - 但必须在配置文件中更改 我发现了一件奇怪的事情:我在我的 makefile 中定义了-std=c++11
,但它仍然需要-std=gnu++0x
选项。很奇怪。【参考方案2】:
-D__STDC_INT64__ 允许在 Android 的 stdint.h 中定义 uint64_t 和 int64_t。
但是,这不是理想的解决方法。该错误与 Android、stdint 和 -std=c++0x 有关。请参阅What's the difference in GCC between -std=gnu++0x and -std=c++0x and which one should be used? 了解更多信息。如果您遵循思路,另一种(更好的??)修复方法是修改 icu 配置脚本,使其调用 gnu++0x 而不是 c++0x。这可能是正确的做法。
*** 7238,7244 ****
OLD_CFLAGS="$CFLAGS"
OLD_CXXFLAGS="$CXXFLAGS"
CFLAGS="$CFLAGS -std=gnu99 -D_GCC_"
! CXXFLAGS="$CXXFLAGS -std=c++0x"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
--- 7241,7247 ----
OLD_CFLAGS="$CFLAGS"
OLD_CXXFLAGS="$CXXFLAGS"
CFLAGS="$CFLAGS -std=gnu99 -D_GCC_"
! CXXFLAGS="$CXXFLAGS -std=gnu++0x"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
***************
【讨论】:
【参考方案3】:我已经通过在 icudefs.mk 中添加一个选项 -D__STDC_INT64__ 到 CPPFLGAS 来解决这种情况
【讨论】:
【参考方案4】:你能设置-DU_HAVE_UINT64_T=0
吗?
【讨论】:
我删除了我的 STDC_INT64 hack 并尝试了 -DU_HAVE_UINT4_T=0。不爱,同样的错误'uint64_t'没有命名类型。第一个错误实际上是 Android 中的错误。如果未调用 STDC_INT64,则不应在 sys/types.h 中定义 uint64_t 我会修复 sys/types.h 然后再试一次。 不,它没有帮助。在 cstring.h 中,ICU 调用 int64_t(一些转换例程),使用 -DU_HAVE_UINT4_T=0 对此没有帮助。 /__/source/common/cstring.h:109: 错误:'int64_t' 尚未声明 但我会试试 DU_HAVE_INT64T=0 不 - 错误:'int64_t' 尚未声明,即使使用 -DU_HAVE_INT64_T=0【参考方案5】:更新到 NDK 8e,它支持来自 C++11 的更多内容
您的 Application.mk 还应该包含一些标志,看看我的文件
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 -std=c++11 -DDEBUG=1
APP_USE_CPP0X := true
NDK_TOOLCHAIN_VERSION=4.7
【讨论】:
以上是关于为 Android 编译 ICU - 'uint64_t' 没有命名类型的主要内容,如果未能解决你的问题,请参考以下文章