Build boost for android with hunter - android

my troubles are the following.
A boost is integrated to my CMake with hunter:
include(cmake/HunterGate.cmake)
cmake_host_system_information(RESULT HUNTER_JOBS_NUMBER QUERY NUMBER_OF_LOGICAL_CORES)
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz"
SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd"
LOCAL
)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(BOOST_COMPONENTS)
list(APPEND BOOST_COMPONENTS system program_options)
hunter_add_package(Boost COMPONENTS ${BOOST_COMPONENTS})
find_package(Boost CONFIG COMPONENTS ${BOOST_COMPONENTS})
I build my project on linux Ubuntu for android with the following parameters:
config-android : _android
cd $< && cmake \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_TOOLCHAIN_FILE=$(NDK)/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$(ABI) \
-DANDROID_PLATFORM=android-$(MINSDKVERSION) \
-DANDROID_TARGET=$(TARGET) \
..
If I assign $ABI=armeabi-v7a, everything is all right. As I see, the boost is built on the following configuration:
[ 75%] Performing build step for 'Boost-system'
Performing configuration checks
- default address-model : 32-bit [1]
- default architecture : arm [1]
Building the Boost C++ Libraries.
However, if assign any other interface, for example, $ABI=x86_64, I have an error:
ld: error: /home/vitali/.hunter/_Base/a3d7f43/0db57b3/73320e1/Install/lib/libboost_program_options-mt-a64.a(cmdline.o) is incompatible with elf_x86_64
I suspect the reason for that error is the hunter builds boost not for the assigned ABI. As I see, it shows the same configuration as it was for arm ABI:
[ 75%] Performing build step for 'Boost-system'
Performing configuration checks
- default address-model : 32-bit [1]
- default architecture : arm [1]
Building the Boost C++ Libraries.
My question is the following: how to make hunter to build boost for the appropriate ABI ?
Thanks!

I've met the same problem with Hunter. It's easy to solve. Create (or add to) file cmake/Hunter/config.cmake the following lines to pass additional cmake/ndk-toolchain parameters to boost build:
if(ANDROID)
hunter_config(
Boost
VERSION ${HUNTER_Boost_VERSION}
CMAKE_ARGS
CMAKE_ANDROID_ARCH_ABI=${ANDROID_ABI}
ANDROID_ABI=${ANDROID_ABI}
ANDROID_PLATFORM=${ANDROID_PLATFORM}
)
else()
hunter_config(
Boost
VERSION ${HUNTER_Boost_VERSION}
)
endif()
Generally, you have to pass ANDROID_ABI and ANDROID_PLATFORM. Hunter runs new cmake process to build boost, ndk toolchain is passed, abi & platform are not. So, toolchain does not know how to build boost and builds it by default. As result, there are many link errors.

Related

Error when attempting to configure cmake for cross compilation to android

I have been trying to build a c++ library for android using cmake cross compilation.
The library itself is a trivial test I made purely for testing the androind build process.
I have been using the cmake gui (v 3.25.0) on a windows machine.
I use a visual studio 2019 generator in cmake and specify a toolchain file.
Unfortunately, I seem to get the same error whatever I try. I tried searching for similar problems and trouble shooting, but have so far been unable to make any progress. If anyone with more experience could lend a hand, I would be very grateful!
I have attempted setting many different variables in the toolchain file in an attempt to resolve the problem, but the basic version of what I am working with is:
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
set(CMAKE_ANDROID_NDK C:/Microsoft/AndroidNDK64/android-ndk-r16b/)
The error I run into happens whenever I configure cmake. The outut I get from cmake looks something like this:
Android: Targeting API '27' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
Android: Selected Clang toolchain 'arm-linux-androideabi-clang' with GCC toolchain 'arm-linux-androideabi-4.9'
The C compiler identification is Clang 5.0.300080
The CXX compiler identification is Clang 5.0.300080
Detecting C compiler ABI info
Detecting C compiler ABI info - failed
Check for working C compiler: C:/Microsoft/AndroidNDK64/android-ndk-r16b//toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe
Check for working C compiler: C:/Microsoft/AndroidNDK64/android-ndk-r16b//toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe - broken
CMake Error at C:/Program Files/CMake/share/cmake-3.25/Modules/CMakeTestCCompiler.cmake:70 (message):
The C compiler
"C:/Microsoft/AndroidNDK64/android-ndk-r16b//toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Users/username/Documents/Code Projects/Android Test/build/CMakeFiles/CMakeScratch/TryCompile-zqgcqm
Run Build Command(s):C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe cmTC_b0f1d.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=16.0 /v:m && Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
ANDROID_HOME=C:\\Microsoft\AndroidSDK\25
ANT_HOME=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Apps\apache-ant-1.9.3
JAVA_HOME=C:\Program Files\Eclipse Foundation\jdk-8.0.302.8-hotspot
NDK_ROOT=C:\\Microsoft\AndroidNDK64\android-ndk-r16b
testCCompiler.c
clang.exe : warning : argument unused during compilation: '-mthumb' [-Wunused-command-line-argument] [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
clang.exe : warning : argument unused during compilation: '-mfpu=vfpv3-d16' [-Wunused-command-line-argument] [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
clang.exe : warning : argument unused during compilation: '-mfloat-abi=softfp' [-Wunused-command-line-argument] [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
CLANGCOMPILE : error : unknown target CPU 'armv7-a' [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:4 (project)
Configuring incomplete, errors occurred!
I initially used used the NDK version found in the android tools for visual studio found at: "C:/Microsoft/AndroidNDK64/android-ndk-r16b/"
as an NDK version.
I have also tried directly downloading the latest version of the NDK and pointing to that with CMAKE_ANDROID_NDK in the toolchain file, though this did not seem to make any change.
I have tried directly using the toolchain.cmake files found at "NDK/build/cmake/android.toolchain.cmake"
for both the NDK versions described above. This too gave the same error.
Any ideas what could be causing this or how to fix?
Ok, so I was misunderstanding a few things about cross-compiling to android.
First, if I want to be able to use the static library (e.g in android studio), I will need to generate and build a solution for more than one android ABI.
The ABI's to build for are: armeabi-v7a, arm64-v8a, x86_64, x86. I then need to check for each android ABI in the CMakeLists.txt file of Android studio (e.g. elseif(ANDROID_ABI STREQUAL arm64-v8a)) and swap out the location of the library to import to the build folder of that particular ABI.
As far as I am aware, it is unfortunately not possible to generate for all these ABI's as seperate platforms within the same visual studio solution. Given that, cmake must be run 4 seperate times to different build folders, each time targeting a different ABI and generator platform. To save the hassle of doing this manually, creating a batch (.bat) script to automate the process seems the best way to go. This will involve using cmake from the command line instead of the GUI version. The script can also be made to build the generated projects to save opening each one in visual studio and building there.
The batch script I have made to generate and build cross-compilation projects for android is as follows:
#echo OFF
set BUILD_DIR=build
set ANDROID_NDK=C:\Microsoft\AndroidNDK\android-ndk-r23c
set GENERATOR="Visual Studio 17 2022"
set CMAKE_GENERATOR=-G %GENERATOR%
set CMAKE_TOOLCHAIN_FILE=-DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%\build\cmake\android.toolchain.cmake
set CMAKE_SYSTEM_NAME=-DCMAKE_SYSTEM_NAME=Android
set EXTRA_CMAKE_ARGS=-DBUILD_SHARED_LIBS=true -DANDROID_TOOLCHAIN=clang -DANDROID_STL=c++_static
CALL :build_android armeabi-v7a ARM 16
CALL :build_android arm64-v8a ARM64 21
CALL :build_android x86_64 x64 21
CALL :build_android x86 x86 16
EXIT /B %ERRORLEVEL%
:build_android
set ABI_VERSION=%~1
set GENERATOR_PLATFORM=%~2
set MINIMUM_API_LEVEL=%~3
set CMAKE_ANDROID_ARCH_ABI=-DANDROID_ABI=%ABI_VERSION%
set ABI_BUILD_DIR=%BUILD_DIR%\%ABI_VERSION%
set CMAKE_GENERATOR_PLATFORM=-A %GENERATOR_PLATFORM%
set CMAKE_BUILD_DIR=-B %ABI_BUILD_DIR%
set CMAKE_MIN_API=-DANDROID_PLATFORM=android-%MINIMUM_API_LEVEL%
set CMAKE_ARGS=%CMAKE_BUILD_DIR% %CMAKE_ANDROID_ARCH_ABI% %CMAKE_GENERATOR% %CMAKE_GENERATOR_PLATFORM% %CMAKE_SYSTEM_NAME% %CMAKE_TOOLCHAIN_FILE% %CMAKE_MIN_API%
echo building for android ABI: %ABI_VERSION%
echo cmake arguments = %CMAKE_ARGS%
echo:
cmake %CMAKE_ARGS% %EXTRA_CMAKE_ARGS%
echo:
cmake --build %ABI_BUILD_DIR% --target ALL_BUILD
echo:
echo:
EXIT /B 0
This worked for my simple test library, but I guess depending on the project the arguments to the cmake commands may need to be tweaked.

Build CMake library without Android-Studio (by command-line or GUI)

It seems, Android-Studio sets specific CMake options,
And I can not build with command-line (outside of Android-Studio) no matter what I tried!!
Is there any way to build an Android project's CMake library without even opening Android-Studio?
Note: I already found solution and will share answer to this shortly.
Yes there were some options and/or variables that need to be set for CMake command-line build to work (without even opening Android-Studio).
1. Firstly, create the my-toolchain.cmake file (beside your project, maybe in config dir), with content below:
#
# Allows compiling outside of Android-Studio.
#
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_TOOLCHAIN_DIRECTORY "$ENV{ANDROID_HOME}/ndk-bundle/build/cmake")
if(NOT CMAKE_TOOLCHAIN_FILE)
if(NOT ANDROID_ABI)
# Default to 32 Bit ARMv7 CPU.
set(ANDROID_ABI "armeabi-v7a")
endif()
if(NOT ANDROID_PLATFORM)
set(ANDROID_PLATFORM "android-15")
endif()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_DIRECTORY}/android.toolchain.cmake")
endif()
if(WIN32 AND NOT CMAKE_MAKE_PROGRAM)
set(CMAKE_MAKE_PROGRAM "$ENV{ANDROID_HOME}/ndk-bundle/prebuilt/windows/bin/make.exe" CACHE INTERNAL "" FORCE)
endif()
2. Secondly, Add the file created in last step into your project, for example:
cmake_minimum_required(VERSION 3.2)
# Detect toolchain.
include(config/my-toolchain.cmake)
project(MyProject C CXX)
# ... and so on ...
3. Finally, in console cd where your CMakeLists.txt file is, and build with commands like:
cmake -H. -B .build -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DANDROID_PLATFORM=android-14 -D ANDROID_ABI=armeabi-v7a
cd .build
"%ANDROID_HOME%\ndk-bundle\prebuilt\windows\bin\make.exe" install INSTALL_ROOT="%CD%\.build"
Note that last command of Step-3 changes based on your operating-system, but above should work for Windows if you have ANDROID_HOME environment-variable set to Android-SDK root directory (which of course, needs NDK extracted in ndk-bundle sub-dir).
All done!
Just repeat Step-3 for each CPU architecture, i.e. change ANDROID_ABI to one of possible options:
armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64
Although, mips and mips64 are deprecated by now (and Android NDK r16b was last version supporting them).

How to use cmake from command line to make an executable for rooted Android device?

I want to run a simple executable that should print "Hello Cmake" when I will execute it from adb shell. For this, I have created a simple c++ file with CMakeLists.txt file as following:
hello.cpp
#include <iostream>
int main(int, char**) {
std::cout << "Hello, CMake!\n";
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
hello_cmake
# Sets the library as a static library.
STATIC
# Provides a relative path to your source file(s).
hello.cpp )
I have tried to run following command in terminal:
cmake D:/Development/CMAKE/HelloCmake/ -G Ninja \
-DANDROID_TOOLCHAIN_NAME=aarch64-linux-android29-clang++ \
-DANDROID_PLATFORM=29 \
-DCMAKE_CACHEFILE_DIR=D:/Development/CMAKE/HelloCmake/build \
-DCMAKE_MAKE_PROGRAM=D:/Sdk/cmake/3.10.2.4988404/bin/ninja.exe \
-DCMAKE_C_COMPILER=D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang \
-DCMAKE_CXX_COMPILER=D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang++
This has the following result:
D:\Development\CMAKE\HelloCmake>cmake D:/Development/CMAKE/HelloCmake/ -G Ninja -DANDROID_TOOLCHAIN_NAME=aarch64-linux-android29-clang++ -DANDROID_PLATFORM=29 -DCMAKE_CACHEFILE_DIR=D:/Development/CMAKE/HelloCmake/build -DCMAKE_MAKE_PROGRAM=D:/Sdk/cmake/3.10.2.4988404/bin/ninja.exe -DCMAKE_C_COMPILER=D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang -DCMAKE_CXX_COMPILER=D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang++
-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- Check for working C compiler: D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang
-- Check for working C compiler: D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang -- broken
CMake Error at D:/Sdk/cmake/3.10.2.4988404/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
The C compiler
"D:/Sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android29-clang"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: D:/Development/CMAKE/HelloCmake/CMakeFiles/CMakeTmp
Run Build Command:"D:/Sdk/cmake/3.10.2.4988404/bin/ninja.exe" "cmTC_e4775"
ninja: fatal: CreateProcess: %1 is not a valid Win32 application.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt
-- Configuring incomplete, errors occurred!
See also "D:/Development/CMAKE/HelloCmake/CMakeFiles/CMakeOutput.log".
See also "D:/Development/CMAKE/HelloCmake/CMakeFiles/CMakeError.log".
D:\Development\CMAKE\HelloCmake>
Please help me to configure it correctly.
Update 1
With Michael guidance, I have found the build_command.txt file in Android Studio and it has the following contents for simple "Hello World" application:
Executable : D:\Sdk\cmake\3.10.2.4988404\bin\cmake.exe
arguments :
-HD:\Development\Android\HelloCPP\app\src\main\cpp
-BD:\Development\Android\HelloCPP\app\.cxx\cmake\debug\arm64-v8a
-DANDROID_ABI=arm64-v8a
-DANDROID_PLATFORM=android-26
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=D:\Development\Android\HelloCPP\app\build\intermediates\cmake\debug\obj\arm64-v8a
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=D:\Sdk\ndk\20.1.5948944
-DCMAKE_CXX_FLAGS=-std=c++14
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a
-DCMAKE_SYSTEM_VERSION=26
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_ANDROID_NDK=D:\Sdk\ndk\20.1.5948944
-DCMAKE_TOOLCHAIN_FILE=D:\Sdk\ndk\20.1.5948944\build\cmake\android.toolchain.cmake
-G Ninja
-DCMAKE_MAKE_PROGRAM=D:\Sdk\cmake\3.10.2.4988404\bin\ninja.exe
jvmArgs :
I have run the following command for my application:
D:\Sdk\cmake\3.10.2.4988404\bin\cmake.exe
-HD:\Development\CMAKE\HelloCmake\
-BD:\Development\CMAKE\HelloCmake\arm64-v8a
-DANDROID_ABI=arm64-v8a
-DANDROID_PLATFORM=android-29
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=D:\Development\CMAKE\HelloCmake\build
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=D:\Sdk\ndk\20.1.5948944
-DCMAKE_CXX_FLAGS=-std=c++14
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a
-DCMAKE_SYSTEM_VERSION=26
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_ANDROID_NDK=D:\Sdk\ndk\20.1.5948944
-DCMAKE_TOOLCHAIN_FILE=D:\Sdk\ndk\20.1.5948944\build\cmake\android.toolchain.cmake
-G Ninja
-DCMAKE_MAKE_PROGRAM=D:\Sdk\cmake\3.10.2.4988404\bin\ninja.exe
and I get the following output:
D:\Development\CMAKE\HelloCmake>D:\Sdk\cmake\3.10.2.4988404\bin\cmake.exe -HD:\Development\CMAKE\HelloCmake\ -BD:\Development\CMAKE\HelloCmake\arm64-v8a -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-29 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=D:\Development\CMAKE\HelloCmake\build -DCMAKE_BUILD_TYPE=Debug -DANDROID_NDK=D:\Sdk\ndk\20.1.5948944 -DCMAKE_CXX_FLAGS=-std=c++14 -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a -DCMAKE_SYSTEM_VERSION=26 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_ANDROID_NDK=D:\Sdk\ndk\20.1.5948944 -DCMAKE_TOOLCHAIN_FILE=D:\Sdk\ndk\20.1.5948944\build\cmake\android.toolchain.cmake -G Ninja -DCMAKE_MAKE_PROGRAM=D:\Sdk\cmake\3.10.2.4988404\bin\ninja.exe
-- Check for working C compiler: D:/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe
-- Check for working C compiler: D:/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: D:/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe
-- Check for working CXX compiler: D:/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Development/CMAKE/HelloCmake/arm64-v8a
D:\Development\CMAKE\HelloCmake>
Build files are written to arm64-v8a but I didn't find any ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), stripped object that should be able to run on my android device.
I have found only the following files:
$ find . | xargs file | grep ELF
./CMakeFiles/3.10.2/CMakeDetermineCompilerABI_C.bin: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=7cb1fddcd4776716628feaf37d471c1ea4a55314, with debug_info, not stripped
./CMakeFiles/3.10.2/CMakeDetermineCompilerABI_CXX.bin: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=1f498297f62e5a52751312894e88a9abef0412d5, with debug_info, not stripped
./CMakeFiles/feature_tests.bin: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=a56baeb98e3f077c3cc0a512b0535089a717929c, with debug_info, not stripped
Any suggestion?
Update 2
I have run D:\Sdk\cmake\3.10.2.4988404\bin\ninja.exe -C arm64-v8a command to make the target static library but I get libhello_cmake.a which is current ar archive.
I think to make an executable the CMakeLists.txt add_library line should be replaced with something else?
There are a couple of problems:
Static libraries are not meant to be run directly. If you want to build an executable that you can run, you should use add_executable instead of add_library.
When you invoke cmake you should set the CMAKE_TOOLCHAIN_FILE option to specify the toolchain file to use, and possibly other options as well. To get an idea of what Android Studio / Gradle uses, you can use Android Studio's project wizard to create an Android project with C++ support and take a look at the cmake_build_command.txt file that gets generated when you build that project.
After running cmake you also need to run ninja. The command would be something like ninja -C <directory containing build files generated by cmake>.

Checking preprocessor directives with Android Studio Gradle Build, NDK and CMake

I'm passing in preprocessor directives via CMakeLists.txt for the build of a native android library using android NDK.
add_definitions(-DMY_DIRECTIVE=1)
It would be great to double check that those preprocessor directives are actually finding their way into the calls to the compiler (llvm ?)
But the gradle build output doesn't seem to include the calls to the compiler, I just get:
Building C object CMakeFiles/my_project.dir/home/me/projects/my_proj/src/my_native.c.o
Is there a means to make the gradle output more verbose such that I can see the actual compiler calls and check those preprocessor directives are present?
The answer is to understand that Gradle utilises CMake to build the android NDK component (shared library) of an android project, and CMake utilises Ninja as a build system to handle the calls to the compiler. The compiler used by android NDK now defaults to LLVM->Clang.
So in order to actually see the Clang calls you have to find the build.ninja files for each target of your android project.
In my case I am only building for an armeabi-v7a target architecture. Therefore the relevant build.ninja files are found in:
/home/me/projects/my_proj/app/.externalNativeBuild/cmake/debug/armeabi-v7a
/home/me/projects/my_proj/app/.externalNativeBuild/cmake/release/armeabi-v7a
cd to either directory and run:
ninja -v
i.e. the -v option is the key to see all the calls to the clang compiler that the native build (android NDK) part of your android project generates.
Note if you have installed CMake via the android package manager, you may find that ninja is not installed in a location that is on your PATH. For me the ninja binary is located as follows:
~/Android/Sdk/cmake/3.6.3155560/bin/ninja
(same directory as cmake binary)
Therefore for me to see all the clang compiler calls for my android project's debug armeabi-v7a build I have to run:
cd /home/me/projects/my_proj/app/.externalNativeBuild/cmake/debug/armeabi-v7a
~/Android/Sdk/cmake/3.6.3155560/bin/ninja -v
Note if ninja tells you ninja: no work to do.
Then run:
~/Android/Sdk/cmake/3.6.3155560/bin/ninja clean
Relevant ninja documentation is -> https://ninja-build.org/manual.html#_extra_tools

How to configure gcc to compile for android?

I've read in the gcc documentation that it supports building android binaries with the -mandroid and -mbionic switches. First I tried it with the native gcc built from svn. Result:
dancsi#dancsi-VirtualBox:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.7.0/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../source/configure --enable-threads --disable-nls
Thread model: posix
gcc version 4.7.0 20110611 (experimental) (GCC)
dancsi#dancsi-VirtualBox:~$ g++ test.cpp -mandroid -o test.out
dancsi#dancsi-VirtualBox:~$ file test.out
test.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
Basically, it failed. Next, I tried to compile the same gcc sources with target=arm-linux-androideabi, (without defining sysroot,...), and it passed the configuration, but failed to build saying pthread.h is not found:
In file included from ../.././gcc/gthr-default.h:1:0,
from ../../../combined/libgcc/../gcc/gthr.h:160,
from ../../../combined/libgcc/../gcc/unwind-dw2.c:37:
../../../combined/libgcc/../gcc/gthr-posix.h:41:21: fatal error: pthread.h: No such file or directory
compilation terminated.
So, does anybody have the instructions for how to use gcc to build android binaries (I don't want to use code sourcery or android-ndk)?
EDIT:
my configure options
configure --target=arm-linux-android --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-libssp --disable-libgomp --disable-nls --enable-languages=c,c++,java
I had exactly the same problem as described by dancsi while trying to compile my own cross compilation tool chains for Android (I wanted to build a 32 bit variant of them so I don't need to buy a 64 bit PC or do my android stuff in a VM).
I am using the tool chain sources from the official AOSP tool chain repo:
repo init -u https://android.googlesource.com/toolchain/manifest
The solution is to use the following 2 extra configure options: --with-headers and --with-libs. I've got this solution by reading the following file: [android-toolchain-repo]/build/README:
The other way is to specify the headers and libraries with --with-headers and
--with-libs separately. If you configure your tree with a prefix. The headers
and libraries will be copied to the install directory specified by the prefix.
For the values of those 2 extra parameters I used [android-src-repo]/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib and [android-src-repo]/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/include. [android-src-repo] is referring to my repo checkout of the base AOSP sources (in my case I am on the android-4.2.2_r1 branch of it).
The end-result of the two configure statements I need are the following:
./configure --target=arm-eabi --host=i686-linux-gnu --build=i686-linux-gnu --disable-gold \
--with-gcc-version=4.6 --with-binutils-version=2.21 --with-gmp-version=4.2.4 --with-mpfr-version=2.4.1 \
--with-gdb-version=7.3.x --with-gold-version=2.21 --prefix=/tmp/toolchain --disable-multilib \
--with-libs=/home/boeboe/android-src/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib \
--with-headers=/home/boeboe/android-src/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/include \
--program-transform-name='s&^&arm-eabi-&' --with-arch=armv5te --disable-option-checking
./configure --target=arm-linux-androideabi --host=i686-linux-gnu --build=i686-linux-gnu --enable-gold \
--with-gcc-version=4.6 --with-binutils-version=2.21 --with-gmp-version=4.2.4 --with-mpfr-version=2.4.1 \
--with-gdb-version=7.3.x --with-gold-version=2.21 --prefix=/tmp/toolchain \
--with-libs=/home/boeboe/android-src/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/lib \
--with-headers=/home/boeboe/android-src/prebuilts/ndk/8/platforms/android-14/arch-arm/usr/include \
--program-transform-name='s&^&arm-linux-androideabi-&' --disable-option-checking
Notice the extra --disable-option-checking argument which was necessary for configure to accept all arguments!
This long list of arguments was constructed by checking the original configure arguments passed for the default 64 bit version of the 4.6 gcc toolchain. This can be checked in the SOURCES files available in [android-src-repo]/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6 and [android-src-repo]/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6.
In the same files, git tags can be found, so I also checkout those specific version in my [android-toolchain-repo]. For the extra modules needed by gcc, like gmp/mpfr/gdb..., I extracted the correct versions of the tar-balls available in [android-toolchain-repo]/gmp|mpfr|gdb. This was the easiest way I could find out, for my original configure statement to be able to pick up those modules.
The same technique as described above also allowed me to compile a 32 bit variant of the latest gcc 4.7 tool chain (currently being used on the MAIN branch of AOSP). The configure options were of course different in this case.
In file included from ../.././gcc/gthr-default.h:1:0,
from /mnt/network/source/gcc/libgcc/../gcc/gthr.h:160,
from /mnt/network/source/gcc/libgcc/../gcc/unwind-dw2.c:37:
/mnt/network/source/gcc/libgcc/../gcc/gthr-posix.h:41:21: fatal error: pthread.h: No such file or directory
compilation terminated.
make[2]: *** [unwind-dw2.o] Error 1
make[1]: *** [all-target-libgcc] Error 2
make: *** [all] Error 2
I'm getting the same error as you, but I'm not compiling for Android. I'm trying to build w64-mingw32 compiler.
AR=x86_64-w64-mingw32-ar RANLIB=x86_64-w64-mingw32-ranlib
../gcc-4.5.1/configure --prefix=/tools \
--with-local-prefix=/tools --enable-clocale=gnu \
--enable-shared --enable-threads=posix \
--enable-__cxa_atexit --enable-languages=c,c++ \
--disable-libstdcxx-pch --disable-multilib \
--disable-bootstrap --disable-libgomp \
--without-ppl --without-cloog --build=$MACHTYPE --host=$MACHTYPE --target=x86_64-w64-mingw32
My response is so you know its not just Android, the trouble is more general then just building for the ARM architecture.
I think its a c++ issue, cause I had/have no trouble with building a c compiler alone.

Categories

Resources