Running CMake from command line within an Android NDK project - android

How might one run an NDK Cmake build independently from the rest of an Android project, ideally from the command line, external to Android Studio?
The equivalent of running ndk-build from the jni directory for slightly older Android NDK projects.
I need to investigate exactly what the calls to the compiler look like, and I can't seem to get this information when building the whole project from within Android Studio
My first attempt was just to run cmake from the project/app directory containing CMakeLists.txt, but this informs me that cmake is not installed - so how is Android Studio managing to build it then?

If your goal is to just run from the command line (as opposed to trying to do exactly what gradle is doing), just use cmake the way you normally would:
$ cmake -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=whatever $YOUR_SOURCE_DIR
Alternatively, you can just run ./gradlew from the command line.

Your original problem is that you cannot see the command-line invocation when building with Android Studio.
You can get the command line arguments to the compiler by editing your app/build.gradle file.
defaultConfig {
...
externalNativeBuild {
cmake {
...
arguments "-DCMAKE_VERBOSE_MAKEFILE=1", ...
}
}
}
In Adroid Studio's Gradle Console pane, you will then see the command line for the compiler and linker like so:
[1/176] /home/bram/android-sdk-linux/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang --target=armv7-none-linux-androideabi --gcc-toolchain=/home/bram/android-sdk-linux/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 --sysroot=/home/bram/android-sdk-linux/ndk-bundle/sysroot -isystem /home/bram/android-sdk-linux/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=19 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -marm -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security -Os -DNDEBUG -fPIC -MD -MT /home/bram/src/GPGOAP/CMakeFiles/gpgoap.dir/astar.c.o -MF /home/bram/src/GPGOAP/CMakeFiles/gpgoap.dir/astar.c.o.d -o /home/bram/src/GPGOAP/CMakeFiles/gpgoap.dir/astar.c.o -c /home/bram/src/GPGOAP/astar.c

As detail to the accepted answer:
The complete set of parameters passed to CMake is written to:
<project-root>/<module-root>/.externalNativeBuild/cmake/<build-type>/<ABI>/cmake_build_command.txt`
See for details: https://developer.android.com/ndk/guides/cmake.html#build-command

Related

Updating application with C++ native library to NDK 18, cmake isn't including required sysroot platform include directory

I have an Android application, developed with Android Studio, that is using a very old build system - NDK 14 with CMake 3.6 and AGP 3.5. I'm trying to update it to NDK 18 (I eventually want to update it to latest NDK, but baby steps) using CMake 3.18.1 and AGP 4.2.2 with Gradle 6.7.1, but the build fails due to errors finding a system include file asm/types.h.
Looking at the clang++ compile command that CMake generates, it is clearly missing the ${SYSROOT}/usr/include/<platform-abi> directory.
My CMake (which worked well for NDK 14 with CMake 3.6.1) has these lines:
if(${CMAKE_ANDROID_ARCH_ABI} STREQUAL arm64-v8a)
include_directories(${ANDROID_SYSROOT}/usr/include/aarch64-linux-android)
elseif(${CMAKE_ANDROID_ARCH_ABI} STREQUAL x86_64)
include_directories(${ANDROID_SYSROOT}/usr/include/x86_64-linux-android)
endif()
Running CMake with --trace-expand, I can see it correctly parses those lines:
…
… arm64Release|arm64-v8a :/home/…/myapp/mynativelib/CMakeLists.txt(5):
if(arm64-v8a STREQUAL arm64-v8a )
… arm64Release|arm64-v8a :/home/…/myapp/mynativelib/CMakeLists.txt(6):
include_directories(/home/…/Android/Sdk/ndk/18.1.5063045/sysroot/usr/include/aarch64-linux-android )
…
But the build.ninja file generated does not have this include directory - it contains compile directives that look like so:
build CMakeFiles/mynativelib.dir/home/…/mynativelib/MyClass.cpp.o: \
CXX_COMPILER__mynativelib_Debug /home/…/mynativelib/MyClass.cpp || \
cmake_object_order_depends_target_mynativelib
DEFINES = -DANDROID -DCMAKE_BUILD_TYPE=Debug -DDEBUG -DMIXIT=0 -DNDEBUG -DRELEASE=0 … -D__GXX_EXPERIMENTAL_CXX0X__ -D__STDC_CONSTANT_MACROS
DEP_FILE = CMakeFiles/mynativelib.dir/home/…/mynativelib/MyClass.cpp.o.d
FLAGS = -std=c++14 -fno-stack-protector -ffor-scope -fexceptions -O0 -fno-limit-debug-info \
-fPIC -fno-stack-protector -fpic -ffunction-sections -funwind-tables -no-canonical-prefixes \
-Os -fomit-frame-pointer -fomit-frame-pointer -UNDEBUG -fno-omit-frame-pointer -Ijni -Wformat \
-Wa,--noexecstack -fno-stack-protector -std=c++14
INCLUDES = -I/home/…/Android/Sdk/ndk/18.1.5063045/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/include \
-I../../../../../../../some-custom-include-from-cmake \
-isystem /home/…/Android/Sdk/ndk/18.1.5063045/sources/cxx-stl/llvm-libc++/include
-isystem /home/…/Android/Sdk/ndk/18.1.5063045/sources/cxx-stl/llvm-libc++abi/include
OBJECT_DIR = CMakeFiles/mynativelib.dir
OBJECT_FILE_DIR = CMakeFiles/mynativelib.dir/home/…/mynativelib
I can see that the build command include the some-custom-include-from-cmake include directory, that is added in my CMakeLists.txt file, as well as all the cxx-stl/llvm-libc++ includes that are also added in the CMakeLists.txt file, but the /usr/include/<android-abi> platform include dir is missing.
Even if I use the include_directories(${ANDROID_SYSROOT}/usr/include/aarch64-linux-android) command without the if check, right near where the other include_directories() commands that do make it into the build file, it is still missing from the build file. I even tried to add the -I flag directly using set(CMAKE_CXX_FLAGS) and that didn't cause the required include dir to be listed.
OTOH, if I change the include_directories(${ANDROID_SYSROOT}…) to be something that doesn't start with ${ANDROID_SYSROOT}, or points to a non-existing directory - then whatever I put there does make it to the build.ninja file.
Looks like something is very purposefully removing include directories that are in ${ANDROID_SYSROOT} maybe?

android studio 3.2 initial build error (testCCompiler.c file not found, windows 10)

today I installed android studio 3.2.1 on my windows 10 PC at home.
(I have installed a previous version 3 months ago but I unstalled it before installing new one, because it had similar problem I remember)
When I install the program, it is supposed to build itself but it fails with below messages.
Run Build Command:"C:/Users/Chan
Kim/AppData/Local/Android/Sdk/cmake/3.6.4111459/bin/ninja.exe" "cmTC_4535f"
[1/2] Building C object CMakeFiles/cmTC_4535f.dir/testCCompiler.c.o
FAILED:
C:\Users\CHANKI~1\AppData\Local\Android\Sdk\NDK-BU~1\TOOLCH~1\llvm\prebuilt\WINDOW~1\bin\clang.exe
--target=armv7-none-linux-androideabi24 --gcc-toolchain="C:/Users/Chan
Kim/AppData/Local/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64"
--sysroot="C:/Users/Chan Kim/AppData/Local/Android/Sdk/ndk-bundle/sysroot"
-isystem C:/Users/Chan
Kim/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi
-g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong
-no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
-mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security -fPIE
-o CMakeFiles/cmTC_4535f.dir/testCCompiler.c.o -c
C:\ANDPRG\app\.externalNativeBuild\cmake\release\armeabi-v7a\CMakeFiles\CMakeTmp\testCCompiler.c
error: no such file or directory:
'Kim/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi'
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt
-- Configuring incomplete, errors occurred!
See also "C:/ANDPRG/app/.externalNativeBuild/cmake/release/armeabi-v7a/CMakeFiles/CMakeOutput.log".
See also "C:/ANDPRG/app/.externalNativeBuild/cmake/release/armeabi-v7a/CMakeFiles/CMakeError.log".
Build command failed.
Error while executing process C:\Users\Chan Kim\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {-HC:\ANDPRG\app -BC:\ANDPRG\app\.externalNativeBuild\cmake\debug\armeabi-v7a -DANDROID_ABI=armeabi-v7a -DANDROID_PLATFORM=android-24 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=C:\ANDPRG\app\build\intermediates\cmake\debug\obj\armeabi-v7a -DCMAKE_BUILD_TYPE=Debug -DANDROID_NDK=C:\Users\Chan Kim\AppData\Local\Android\Sdk\ndk-bundle -DCMAKE_CXX_FLAGS= -DCMAKE_TOOLCHAIN_FILE=C:\Users\Chan Kim\AppData\Local\Android\Sdk\ndk-bundle\build\cmake\android.toolchain.cmake -DCMAKE_MAKE_PROGRAM=C:\Users\Chan Kim\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\ninja.exe -GAndroid Gradle - Ninja}
-- Check for working C compiler: C:/Users/Chan Kim/AppData/Local/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe
-- Check for working C compiler: C:/Users/Chan Kim/AppData/Local/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -- broken
It fails with the following output:
Change Dir: C:/ANDPRG/app/.externalNativeBuild/cmake/debug/armeabi-v7a/CMakeFiles/CMakeTmp
Run Build Command:"C:/Users/Chan
Kim/AppData/Local/Android/Sdk/cmake/3.6.4111459/bin/ninja.exe" "cmTC_23398"
[1/2] Building C object CMakeFiles/cmTC_23398.dir/testCCompiler.c.o
FAILED:
C:\Users\CHANKI~1\AppData\Local\Android\Sdk\NDK-BU~1\TOOLCH~1\llvm\prebuilt\WINDOW~1\bin\clang.exe
--target=armv7-none-linux-androideabi24 --gcc-toolchain="C:/Users/Chan
Kim/AppData/Local/Android/Sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64"
--sysroot="C:/Users/Chan Kim/AppData/Local/Android/Sdk/ndk-bundle/sysroot"
-isystem C:/Users/Chan
Kim/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi
-g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong
-no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
-mthumb -mfpu=neon -Wa,--noexecstack -Wformat -Werror=format-security -fPIE
-o CMakeFiles/cmTC_23398.dir/testCCompiler.c.o -c
C:\ANDPRG\app\.externalNativeBuild\cmake\debug\armeabi-v7a\CMakeFiles\CMakeTmp\testCCompiler.c
error: no such file or directory:
'Kim/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/arm-linux-androideabi'
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt
-- Configuring incomplete, errors occurred!
See also "C:/ANDPRG/app/.externalNativeBuild/cmake/debug/armeabi-v7a/CMakeFiles/CMakeOutput.log".
See also "C:/ANDPRG/app/.externalNativeBuild/cmake/debug/armeabi-v7a/CMakeFiles/CMakeError.log".
I saw similar question on SO but it's not exactly same to my situtation and I tried the suggestions(Refresh linked C++ project) and it didn't work. and some advices are for linux. The first error message is 'can't find cCompilerProgram.c' for cmake.(When I look into the folder, the file is not actuall there) How can I solve this? By the way, my login name on windows 10 is 'Chan Kim' with space in the middle. Can it have any problem? I guess the testCCompiler.c file is what the build process make during the build.
Any suggestion will be deeply appreciated.
the error actually reads:
-- Check for working C compiler: .../prebuilt/windows-x86_64/bin/clang.exe -- broken
this seems related.
My problem was that my login name in windows10 was 'Chan Kim' and the error log shows it cannot parse down the folder name containing 'Chan Kim' and it cannot process space in the folder name. So I created a new account 'ckim' and did the same (it downloads huge amount of data under C:\Users\ckim this time) and everything works fine.
So DON'T USE USERNAME WITH SPACE whne using android studio. (I don't know why the book and android studio doesn't warn about this situtation. I read in the book, if my login name contains Korean characters, it won't work. but it turns out login name with space doesn't work either).
Hope this be useful for someone.
ADD : I tried configuring the SDK again using Users\ChanKim\AppData folder and it works too. (originally it was using Users\Chan Kim\AppData)

gradle build for android native project fails with "unable to open output file" error

I am trying to build an android native project using gradle. While the build passes for the architectures arm64-v8a, x86 and x86_64, it fails for armeabi-v7a with a unique error:
/{sdk-path}/ndk-bundle/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=15 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -frtti -fexceptions -Os -DNDEBUG -O2 -DNDEBUG -D_NDEBUG=1 -s -fPIC -Wdeprecated-declarations -std=c++14 -MD -MT CMakeFiles/acplocalnet.dir/src/main/cpp/HttpTransferCallbackHookImpl.cpp.o -MF CMakeFiles/acplocalnet.dir/src/main/cpp/HttpTransferCallbackHookImpl.cpp.o.d -o CMakeFiles/acplocalnet.dir/src/main/cpp/HttpTransferCallbackHookImpl.cpp.o -c /Users/acpl/workspace/ACPLocal_net_Android/net/project/android/acplocalnet/app/src/main/cpp/HttpTransferCallbackHookImpl.cpp
clang++: warning: argument unused during compilation: '-s' [-Wunused-command-line-argument]
error: unable to open output file '/apps/temp/HttpTransferCallbackHookImpl-baaa5e.s': 'No such file or directory'
1 error generated.
ninja: build stopped: subcommand failed.
The issue here is I am able to run this command and it builds the native libraries successfully when run the machine locally, but it fails when it is run through jenkins. The other amusing thing is that it fails only for the abi armeabi-v7a and passes for all other architectures.
I have verified the user, path and environment variables like ANDROID_HOME and ANDROID_NDK_HOME which are same when I run using the command line on the machine locally and when run using jenkins.
The command was not able to open the output files in the location "/apps/temp" as this directory was not present in the slave. This temp directory present in the jenkins master and was passed to the slave which was visible in the build variable TMP_DIR. Explicitly mentioning a valid temporary directory for the jenkins slave fixed the issue.

Error on build cpp project in android studio in linux

I installed android sdk, platform and build tools and NDK in my ArchLinux to develop with android-studio and c++. I've created a simple "hello world program" just to start but it is not compiling. The error message on build returned by android studio is "A problem occurred configuring project ':app'. executing external native build for cmake /home/fabio/AndroidStudioProjects/HelloWorld/app/CMakeLists.txt"
On the CMakeError.log:
Determining if the C compiler works failed with the following output:
Change Dir: /home/fabio/AndroidStudioProjects/HelloWorld/app/.externalNativeBuild/cmake/debug/armeabi/CMakeFiles/CMakeTmp
Run Build Command:"/opt/android-sdk/cmake/3.6.3155560/bin/ninja" "cmTC_be251"
[1/2] Building C object CMakeFiles/cmTC_be251.dir/testCCompiler.c.o
FAILED: /opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -target armv5te-none-linux-androideabi -gcc-toolchain /opt/android-ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 --sysroot=/opt/android-ndk/platforms/android-15/arch-arm -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -fno-integrated-as -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -o CMakeFiles/cmTC_be251.dir/testCCompiler.c.o -c /home/fabio/AndroidStudioProjects/HelloWorld/app/.externalNativeBuild/cmake/debug/armeabi/CMakeFiles/CMakeTmp/testCCompiler.c
/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directoryninja: build stopped: subcommand failed.
For the creation of the project, I just checked the option "Include c++ support" and started with a blank activity, changed no code then.
Edit Tryied instlalling libtinfo as suggested in this thread but didn't worked.
I experienced the same issue. Quite many of the other distributions often have outdated packages. They still use ncurses 5 instead of ncurses 6 (libtinfo seems to belong to ncurses). Assuming, that the android ndk's version of clang was built on such a system, it was worth a try to use ncurses 5. From the Arch User Repositories I was able to install the latest version of ncurses5-compat-libs (and I also installed the 32bit version: lib32-ncurses5-compat-libs). This solved the problem for me. If you have it installed already, try reinstalling or updating it, if it is outdated.

Android ndk-r8 "error trying to exec 'cc1plus': execvp: No such file or directory"

I am trying to use the Android NDK on Mountain Lion to build a library for Android, following this guide
http://masl.cis.gvsu.edu/2012/01/25/android-echoprint/
When it comes time to compile the library, I run:
cd <path to jni>
<ndk>/ndk-build
I get the following error:
Compile++ thumb : echoprint-jni <= AndroidCodegen.cpp
arm-linux-androideabi-g++: error trying to exec 'cc1plus': execvp: No such file or directory
make: *** [/Users/wingdom/Desktop/obj/local/armeabi/objs/echoprint-jni/AndroidCodegen.o] Error 1
I believe I have added everything I need to to my path variable:
export PATH=$PATH:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:Developer/android-sdk/tools:/Developer/android-sdk/platform-tools:/Developer/android-ndk:/Developer/android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin
What else do I need to do in order to get this to compile? I am using the r8b NDK currently, but have tried it with versions all the way back to 6.
EDIT:
I tried this solution: Error while building android ndk sample project
adding
export PATH=$PATH:/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2
to my path gets me this error:
cc1plus: error: unrecognized command line option "-mbionic"
cc1plus: error: unrecognized command line option "-mthumb"
cc1plus: error: unrecognized command line option "-mfpu=vfp"
/Users/wingdom/Desktop/jni/AndroidCodegen.cpp:1: error: bad value (armv5te) for -march= switch
/Users/wingdom/Desktop/jni/AndroidCodegen.cpp:1: error: bad value (xscale) for -mtune= switch
make: *** [/Users/wingdom/Desktop/obj/local/armeabi/objs/echoprint-jni/AndroidCodegen.o] Error 1
but adding
export CROSS_COMPILER=$PATH:/Developer/android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin
doesn't help, like it did in the link above.
I have experienced same error.
I was not able to execute even 'gcc, g++' command. So I have googled a lot to find solution, but nothing helped for me.
Then, I found that some filename in ndk is not correct, with tailing _ on some filename.. (In my case, in toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/arm-linux-androideabi/bin folder, there are gcc_, g++_, c++_ instead of gcc, g++, c++.)
I used The unarchiver to extract NDK archive, so I think there are something wrong with unarchiving procedure.
So I re-downloaded NDK and checked MD5 checksum, then extracted archive using Mac's default archive utility.
Now, the problem has solved.
Sounds like you have a bad download/unpack of the NDK. The cc1plus binary that it's looking for should be in $NDK_HOME/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/libexec/gcc/arm-linux-androideabi/4.4.3/. If it's not there, try re-downloading the SDK and/or unpacking it again.
If it is there, be sure to build passing V=1 to ndk-build, and see if there are any odd -B options passed to the compiler. The -B option tells gcc where to find its "sub-programs" (of which cc1plus is one). Pretty sure there shouldn't be any on the command lines for r8, so if there are, something somewhere is passing bad flags. For example, on my system, a C++ NDK command line ends up looking something like this:
/opt/android-ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++ -MMD -MP -MF ./obj/local/armeabi-v7a/objs/sometarget/SomeCppFile.o.d -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-exceptions -fno-rtti -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -I/opt/android-ndk/sources/cxx-stl/stlport/stlport -I/opt/android-ndk/sources/cxx-stl//gabi++/include -DANDROID -Wall -Wa,--noexecstack -frtti -O2 -DNDEBUG -g -I/opt/android-ndk/platforms/android-8/arch-arm/usr/include -c jni/SomeCppFile.cpp -o ./obj/local/armeabi-v7a/objs/sometarget/SomeCppFile.o
Maybe you need to install the g++:
$sudo apt-get install g++
I have spent about a day to find root cause of this
arm-linux-androideabi-gcc: error trying to exec 'cc1': execvp: No such file...
and others issues.
The issues were that I unpacked NDK and SDK with 7z which removed executable permission for all binaries and Eclipse was not able to start cc1.
Once I unpacked tar files of SDK and NDK using tar, everything started working well.

Categories

Resources