SQLite Forum

Compile error for Android
Login

Compile error for Android

(1) By anonymous on 2024-02-18 12:21:13 [source]

Hello,

When compiling sqlite for Android I encountered the following error:

libtool: compile:  armv7a-linux-androideabi21-clang -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.43.2\" "-DPACKAGE_STRING=\"sqlite 3.43.2\"" -DPACKAGE_BUGREPORT=\"http://www.sqlite.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.43.2\" -D_FILE_OFFSET_BITS=64 -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_FDATASYNC=1 -DHAVE_USLEEP=1 -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1 -DHAVE_DECL_STRERROR_R=1 -DHAVE_STRERROR_R=1 -DHAVE_POSIX_FALLOCATE=1 -DHAVE_ZLIB_H=1 -I. -I/var/tmp/deps/src/sqlite-autoconf -D_REENTRANT=1 -DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_HAVE_ZLIB -fPIC -mthumb -MT sqlite3.lo -MD -MP -MF .deps/sqlite3.Tpo -c /var/tmp/deps/src/sqlite-autoconf/sqlite3.c -o sqlite3.o
/var/tmp/deps/src/sqlite-autoconf/sqlite3.c:38937:8: error: incompatible integer to pointer conversion assigning to 'char *' from 'int' [-Wint-conversion]
  zErr =
       ^
1 error generated.

This is with the NDK r26b and didn't happen in the past (e.g. with r25c).

I checked the code in question and it seems to be expecting strerror_r to return a char pointer.

The NDK string header contains this:

#if defined(__USE_GNU) && __ANDROID_API__ >= 23
char* _Nonnull strerror_r(int __errno_value, char* _Nullable __buf, size_t __n) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23);
#else /* POSIX */
int strerror_r(int __errno_value, char* _Nonnull __buf, size_t __n);
#endif

Since I'm using API level 21 it will not return a char pointer. It looks like the code and/or configure tests have to be adjusted for this edge case.

(2.1) By Stephan Beal (stephan) on 2024-02-18 14:57:55 edited from 2.0 in reply to 1 [link] [source]

/var/tmp/deps/src/sqlite-autoconf/sqlite3.c:38937:8: error:

You'll need to tell us precisely which version you're working from. Without that, the line number is useless.

$ grep -c 'zErr =' sqlite3.c
117

Edit: i now see the version being passed along in the compilation flags, but (A) that is unreliable and (B) don't do that - the source code includes its version number. We need the hash of the version you're using.

(3) By anonymous on 2024-02-18 16:05:55 in reply to 2.1 [link] [source]

I just realized I was not building the latest version of SQLite at all, sorry.

It still happens on 3.45.1 however:

libtool: compile:  armv7a-linux-androideabi21-clang -DPACKAGE_NAME=\"sqlite\" -DPACKAGE_TARNAME=\"sqlite\" -DPACKAGE_VERSION=\"3.45.1\" "-DPACKAGE_STRING=\"sqlite 3.45.1\"" -DPACKAGE_BUGREPORT=\"http://www.sqlite.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"sqlite\" -DVERSION=\"3.45.1\" -D_FILE_OFFSET_BITS=64 -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_FDATASYNC=1 -DHAVE_USLEEP=1 -DHAVE_LOCALTIME_R=1 -DHAVE_GMTIME_R=1 -DHAVE_DECL_STRERROR_R=1 -DHAVE_STRERROR_R=1 -DHAVE_POSIX_FALLOCATE=1 -DHAVE_ZLIB_H=1 -I. -I/var/tmp/deps/src/sqlite-autoconf -D_REENTRANT=1 -DSQLITE_THREADSAFE=1 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_HAVE_ZLIB -fPIC -mthumb -MT sqlite3.lo -MD -MP -MF .deps/sqlite3.Tpo -c /var/tmp/deps/src/sqlite-autoconf/sqlite3.c -o sqlite3.o
/var/tmp/deps/src/sqlite-autoconf/sqlite3.c:39267:8: error: incompatible integer to pointer conversion assigning to 'char *' from 'int' [-Wint-conversion]
  zErr =
       ^
1 error generated.

This is sqlite-autoconf-3450100.tar.gz downloaded from the website just five minutes ago.

The code in question in the source repo seems to be this: https://github.com/sqlite/sqlite/blob/6161cdd446eec170f7c0edf58d0d72a2cd3c5f85/src/os_unix.c#L1287-L1302

(B) don't do that - the source code includes its version number

The compile flags are not my choice, I am merely using the included autoconf script :)

(4) By Stephan Beal (stephan) on 2024-02-18 16:15:30 in reply to 3 [link] [source]

The code in question in the source repo seems to be this: ...

As a quick workaround, can you please try a local patch like (untested):

#if (defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)) \
  && (!defined(ANDROID) && !defined(__ANDROID__))
...

And let us know if that works for you?

Apparently the existing #if check is matching for Android but shouldn't be.

(5) By anonymous on 2024-02-18 17:13:19 in reply to 4 [link] [source]

That compiles fine.

What also works is removing the || defined(__USE_GNU) part.

(6) By Stephan Beal (stephan) on 2024-02-18 17:22:37 in reply to 5 [link] [source]

That compiles fine.

Does it run, though? My reading of your reported warning is that strerror_p() is not defined on your target system, so the resulting library/app will fail to load due to an unresolved symbol error.

My proposed change would look something like:

Index: src/os_unix.c
==================================================================
--- src/os_unix.c
+++ src/os_unix.c
@@ -1294,14 +1294,16 @@
   ** If the code incorrectly assumes that it is the POSIX version that is
   ** available, the error message will often be an empty string. Not a
   ** huge problem. Incorrectly concluding that the GNU version is available
   ** could lead to a segfault though.
   */
-#if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
+# if !defined(ANDROID) && !defined(__ANDROID__)
+#  if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU)
   zErr =
-# endif
+#  endif
   strerror_r(iErrno, aErr, sizeof(aErr)-1);
+# endif
 
 #elif SQLITE_THREADSAFE
   /* This is a threadsafe build, but strerror_r() is not available. */
   zErr = "";
 #else

(7) By anonymous on 2024-02-18 19:25:36 in reply to 6 [link] [source]

Yes, it does run too.

As I quoted from the system headers in the first post strerror_r exists, it just doesn't return a char pointer (in these circumstances).

(8) By Stephan Beal (stephan) on 2024-02-18 20:25:54 in reply to 7 [link] [source]

As I quoted from the system headers in the first post strerror_r exists, it just doesn't return a char pointer (in these circumstances).

Indeed, you did. i got distracted the other details and didn't reach that point! We'll get this patched with the first of the upthread approaches by tomorrow at the latest. Thank you for the report and confirmation of the patch.

(9) By anonymous on 2024-02-19 18:10:34 in reply to 1 [link] [source]

From https://linux.die.net/man/3/strerror_r:

int strerror_r(int errnum, char *buf, size_t buflen);
            /* XSI-compliant */

char *strerror_r(int errnum, char *buf, size_t buflen);
            /* GNU-specific */

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

The XSI-compliant version of strerror_r() is provided if:
(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE
Otherwise, the GNU-specific version is provided. 

The strerror_r() function is similar to strerror(), but is thread safe.

If no feature test macros are explicitly defined, then (since glibc 2.4) _POSIX_SOURCE is defined by default with the value 200112L, so that the XSI-compliant version of strerror_r() is provided by default.

The XSI-compliant strerror_r() is preferred for portable applications.