Reputation: 10573
I setup conan for cross building android app on my linux, i have my_profile below for conan for this cross building, which that I run conan create . user/testing -pr=my_profile
include(default)
target_host=aarch64-linux-android
android_ndk=$HOME/android-ndk-r21
api_level=21
[settings]
arch=armv8
build_type=Release
compiler=clang
compiler.libcxx=libc++
compiler.version=9
os=Android
os.api_level=$api_level
[build_requires]
[options]
[env]
PATH=[$android_ndk/toolchains/llvm/prebuilt/linux-x86_64/bin]
CHOST=$target_host
AR=$target_host-ar
AS=$target_host-as
LD=$target_host-ld
STRIP=$target_host-strip
RANLIB=$target_host-ranlib
CC=$target_host$api_level-clang
CXX=$target_host$api_level-clang++
CONAN_MAKE_PROGRAM=$android_ndk/prebuilt/linux-x86_64/bin/make
CONAN_CMAKE_TOOLCHAIN_FILE=$android_ndk/build/cmake/android.toolchain.cmake
and I made a very simple file:
#include <fcntl.h>
int raw_fallocate(int fd, off_t length) {
if (fallocate(fd, 0, 0, length) == 0) return 0;
return -1;
}
I found that in the fcntl.h
, it only defines fallocate
when __ANDROID_API >=21
with #ifdef
so in my CMakeLists.txt
, I need to put
target_compile_definitions(hello PRIVATE __ANDROID_API__=21)
to make it compile, otherwise, the compiler will complain it cannot find definition of fallocate
.
That all make sense. However, when I put this preprocessor definition, I still got a warning message saying:
In file included from <built-in>:413:
<command line>:1:9: warning: '__ANDROID_API__' macro redefined [-Wmacro-redefined]
#define __ANDROID_API__ 21
^
<built-in>:405:9: note: previous definition is here
#define __ANDROID_API__ 16
^
1 warning generated.
What I don't understand is I could not find this built-in thing..., i searched my whole android_ndk folder, and could not find where is this #define __ANDROID_API__ 16
Also I only have android_ndk v21 installed, I have no idea where this version of 16 came from.
Any idea?
Upvotes: 2
Views: 5217
Reputation: 57173
This #define __ANDROID_API__ 16
comes from the NDK itself (this is the lowest supported API for android-ndk-r21. To set it to 21, you must pass ANDROID_PLATFORM
parameter to CMake. Update: this is actually wrong. For ABI arm64-v8a
the minimal API is 21. So, the problem is that arch=armv8
didn't work.
According to the conan instructions, set os.api_level=21
should have worked. But with this approach, you should not supply the CONAN_CMAKE_TOOLCHAIN_FILE
. Update: this does not work because conan
is not compatible with NDK r21.
I assume that when you do supply CONAN_CMAKE_TOOLCHAIN_FILE
, all the settings, like CC=
and AR=
become irrelevant. Same for os.api_level
and arch
. But if you replace cmake
with a script that calls the original cmake
binary and sets the necessarycommand-line parameters, including -DANDROID_PLATFORM=android-21
, you should be set. Simply add to my_profile
:
CONAN_CMAKE_PROGRAM=cmake-wrapper
This approach is used in https://github.com/bincrafters/conan-android_ndk_installer package.
Upvotes: 4
Reputation: 10573
So I've been digging into this a little bit, and I think I found where the problem is. As @Alex Cohn said, the android ndk sets the min api level to 16 in the file
$android_ndk/build/cmake/platforms.cmake
, it says on the first line set(NDK_MIN_PLATFORM_LEVEL "16")
. After I change it to 21, everything works.
Now the question becomes: How can I override this value externally without touching this platforms.cmake
file (I just don't want to touch files come with ndk package)? I tried to put set(NDK_MIN_PLATFORM_LEVEL "16")
in my CMakelists.txt
file for my project, but that does not work as I believe it is overridden later on by platforms.cmake
.
Of course the second method of using conan
's ndk-installer also works, and I checked the same platforms.cmake
file in the installed ndk folder, it has the same value of 16
. So there must be somewhere in conan
settings that updated the value to 21
, and I would like to learn where / how this is changed when using ndk-installer, so I can do the same for my manually installled android ndk.
Upvotes: 0