Android移植lame庫(采用CMake)

貌似許多人都是從lame庫開始入門Android NDK開發(fā)的,在網(wǎng)上一搜一大堆詳細(xì)教程。本篇的亮點(diǎn)是采用Google推薦的CMake工具(不是ndk-builder)來移植lame項(xiàng)目。重點(diǎn)寫一下與ndk-builder的差異,而非教程。

1.CMake是什么?

這個(gè)是AndroidStudio 2.2以上的版本才可使用的,跟ndk-builder一樣是一款原生構(gòu)建工具。
與ndk-builder不同的是,ndk-builder需要用到mk文件,而CMake則使用CMakeLists文件。
具體可閱讀官方介紹 向您的項(xiàng)目中添加C代碼 以及 CMake(不讀的話,可能看不懂怎么移植哦)

在這里要說的就是,如果你使用的是AndroidStudio 2.2以上的版本,那么只要在創(chuàng)建項(xiàng)目時(shí)選擇“Include C++ Support”選項(xiàng),然后不停點(diǎn)擊下一步就可以創(chuàng)建一個(gè)使用CMake工具構(gòu)建C\C++代碼的項(xiàng)目。
當(dāng)然前提是,你在SDK Manager中安裝了CMake。

由于本文重點(diǎn)在移植lame項(xiàng)目,對CMake的介紹就不多說了。

2.將lame的代碼放入項(xiàng)目

現(xiàn)在假設(shè)你已經(jīng)創(chuàng)建了一個(gè)采用CMake的NDK項(xiàng)目,那么你可以找到兩個(gè)很重要的東西:cpp文件夾和CMakeLists.txt文件。前者是用來放C\C++源碼的,后者則是CMake的構(gòu)建腳本文件。
如果你看完了向您的項(xiàng)目中添加C代碼 文章,那你肯定知道CMakeLists.txt腳本中的大體內(nèi)容了。

好了,先下載lame吧。
http://lame.sourceforge.net/download.php
http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz
下載完之后解壓,然后找到libmp3lame文件夾,將里面的.c和.h文件全部復(fù)制到項(xiàng)目的cpp目錄中。
注意:libmp3lame文件夾內(nèi)還包含其他文件夾,不用管它。
然后,再找到include文件夾,將lame.h文件拷貝到cpp目錄中。(總共43個(gè)文件)

接下來需要將源文件加入到項(xiàng)目中,通過CMakeLists.txt腳本來控制
在CMakeLists中修改add_library 方法的最后一個(gè)參數(shù),通過AndroidStudio創(chuàng)建的ndk項(xiàng)目中會有一個(gè)native-lib.cpp文件,在此文件后將lame相關(guān)的所有.c文件添加進(jìn)來。這一步是指定源代碼的位置。
像下面這樣:

add_library(native-lib
             SHARED
             native-lib.cpp bitstream.c encoder.c gain_analysis.c lame.c id3tag.c 
             mpglib_interface.c newmdct.c presets.c psymodel.c quantize.c fft.c
             quantize_pvt.c reservoir.c set_get.c tables.c takehiro.c util.c  
             vbrquantize.c VbrTag.c version.c)

不過,這里要注意,AndroidStudio默認(rèn)的CMakeLists文件的位置在項(xiàng)目目錄中,我將它放到cpp目錄中去了。所以才能直接添加.c文件名,否則需要添加相對路徑“src/main/cpp/xxx.c”
到此,lame項(xiàng)目就已經(jīng)被放入我們的ndk項(xiàng)目中了。

3.移植修改

首先,需要對lame中的三個(gè)文件進(jìn)行一些小改動(dòng)。
1)刪除fft.c文件的47行的"include "vector/lame_intrin.h""

2)修改set_get.h文件的24行的#include“l(fā)ame.h"

3)將util.h文件的574行的"extern ieee754_float32_t fast_log2(ieee754_float32_t x);"
替換為 "extern float fast_log2(float x);"

這些跟ndk-builder是一樣的,網(wǎng)上有很多教程。

然后,需要修改app -> build.gradle文件

android {
...
    defaultConfig {
    ...
        externalNativeBuild{
            cmake{
                cFlags "-DSTDC_HEADERS"
            }
        }
    }
}

沒錯(cuò),就是添加這個(gè)-DSTDC_HEADERS編譯標(biāo)識。

大家可以試一下,如果不加這個(gè)標(biāo)志,我們的項(xiàng)目編譯會報(bào)錯(cuò),比如undefined symbol bcopy...之類的。

這里說明一下我的調(diào)查結(jié)果:
首先,添加-D標(biāo)志的意思就是給編譯器添加宏定義。那么-DSTDC_HEADERS就相當(dāng)于給項(xiàng)目增加一句”#define STDC_HEADERS“。

我們打開machine.h文件看一下第34行:

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else
# ifndef HAVE_STRCHR
#  define strchr index
#  define strrchr rindex
# endif
char   *strchr(), *strrchr();
# ifndef HAVE_MEMCPY
#  define memcpy(d, s, n) bcopy ((s), (d), (n))
#  define memmove(d, s, n) bcopy ((s), (d), (n))
# endif
#endif

意思很明白,如果沒有定義STDC_HEADERS這個(gè)宏則會用到bcopy方法,而這個(gè)方法我們根本沒有,于是就報(bào)錯(cuò)了。

4.測試

到現(xiàn)在我們的移植工作就已經(jīng)做完了,接下來可以簡單測試一下。

打開項(xiàng)目中的native-lib.cpp文件,做如下修改:

#include <jni.h>
#include <string>
#include "lame.h"

extern "C"
jstring
Java_com_javine_mylameproject_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    return env->NewStringUTF(get_lame_version());
}

運(yùn)行項(xiàng)目,如無意外我們的app會顯示lame的版本號 3.99.5

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容