Jer*_*ell 6 android gradle android-ndk gradle-experimental
我正在使用android gradle实验插件来构建一个带有一些本机代码的app模块.这个本机代码使用带有预先构建的.so文件的库,我通过android库模块将其捆绑到.aar文件中..aar文件构建正常,但如何将app模块中的本机代码模块链接到.aar模块中预先构建的.so文件?gradle实验文档没有提到这种情况.
另外,如果可能的话,我想在.aar文件中打包包含文件(尽管它们不应与最终应用程序打包在一起).
在/ prebuiltlib中:
build.gradle
-src/
--main/
---jniLibs/
----libfoo.so
这是gradle文件:
/prebuiltlib/build.gradle
apply plugin: "com.android.model.library"
model {
    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.3"
        defaultConfig {
            minSdkVersion.apiLevel = 21
            targetSdkVersion.apiLevel = 21
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file("proguard-rules.pro"))
            }
        }
    }
}
dependencies {
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:25.3.1"
}
这是/app/build.gradle,注意??? 在哪里我不知道该放什么:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.model.application'
model {
    repositories {
        libs(PrebuiltLibraries) {
            // ??? is this right, and does this go into app/build.gradle or mylib/build.gradle?
            foo {
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file('???/libfoo.so')
                }
            }
        }
    }
    android {
        compileSdkVersion = 25
        buildToolsVersion = '25.0.3'
        defaultConfig {
            applicationId = 'com.jeremy.stackoverflow.sample'
            minSdkVersion.apiLevel = 21
            targetSdkVersion.apiLevel = 21
            versionCode = 1
            versionName = '1.0'
        }
        ndk {
            platformVersion = 21
            moduleName = 'native-activity'
            toolchain = 'gcc'
            toolchainVersion = '4.9'
            stl = 'gnustl_shared'
            abiFilters.add('armeabi-v7a')
            ldLibs.addAll(['log',
                           'android',
                           'EGL',
                           'GLESv2'
            ])
            // ??? How do I add include paths from the .aar module?
            cppFlags.add('-I' + file('???/include'))
            cppFlags.addAll(['-std=c++11', '-fexceptions'])
        }
        sources {
            main {
                jni {
                    dependencies {
                        // ??? Is this right?
                        library 'foo' linkage 'shared'
                    }
                }
                jniLibs {
                    source {
                        // ??? Do I need one of these for the libs in the .aar?
                        srcDir file('???/jniLibs')
                    }
                    dependencies {
                        // ??? Is this right?
                        library 'foo'
                    }
                }
            }
        }
        buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file('proguard-rules.pro'))
            }
        }
    }
}
dependencies {
    println rootProject.getName()
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile project(':prebuiltlib')
}
从 Android Gradle Plugin 4.0 开始,可以从 build.gradle 文件中链接的 AAR 导入 C/C++ 依赖项。Gradle 会自动将这些内容提供给本机构建系统,但您的构建系统必须配置为使用导入的库和标头。
在导入模块的应用程序的 build.gradle 上添加:
在 gradle 4.0 中:将以下内容添加到项目的 gradle.properties 文件中:
android.enablePrefab=true
在 gradle 4.1 中:将以下内容添加到模块的 build.gradle 文件的 android 块中:
buildFeatures {
  prefab true
}
然后添加对必须导入的模块的依赖关系:
dependencies {
    implementation files('libs/nativelib-release.aar')
}
在本例中,发布版本中的 lib aar 被放置在 app/libs 目录中。
在要导入的模块的 build.gradle 上添加:
buildFeatures {
    prefabPublishing = true
}
prefab {
    create("nativelib") {
      headers = "src/main/cpp/include"
    }
    // if you have other libs to expose...
    create("myotherlibrary") {
        headers = "src/main/cpp/myotherlibrary/include"
    } 
}
请注意,目前仅允许一个包含路径(必须放置包含公共 API 的 .h),并且此处引发了一个错误: https: //issuetracker.google.com/issues/168775349
,如果您的应用程序定义了 libapp.so 并且它使用 cURL,则您的 CMakeLists.txt 应包含以下内容:
add_library(app SHARED app.cpp)
# Add these two lines.
find_package(nativelib REQUIRED CONFIG)
target_link_libraries(app nativelib::nativelib)
app.cpp 现在能够#include“curl/curl.h”,libapp.so 在构建时将自动链接到 libcurl.so,并且 libcurl.so 将包含在 APK 中。
来源: https: //developer.android.com/studio/build/native-dependency
额外位:
可能需要使用共享 stl 构建 aar 模块,您可以在模块 gradle 文件的 android defaultConfig 上添加以下内容:
externalNativeBuild {
    cmake {
        cppFlags ""
        arguments "-DANDROID_STL=c++_shared"
    }
}
用于调试:
模块库将通过变量暴露给应用程序的cmake CMAKE_FIND_ROOT_PATH。使用message(${CMAKE_FIND_ROOT_PATH})来显示该路径,并且内部将有一个名为nativelibConfig.cmake(或另一个库/模块名称)的文件。该文件包含以下内容:
if(NOT TARGET nativelib::nativelib)
add_library(nativelib::nativelib SHARED IMPORTED)
set_target_properties(nativelib::nativelib PROPERTIES
    IMPORTED_LOCATION "/Users/bloom/.gradle/caches/transforms-3/44ca3477885179ff4cb5073527c9d262/transformed/nativelib-debug/prefab/modules/nativelib/libs/android.arm64-v8a/libnativelib.so"
    INTERFACE_INCLUDE_DIRECTORIES "/Users/bloom/.gradle/caches/transforms-3/44ca3477885179ff4cb5073527c9d262/transformed/nativelib-debug/prefab/modules/nativelib/include"
    INTERFACE_LINK_LIBRARIES ""
)
endif()
它以 :: 格式显示库名称(非常奇怪),以防很难猜测 CMakelists.txt 上使用的名称和导出的路径。
要刷新编辑器等,请尝试构建->刷新链接的 C++ 项目。
| 归档时间: | 
 | 
| 查看次数: | 448 次 | 
| 最近记录: |