android/ndk

mmap causes compile errors on r15c (unknown identifier)

Closed this issue · 12 comments

Description

Usage of mmap with NDK r15c are flagged as errors (use of undeclared identifier 'mmap'). This was not an issue with previous versions of the NDK (including r15 and r15b). This can easily be reproduced by adding usage of mmap to a native project (or include sqlite3).

This issue can be worked around by using the deprecated headers (adding APP_DEPRECATED_HEADERS := true to Application.mk)

Environment Details

  • NDK Version: 15.2.4203891
  • Build sytem: Both NDK-Build and CMAKE
  • Host OS: Windows 10 Enterprise 64bit
  • Compiler: Clang
  • ABI: armeabi-v7a
  • STL: c++_shared
  • NDK API level: 15 (Target/Compile = 26. Minimum = 15)
  • Device API level: 23 (6.0.1)

Are you setting _FILE_OFFSET_BITS=64?

I believe not (I'm not exactly sure where it would be defined, but I checked all our .mk files and places that call through to ndk-build)

I created a bare bones c++ project via Android studio and added sqlite3 to the project with no additional modifications to confirm this issue before logging.

It could also be in one of your sources.

Add the following just above the failing call to mmap:

#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
#error "_FILE_OFFSET_BITS=64"
#elif defined(__USE_FILE_OFFSET64)
#error "__USE_FILE_OFFSET64"
#endif

If either of those errors happens, then something is setting it. It could be one of your build files, your build system (we don't do this in ndk-build though, so not in this case), one of your source files, or one of your dependencies' source files.

We are not using the 64bit offset (The code compiles successfully).

Any chance you just forgot to include <sys/mman.h>? Maybe the old headers leaked that from some other header you were including.

If that's not the case either, I'm out of guesses and will need a test case to do any more (my trivial test case worked fine).

Apologies for this, but we do actually define 64 bits file offset in code (I put the code inside the sqlite3.c file instead of a different file).

What are the implications for this? (I tried to blindly use mmap64 and that didn't work)

edit: Using mmap64 works in my basic test example, so I guess this is highly unlikely at this point to be an NDK issue and more an issue with us (although it's sad that sqlite3 no longer compiles out of the box with ndk r15c)

enh commented

see https://android.googlesource.com/platform/bionic/+/master#32_bit-ABI-bugs-is-32_bit-1 for the full story. but basically, stop defining _FILE_OFFSET_BITS and r15 will behave the same as r14 did.

Thank you for the assistance.

Sorry for wasting your time on a non-issue.

No worries, happy to help :)

enh commented

and it's actually useful feedback that even in r15c where everything is strictly correct, users are confused by the diagnostics. we'll look into what we can do to improve these...

I was having the same issue, and this is what fixed for me.
couchbaselabs/couchbase-lite-libsqlcipher#23

One simple way to fix the missing mmap problem, as long as you can live without large-file support, is to add the following option to your GCC command-line:

-DSQLITE_DISABLE_LFS

which prevents _FILE_OFFSET_BITS from being defined at (in my version) line 75 of the SQLite amalgamation source file sqlite3.c.