4

While attempting to cross-compile ICU using android-ndk-r7 in Linux, the following error occurs after configuration when I run 'make'

__/android-ndk-r7/platforms/android-8/arch-arm/usr/include/sys/types.h:124: error: 'uint64_t' does not name a type

This is triggered by the #include <sys/types.h> in icu/source/common/unicode/ptypes.h:25. It appears to be a non-icu issue in android-ndk-n7. In sys/types.h we see

#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

The culprint here is uint64_t, which is defined in #include <stdint.h> at the top of the sys/types.h. Here we see

#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

If STRICT_ANSI or STDC_VERSION and therefore STDC_INT64 are never definied, including sys/types.h will throw an error since uint64_t is never defined. Any code that later calls either int64_t (happens in icu code) and uint64_t will also throw the same error. My temporary fix for this is to define STDC_INT64 at the top of icu's ptypes.h right before #include <sys/types.h>. Is this a bad idea?

skaffman
  • 398,947
  • 96
  • 818
  • 769
tofutim
  • 22,664
  • 20
  • 87
  • 148

5 Answers5

12

The main issue is that uint64_t isn't a defined type in C versions prior to C99. The best way to have it defined is to tell gcc which standard you'd like to use.

For c++, that's passing the -std=gnu++0x flag. For C, that's passing -std=c99

I.e. add a line something like

APP_CPPFLAGS= -std=gnu++0x

to your Application.mk file.

Alternatively, you can just hack it via your #define; I just wouldn't distribute code with such a hack as it's fragile.

Michael O
  • 3,335
  • 1
  • 16
  • 9
  • this is the right answer - but it has to be changed in the configuration file – tofutim Mar 22 '12 at 08:39
  • I found a strange thing: I have `-std=c++11` defined in my *makefile*, but it anyway needed the `-std=gnu++0x` option. Weird. – Hi-Angel Jul 04 '14 at 06:07
3

-D__STDC_INT64__ allows uint64_t and int64_t to be defined in Android's stdint.h.

However, this is not the ideal fix. The error has to do with Android, stdint and -std=c++0x. See What's the difference in GCC between -std=gnu++0x and -std=c++0x and which one should be used? for further information. If you follow the train of thought, an alternate (better??) fix is to modify the icu configuration script so that it calls for gnu++0x instead of c++0x. That's probably the right thing to do.

*** 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.  */

***************
Community
  • 1
  • 1
tofutim
  • 22,664
  • 20
  • 87
  • 148
1

I have resolved this situation by adding in to icudefs.mk into CPPFLGAS an option -D__STDC_INT64__

FatumR
  • 11
  • 2
0

Update to NDK 8e it supports more things from C++11

Also your Application.mk should contains some flags look at my file

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
Gelldur
  • 11,187
  • 7
  • 57
  • 68
0

Can you set -DU_HAVE_UINT64_T=0 ?

Steven R. Loomis
  • 4,228
  • 28
  • 39
  • I removed my __STDC_INT64__ hack and tried -DU_HAVE_UINT4_T=0. No love, same error 'uint64_t' does not name a type. The first error is really a bug in Android. If __STDC_INT64__ is not called, it shouldn't make the uint64_t definition in sys/types.h – tofutim Feb 13 '12 at 19:23
  • I'll fix sys/types.h though and try again. – tofutim Feb 13 '12 at 19:23
  • Nope, it doesn't help. In cstring.h, ICU calls for int64_t (some conversion routines), using -DU_HAVE_UINT4_T=0 doesn't help in this. /__/source/common/cstring.h:109: error: 'int64_t' has not been declared – tofutim Feb 13 '12 at 19:31
  • But I'll try DU_HAVE_INT64T=0 – tofutim Feb 13 '12 at 19:31
  • Nope - error: 'int64_t' has not been declared even with -DU_HAVE_INT64_T=0 – tofutim Feb 13 '12 at 19:36
  • T_CString_int64ToString(char *buffer, int64_t n, uint32_t radix); does not check for U_HAVE_INT64_T, and there are a number of other places that call int64_t in ICU. – tofutim Feb 13 '12 at 19:38
  • @tofutim ptypes.h has: "#if ! U_HAVE_INT64_T .. typedef signed long long int64_t" and same for UINT64_t if !U_HAVE_INTTYPES_H ... hmm, perhaps inttypes is there but it is broken – Steven R. Loomis Feb 14 '12 at 18:03
  • There is inttypes.h in the Android NDK. Should I be writing -DU_HAVE_INTTYPES_H? Where is U_HAVE_INTTYPES_H defined? – tofutim Feb 14 '12 at 21:37
  • configure detects whether inttypes.h is used. It assumes that if inttypes.h is there, that it contains int64_t. – Steven R. Loomis Feb 16 '12 at 00:47
  • It does claim to have found inttypes - configure:6276: checking for inttypes.h configure:6276: result: yes – tofutim Feb 17 '12 at 20:54
  • I tried -DHAVE_INTTYPES_H=1 - but this did not help. common/cstring.h:109: error: 'int64_t' has not been declared – tofutim Feb 17 '12 at 20:57
  • I thought that the problem might be that HAVE_INTTYPES_H = 1 but U_HAVE_INTTYPES_H is not defined. But in config.log I see U_HAVE_INTTYPES_H='1' – tofutim Feb 17 '12 at 21:01
  • STDC_INT64 may be the right answer then. May be something ICU should define. – Steven R. Loomis Feb 20 '12 at 18:24
  • It may be that the problem is related to this: putil.cpp:#if (U_PF_MINGW <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN) && defined(__STRICT_ANSI__) putil.cpp:#undef __STRICT_ANSI__ umutex.h:#if defined(__STRICT_ANSI__) – tofutim Mar 20 '12 at 01:28
  • It seems that the fix is to define __STDC_INT64__ – tofutim Mar 20 '12 at 02:06