【问题标题】: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。这是个坏主意吗?

【问题讨论】:

    标签: android android-ndk icu


    【解决方案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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-01-05
          • 2021-09-21
          • 1970-01-01
          • 2022-07-26
          • 2017-01-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多