Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Cómo vincular Gradle con tu biblioteca nativa

Para incluir tu proyecto de biblioteca nativa como una dependencia de compilación de Gradle, debes proporcionarle a Gradle la ruta de acceso al archivo de secuencia de comandos de CMake o ndk-build. Cuando compilas tu app, Gradle ejecuta CMake o ndk-build y empaqueta las bibliotecas compartidas con tu APK. Gradle también usa la secuencia de comandos de compilación a fin de determinar qué archivos se incluirán en tu proyecto de Android Studio, para que puedas acceder a ellos desde la ventana Project. Si no dispones de una secuencia de comandos de compilación para tus fuentes nativas, debes crear una secuencia de comandos de compilación de CMake para proceder.

Cada módulo del proyecto de Android puede vincularse a un solo archivo de secuencia de comandos de CMake o ndk-build. Por ejemplo, si deseas compilar y empaquetar resultados de varios proyectos de CMake, debes usar un archivo CMakeLists.txt como secuencia de comandos de compilación de CMake de nivel superior (que luego se vincula a Gradle) y agregar otros proyectos de CMake como dependencias de esa secuencia de comandos de compilación. Del mismo modo, si usas ndk-build, puedes incluir otros Makefiles en el archivo de secuencia de comandos Android.mk de nivel superior.

Una vez que vinculas Gradle con el proyecto nativo, Android Studio actualiza el panel Project para mostrar tus archivos de origen y bibliotecas nativas en el grupo cpp y tus secuencias de comandos de compilación externas en el grupo External Build Files.

Nota: Cuando realices cambios en la configuración de Gradle, asegúrate de aplicarlos haciendo clic en Sync Project , en la barra de herramientas. Además, cuando realices cambios en el archivo de secuencia de comandos de CMake o ndk-build después de haberlo vinculado con Gradle, debes sincronizar Android Studio con los cambios seleccionando Build > Refresh Linked C++ Projects en la barra de menú.

Puedes vincular Gradle con un proyecto externo de CMake o ndk-build usando la IU de Android Studio:

  1. Abre el panel Project del lado izquierdo de IDE y selecciona la vista de Android.
  2. Haz clic con el botón secundario en el módulo que desees vincular con tu biblioteca nativa (por ejemplo, el módulo de app) y selecciona Link C++ Project with Gradle en el menú. Verás un diálogo similar al que se muestra en la figura 4.
  3. En el menú desplegable, selecciona CMake o ndk-build.
    1. Si seleccionas CMake, usa el campo junto a Project Path para especificar el archivo de secuencia de comandos CMakeLists.txt de tu proyecto de CMake externo.
    2. Si seleccionas ndk-build, usa el campo junto a Project Path para especificar el archivo de secuencia de comandos Android.mk de tu proyecto de ndk-build externo. Android Studio también incluye el archivo Application.mk, si se encuentra en el mismo directorio que tu archivo Android.mk.

    Figura 4: Vinculación de un proyecto externo de C ++ desde el cuadro de diálogo de Android Studio

  4. Haz clic en OK.

Cómo configurar Gradle de forma manual

Para establecer de forma manual que Gradle se vincule con tu biblioteca nativa, debes agregar el bloque externalNativeBuild al archivo de nivel de módulo build.gradle y configurarlo con el bloque cmake o ndkBuild:

    android {
      ...
      defaultConfig {...}
      buildTypes {...}

      // Encapsulates your external native build configurations.
      externalNativeBuild {

        // Encapsulates your CMake build configurations.
        cmake {

          // Provides a relative path to your CMake build script.
          path "CMakeLists.txt"
        }
      }
    }
    

Nota: Si deseas vincular Gradle con un proyecto ndk-build existente, usa el bloque ndkBuild en lugar de cmake y proporciona una ruta de acceso relativa al archivo Android.mk. Gradle también incluye el archivo Application.mk, si se encuentra en el mismo directorio que el archivo Android.mk.

Cómo especificar configuraciones opcionales

Puedes especificar argumentos y marcas opcionales para CMake o ndk-build configurando otro bloque externalNativeBuild en el bloque defaultConfig de tu archivo build.gradle de nivel de módulo. Como en el caso de otras propiedades del bloque defaultConfig, puedes anular estas propiedades para cada variante de producto de tu configuración de compilación.

Por ejemplo, si tu proyecto de CMake o ndk-build define varias bibliotecas nativas y ejecutables, puedes usar la propiedad targets para compilar y empaquetar solo un subconjunto de esos artefactos para una variante de producto específica. En la siguiente muestra de código, se describen algunas de las propiedades que puedes configurar:

    android {
      ...
      defaultConfig {
        ...
        // This block is different from the one you use to link Gradle
        // to your CMake or ndk-build script.
        externalNativeBuild {

          // For ndk-build, instead use the ndkBuild block.
          cmake {

            // Passes optional arguments to CMake.
            arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"

            // Sets a flag to enable format macro constants for the C compiler.
            cFlags "-D__STDC_FORMAT_MACROS"

            // Sets optional flags for the C++ compiler.
            cppFlags "-fexceptions", "-frtti"
          }
        }
      }

      buildTypes {...}

      productFlavors {
        ...
        demo {
          ...
          externalNativeBuild {
            cmake {
              ...
              // Specifies which native libraries or executables to build and package
              // for this product flavor. The following tells Gradle to build only the
              // "native-lib-demo" and "my-executible-demo" outputs from the linked
              // CMake project. If you don't configure this property, Gradle builds all
              // executables and shared object libraries that you define in your CMake
              // (or ndk-build) project. However, by default, Gradle packages only the
              // shared libraries in your APK.
              targets "native-lib-demo",
                      // You need to specify this executable and its sources in your CMakeLists.txt
                      // using the add_executable() command. However, building executables from your
                      // native sources is optional, and building native libraries to package into
                      // your APK satisfies most project requirements.
                      "my-executible-demo"
            }
          }
        }

        paid {
          ...
          externalNativeBuild {
            cmake {
              ...
              targets "native-lib-paid",
                      "my-executible-paid"
            }
          }
        }
      }

      // Use this block to link Gradle to your CMake or ndk-build script.
      externalNativeBuild {
        cmake {...}
        // or ndkBuild {...}
      }
    }
    

Si quieres obtener más información sobre la configuración de variantes de productos y de compilación, consulta la sección Cómo configurar variantes de compilación. Para obtener una lista de variables que puedes configurar para CMake con la propiedad arguments, consulta Cómo usar variables de CMake.

Cómo incluir bibliotecas nativas ya compiladas

Si deseas que Gradle empaquete las bibliotecas nativas ya compiladas con tu APK, modifica la configuración predeterminada del conjunto de orígenes de modo que se incluya el directorio de tus archivos .so compilados previamente, como se muestra a continuación. Ten en cuenta que este paso no es necesario para incluir artefactos de secuencias de comandos de compilación de CMake que vinculas a Gradle.

    android {
        ...
        sourceSets {
            main {
                jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/'
            }
        }
    }
    

Cómo especificar ABI

De forma predeterminada, Gradle compila tu biblioteca nativa en archivos .so separados para las interfaces binarias de la aplicación (ABI) que admite el NDK, y los empaqueta en el APK. Si deseas que Gradle compile y empaquete solo ciertas configuraciones de ABI de tus bibliotecas nativas, puedes indicarlo con la marca ndk.abiFilters en el archivo build.gradle de nivel de módulo, como se muestra a continuación:

    android {
      ...
      defaultConfig {
        ...
        externalNativeBuild {
          cmake {...}
          // or ndkBuild {...}
        }

        // Similar to other properties in the defaultConfig block,
        // you can configure the ndk block for each product flavor
        // in your build configuration.
        ndk {
          // Specifies the ABI configurations of your native
          // libraries Gradle should build and package with your APK.
          abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
                       'arm64-v8a'
        }
      }
      buildTypes {...}
      externalNativeBuild {...}
    }
    

En la mayoría de los casos, solo es necesario especificar abiFilters en el bloque ndk, como se muestra más arriba, ya que le indica a Gradle que debe compilar y empaquetar esas versiones de tus bibliotecas nativas. Sin embargo, si deseas controlar lo que Gradle debe compilar, independientemente de lo que quieres que empaquete en tu APK, configura otra marca abiFilters en el bloque defaultConfig.externalNativeBuild.cmake (o el bloque defaultConfig.externalNativeBuild.ndkBuild). Gradle compila esas configuraciones de ABI, pero solo empaqueta las que especificas en el bloque defaultConfig.ndk.

Para reducir aún más el tamaño del APK, puedes configurar varios APK basados en ABI. De esta forma, en lugar de crear un APK grande con todas las versiones de las bibliotecas nativas, Gradle crea un APK separado para cada ABI que deseas admitir y solo empaqueta los archivos que necesita cada ABI. Si configuras varios APK por ABI sin especificar la marca abiFilters, como se indica en la muestra de código anterior, Gradle compila todas las versiones de ABI compatibles de tus bibliotecas nativas, pero solo empaqueta las que especificas en la configuración de varios APK. Para evitar compilar versiones de bibliotecas nativas que no deseas, proporciona la misma lista de ABI para la marca abiFilters y tu configuración de varios APK por ABI.