Skip to content

Unable to build for Android (even on NDK r23b) #45

Closed
@sjevtic

Description

I have been having considerable problems compiling for Android. In particular, the error from #9 is familiar:

../src/fileencryptor/../cryptbase/../common_be.h:145:10: error: no matching function for call to 'bytesToHexString'

@bepaald concluded here:

Apparently, clang is the problem (on MacOS, it works fine on Linux).

Following a deeper investigation, I concluded that the problem is not actually clang itself, but rather libc++, which is LLVM's implementation of the C++ standard library. The problem is fairly uncommon on the Linux desktop, where GNU libstdc++ is still the most commonly used C++ standard library, even when using clang to compile. On Ubuntu 20.04 for example, builds with clang are by default still done by including headers and linking against libraries from GNU libstdc++.

The exact same issue was opened against the NDK itself. It is a longstanding issue (2.5 years) with no resolution, apparently in large part because the problem has not been fully addressed within upstream libc++. However, an astute comment notes that there is an open but still unmerged review for a fix.

To be clear, this is not a defect in signalbackup-tools. Rather, libc++ has a defect that substantially breaks its C++ 17 compatibility. However, given the current (and increasing) prevalence of the LLVM toolchain, I believe that compatibility with LLVM's libc++ remains a worthy goal, especially in the case of Android where Google has been steadily removing support for the GNU tools for years already. Unlike the workaround discussed in #9 for the macOS use case, the use of gcc and libstdc++ is not a practical option for Android, thus motivating me to open this new issue.

Further examination of the fix reveals that it is effectively a header-only change, so it can be easily deployed without either a standard library rebuild or even a system configuration change. In particular what I did was create a new subdirectory in my signalbackup-tools workspace ("sysinclude") into which I placed the new header. Then I prepended the subdirectory to the system include search path with a clang command line option: -isystem./sysinclude". The matter cannot be readily addressed with a source change since in some cases the included system headers include <memory> ahead of the explicit inclusions of the header directly by the signalbackup-tools source itself.

As an alternative approach which would likely lead to increased compatibility on older platforms, signalbackup-tools could be reworked such that it targets an older C++ standard (e.g., C++ 14) for which support is more mature across a larger range of environments.

It is also worth noting that in this environment, setlocale() is in the global namespace rather than the "std" namespace. I addressed this naively in sqlitedb/widestring.cc with a preprocessor definition:

#ifdef NDK_LOCALE_WORKAROUND
  setlocale(LC_ALL, "en_US.utf8");
#else
  std::setlocale(LC_ALL, "en_US.utf8");
#endif

The change may then be activated as needed as needed with a clang command line option: -DNDK_LOCALE_WORKAROUND.

Note that earlier NDK versions cause even more problems: of particular note, std::filesystem support needed by signalbackup-tools was not supported bu the bundled libc++ shipped with NDK versions prior to r22.

Of course, at the end of the day, the user attempting to build signalbackup-tools for his/her preferred platform should not need to be concerned with such details; administration of such particulars should be handled with Autoconf/Makefile or a similar technology; this has already been discussed in both #11 and #13.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions