1. 程式人生 > >AndroidStudio編譯Taglib原始碼中遇到的一些問題

AndroidStudio編譯Taglib原始碼中遇到的一些問題

系統Ubuntu18.04

AndroidStudio版本3.2.1

NDK:android-ndk-r10e,未使用最新的ndk,貌似最新的有些問題

Taglib是最新的taglib-1.11.1

第一次在AndroidStuido中編譯第三方庫,遇到的主要問題如下:

1.只是從Build選單執行Make Project或者Rebuild Project,報錯資訊如下:

Process 'command '/home/gym/bin/android-ndk-r10e/ndk-build'' finished with non-zero exit value 2
並沒有詳細錯誤資訊,從網上搜索大部分說是NDK版本太新了,需要使用舊的r10e版本,所以就下載了r10e版本;但還是會報這個錯誤。

2.後來,由於沒有生成Release版本的aar檔案,在網上看到可以在AndroidStudio右側的Gradle視窗的工程的Module下的Task/build目錄下執行assembleDebug/assembleRelease單獨編譯debug或release版本,assemble則是編譯debug和release版本。

如圖:

雙擊後自動執行編譯,這時候報錯資訊就詳細了,會具體到程式碼行:

jni/taglib/toolkit/tfile.cpp: In member function 'TagLib::PropertyMap TagLib::File::properties() const':
jni/taglib/toolkit/tfile.cpp:115:42: error: 'dynamic_cast' not permitted with -fno-rtti


   if(dynamic_cast<const APE::File* >(this))
                                          ^

具體上面的報錯資訊,解決辦法是:

在taglib的Adnroid.mk中的LOCAL_CPPFLAGS中增加-frtti,則可以編譯過了。

其中ndkBuild配置如下,兩者都可以成功編譯出so和aar檔案:

// This build task also valid
/*task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
    println('executing ndkBuild')
    def ndkBuildingDir = android.ndkDirectory
    ndkBuildingDir = "$ndkBuildingDir/ndk-build"
    commandLine ndkBuildingDir, '-j8', '-C', file('src/main').absolutePath
}*/

task ndkBuild(type: Exec) {
    commandLine 'ndk-build', '-C', file('src/main/jni').absolutePath
}

3.生的aar檔案沒有包含so檔案,導致在執行時提示找不到類

在audioinfo的build.gradle檔案中增加以下配置資訊,必須按照以下方式配置,不能按照註釋掉的方法配置。

sourceSets {
    main {
        jni.srcDirs = [] // 遮蔽gradle的jni生成過程
        //jni.srcDirs = ['src/main/jni'] //disable automatic ndk-build
        //jniLibs.srcDirs = ['libs'] // 指定引用so庫的目錄
        jniLibs.srcDirs = ['src/main/libs']  //指定引用so庫的目錄
    }
}

這樣配置後,就可以正常生成可用的so和aar檔案了。

4.Project中jni的目錄結構如下圖,taglib位於audioinfo module的src/main/jni目錄下,jni與java是同級的。

5.還可以在build.gradle中配置自動拷貝aar到app模組

gradle程式碼如下:

// Copy aar files from "audioinfo/build/outputs/aar" to "app/libs" folder
task copyAAR(type: Copy) {
    from 'build/outputs/aar'
    into '../app/libs'
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(copyAAR)
}

點選右側Gradle視窗的audioinfo/Tasks/other/copyAAR就自動把aar檔案拷貝到app目錄的libs目錄下:

拷貝結果:

在編譯階段的最後,還報過 FileRef::FileTypeResolver沒有解構函式的錯誤,增加以下建構函式和解構函式後編譯通過;但現在去掉增加的程式碼還是可以編譯過,這就很奇怪了。

    class TAGLIB_EXPORT FileTypeResolver
    {
      TAGLIB_IGNORE_MISSING_DESTRUCTOR
    public:
        // AMEYUME Add {@
        /*!
         * Creates a null FileTypeResolver.
         */
        //FileTypeResolver();

        /*!
         * Destroys this FileTypeResolver instance.
         */
        //virtual ~FileTypeResolver();
        // AMEYUME @}