简体   繁体   中英

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:

  1. 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 .

  2. 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.

  3. After running cmake you also need to run ninja . The command would be something like ninja -C <directory containing build files generated by cmake> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM