为 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 触发的。这似乎是 android-ndk-n7 中的非 icu 问题。在 sys/types.h 我们看到

#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_ANSISTDC_VERSION 并因此 STDC_INT64 从未定义,包括 sys/types.h 将抛出错误,因为 uint64_t 从未定义.以后调用 int64_t(发生在 icu 代码中)和 uint64_t 的任何代码也将引发相同的错误。我对此的临时解决方法是在 icu 的 ptypes.h 顶部 #include 之前定义 STDC_INT64。这是个坏主意吗?

【问题讨论】:

【参考方案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' 没有命名类型的主要内容,如果未能解决你的问题,请参考以下文章

编译icu库(用到了cygwin)

Windows 下 VS2019 编译 icu 库

Windows 下 VS2019 编译 icu 库

Windows 下 VS2019 编译 icu 库

Qt 5.6.0 动态编译(VS2013 x86 target xp openssl icu webkit)

Qt5.9.0正式版动态编译 (VS2017) 支持WebEngine ICU OpenSSL