Registro de aprendizaje de Cmake (nueve): use Cmake para compilar de forma cruzada la biblioteca .so de Android

I. Introducción

En la actualidad, es relativamente simple usar Android Studio para compilar .so para Android, pero a veces es necesario crear un proyecto de Android para Android Studio. Aquí, se registra que puede usar las herramientas de desarrollo Cmake y C ++ Clion sin Android Studio ( u otras herramientas de desarrollo. Estas herramientas de desarrollo no son las mismas que Android Studio, cualquier herramienta servirá).
De hecho, existe una forma más sencilla de compilar .so. Por ejemplo, puede usar cmake para compilar el proyecto c++ directamente en el entorno Linux, y la biblioteca .so aparece en este momento. Pero si el entorno de desarrollo es Mac o Windows, se generarán archivos dylib o exe, que no son los archivos que queremos, por lo que necesitamos usar tecnología de compilación cruzada.
Cmake proporciona dos formas de compilar archivos .so de Android: NDK o cadena de herramientas cruzada . Dado que estoy involucrado en el desarrollo de Android, hay dependencias de NDK preparadas y es necesario descargar la cadena de compilación cruzada. Así que uso NDK para compilar, pero probablemente sea posible modificarlo de acuerdo con esto. Más tarde, cuando haya tiempo, registraremos el método de compilación utilizando la cadena de herramientas cruzada.
El proyecto es desordenado y lo organizaré más adelante.
Sin embargo, no importa de qué manera use NDK o la cadena de herramientas cruzadas, debe asociarse con NDK y no habrá ningún problema de compilar .so sin NDK

2. Código relevante compilado usando NDK

La herramienta de desarrollo es CLion. Cabe señalar que tanto Android Studio como CLion usan el sistema de compilación ninja. Si usa otros sistemas de compilación, debe modificarlo, pero el código en el artículo ya tiene este código, y puede simplemente cambie la ruta en ese momento. La estructura general del proyecto es la siguiente
:
inserte la descripción de la imagen aquí
El código central es:
Cabe señalar que la parte establecida del código debe escribirse project(untitled VERSION 1.0)antes de la llamada a la función.

# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21) # API level
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_ANDROID_NDK /Users/c/Documents/sdk/android/ndk/25.1.8937393)
#set(CMAKE_TOOLCHAIN_FILE /Users/c/Documents/sdk/android/ndk/25.1.8937393/build/cmake/android.toolchain.cmake)
set(CMAKE_MAKE_PROGRAM /Users/c/Documents/sdk/android/cmake/3.22.1/bin/ninja)
#set(CMAKE_ANDROID_STL_TYPE gnustl_static) # 需要注意的是NDK不支持这个属性,可能是NDK版本原因,所以使用c++_shared,
set(CMAKE_ANDROID_STL_TYPE c++_shared)
set(CMAKE_EXPORT_COMPILE_COMMANDS NO)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

aux_source_directory(. SRC_LIST) #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
#ADD_EXECUTABLE(hello ${SRC_LIST}) #生成应用程序 hello (在windows下会自动生成hello.exe)

# 将相关文件添加到SqrtLibrary库 ,最终编译成共享库 .so
add_library(SqrtLibrary SHARED
        ${SRC_LIST}
        )

CMakeLists.txt

cmake_minimum_required(VERSION 3.23) # 这是Cmake版本

#======这一段来自Android开发者平台:https://developer.android.google.cn/ndk/guides/cmake?hl=zh-cn#using_prebuilt_libraries 
#-DCMAKE_FIND_ROOT_PATH=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/.cxx/cmake/universalDebug/prefab/armeabi-v7a/prefab
#-DCMAKE_BUILD_TYPE=Debug
#-DCMAKE_TOOLCHAIN_FILE=${HOME}/Android/Sdk/ndk/22.1.7171670/build/cmake/android.toolchain.cmake
#-DANDROID_ABI=armeabi-v7a
#-DANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
#-DANDROID_PLATFORM=android-23
#-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
#-DCMAKE_ANDROID_NDK=${HOME}/Android/Sdk/ndk/22.1.7171670
#-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
#-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
#-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${HOME}/Dev/github-projects/googlesamples/ndk-samples/hello-jni/app/build/intermediates/cmake/universalDebug/obj/armeabi-v7a
#-DCMAKE_MAKE_PROGRAM=${HOME}/Android/Sdk/cmake/3.10.2.4988404/bin/ninja
#-DCMAKE_SYSTEM_NAME=Android
#-DCMAKE_SYSTEM_VERSION=23

#====== end ======


# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21) # API level
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_ANDROID_NDK /Users/c/Documents/sdk/android/ndk/25.1.8937393)
set(CMAKE_MAKE_PROGRAM /Users/c/Documents/sdk/android/cmake/3.22.1/bin/ninja)
#set(CMAKE_ANDROID_STL_TYPE gnustl_static) # 需要注意的是NDK不支持这个属性,可能是NDK版本原因,所以使用c++_shared,
set(CMAKE_ANDROID_STL_TYPE c++_shared)
set(CMAKE_EXPORT_COMPILE_COMMANDS NO)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

project(untitled VERSION 1.0)

add_subdirectory(libscanner)
configure_file(square.h.in square.h)

# specify the C++ standard
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)


# 通过BUILD_SHARED_LIBS 创建共享库,后面值需要设置为ON,
# 这个属性写到这里,如果libscanner使用这个值的话有时候会报找不到的错误,如果经过反复Build后无法解决,将该属性写到相关的libscanner的CMakeLists.txt。但是这样的话最终rebuld后只会生成libscanner的.so。不过这也是预想的情况本身顶层目录也没有要求生成.so文件
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

add_executable(untitled square_main.cpp)

target_link_libraries(untitled PUBLIC scanner tutorial_compiler_flags)
target_include_directories(untitled PUBLIC
        "${PROJECT_BINARY_DIR}"
        "${PROJECT_SOURCE_DIR}/libscanner"
        )

# 打印日志
message("---PROJECT_BINARY_DIR--${PROJECT_BINARY_DIR}")
message("---PROJECT_SOURCE_DIR--${PROJECT_SOURCE_DIR}")
message("---libscanner头文件--${PROJECT_SOURCE_DIR}/libscanner")

libscanner/CMakeLists.txt

add_library(scanner scanner.cpp) # 默认编译成静态库
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(scanner
        INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
        )

#add_executable(MakeTable scanner.cpp)
#target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
aux_source_directory(. SRC_LIST) #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
#ADD_EXECUTABLE(hello ${SRC_LIST}) #生成应用程序 hello (在windows下会自动生成hello.exe)


# 将相关文件添加到SqrtLibrary库
add_library(SqrtLibrary SHARED
       ${SRC_LIST}
        )


# 文件应该去哪个路径下面查找
target_include_directories(SqrtLibrary PRIVATE
        ${CMAKE_CURRENT_BINARY_DIR}
        )

# 将tutorial_compiler_flags库链接到SqrtLibrary
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)

# 将SqrtLibrary库链接到libscanner
target_link_libraries(scanner PRIVATE SqrtLibrary)

# 将tutorial_compiler_flags库链接到libscanner
target_link_libraries(scanner PUBLIC tutorial_compiler_flags)


message("YM--->${BUILD_SHARED_LIBS}")

# state that SqrtLibrary need PIC when the default is shared libraries
set_target_properties(SqrtLibrary PROPERTIES
        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
        )

Después de volver a compilar después de escribir, puede encontrar la biblioteca .so generada en la carpeta de compilación

Cuarto, use la cadena de herramientas cruzadas para compilar

Si usa una cadena de herramientas cruzadas, la compilación solo necesita cambiar una línea de código en comparación con el método anterior. Debido a los cambios posteriores a la nueva versión de NDK r-19, será más fácil de usar. Simplemente especifique la propiedad CMAKE_TOOLCHAIN_FILE

#set(CMAKE_ANDROID_NDK /Users/c/Documents/sdk/android/ndk/25.1.8937393)
set(CMAKE_TOOLCHAIN_FILE /Users/c/Documents/sdk/android/ndk/25.1.8937393/build/cmake/android.toolchain.cmake)

4. Enlace de referencia

  1. Introducción a CMake en el sitio web oficial de Android
  2. Comprensión profunda del uso de CMake para compilar programas NDK
  3. cmake-herramientas(7)
  4. android/ndk-muestras
  5. CMAKE crea un entorno de compilación, empaquetado y lanzamiento de Android bajo Linux
  6. Bibliotecas comunes para la compilación cruzada de Android (cmake
  7. 10. Notas sobre la compilación cruzada de NDK
  8. cmake: add_library explicación detallada

Supongo que te gusta

Origin blog.csdn.net/Mr_Tony/article/details/130956210
Recomendado
Clasificación