Android Studio用cmake编译SDL2

先说SDL(Simple DirectMedia Layer)的作用吧,SDL是套跨平台的多媒体库,代码是用c语言写的,在Android应用开发上多是和FFmpeg合作来开发我们常用的视音频播放器。关于FFmpeg移植到Android可参加博客:FFmpeg(3.3.2)移植Android平台Android Studio通过cmake创建FFmpeg项目就可以了。先上一张FFmpeg+SDL2实现的音频播放器效果(后面开发完了也会开源出来的,可做网络音乐或FM等SDK的使用)

SDL2和FFmpeg开发的音频播放器

我在上一篇博客中(Android编译SDL2和demo展示(2.0.5))已经实现了把SDL2移植到Android平台上,但是是在eclipse+NDK下面编译的,随着Android Studio的兴起,现在开发Android都不用eclipse了,所以就打算用AS再编译一次。
在编译的过程中发现AS已经不支持低版本的NDK了,只好用最新版本的NDK(NDK国内下载地址)这里我用的是13b版本的,但是新的NDK已经改变了编译clang来编译不再是gcc了,直接移植源码发现编译到了和OpenGL相关的库时就报错了,找不到相应的引用,尝试了各种方法都误解,最终想到了通过移植SDL2.so库和.c源文件的方式来移植,这种方式完全不影响我们添加自己的C代码,也算一种比较好的解决办法了。
一、用AS创建C/C++项目,这里需要注意,由于Java和c语言的调用是个包名类名方法名相关的,所以当我们在SDL中编译SDL2.so库时使用了怎样的包名结构和类结构,这里也需要一样的结构才行,不然不能调用,新项目的包名可以不一样,新建包的包名和SDL2.so库里面的一样就可以了。这里就用默认的包名和类名开演示。
1、用AS创建C/C++项目,包名为:org.libsdl.app,启动activity为:SDLActivity,因为这些信息都打包到了SDL2.so在了里面。

AS创建c/c++项目

更改activity为SDLActivity

2、刚创建的项目还不能编译成功,需要设置NDK路径

添加NDK路径

运行AS C/C++默认项目成功

二、改造默认工程
1、删掉原来的main中cpp文件夹,创建jni文件夹(习惯了jni,用cpp文件夹也行)。然后在jni文件夹中创建armeabi文件夹,然后把在Android编译SDL2和demo展示(2.0.5)中生成的libSDL2.so复制到armeabi文件夹中;再在jni文件夹中创建sdl文件夹,并将SDL中的头文件include拷贝到里面;如图:

导入SDL库和头文件

2、在sdl中创建src文件夹,然后导入需要的文件:SDL中src根目录下的所以文件、core文件夹中的android文件夹中所以文件(这里面就是实现的SDLActivity.java中的本地方法)、dynapi文件夹中所以文件、main文件夹中android文件夹中的所有文件。如图:

导入SDL中src需要文件

这样就算改造完成了。
三、编写CMakeLists编译脚本
1、更改生成的动态库名称:sdlmain

add_library( # Sets the name of the library.
sdlmain
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/jni/sdl/src/main/android/SDL_android_main.c
src/main/jni/SDL4Android.c)

其中SDL_android_main.c会调用SDL_android中的函数,然后还作为入口方法调用我们自己SDL4Android.c文件中的main方法,SDL4Android.c是我们自己添加的c文件。
2、导入SDL头文件:
include_directories(src/main/jni/sdl/include)
3、添加SDL2.so库:

add_library( SDL2
SHARED
IMPORTED)
set_target_properties( SDL2
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/src/main/jni/armeabi/libSDL2.so)

4、链接SDL2.so和libsdlmain.so

target_link_libraries( # Specifies the target library.
sdlmain
SDL2
# Links the target library to the log library
# included in the NDK.
${log-lib} )

这样CMakeLists配置好了,全部如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
include_directories(src/main/jni/sdl/include)
add_library( # Sets the name of the library.
                    sdlmain
                    # Sets the library as a shared library.
                    SHARED
                    # Provides a relative path to your source file(s).
                    src/main/jni/sdl/src/main/android/SDL_android_main.c
                    src/main/jni/SDL4Android.c)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
                    log-lib
                    # Specifies the name of the NDK library that
                    # you want CMake to locate.
                    log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
add_library( SDL2
                    SHARED
                    IMPORTED)
set_target_properties( SDL2
                    PROPERTIES IMPORTED_LOCATION
                    ${CMAKE_SOURCE_DIR}/src/main/jni/armeabi/libSDL2.so)
target_link_libraries( # Specifies the target library.
                    sdlmain
                    SDL2
                    # Links the target library to the log library
                    # included in the NDK.
                    ${log-lib} )

四、配置build.gradle,因为只编译了arm平台的,所以要指定一下只生成arm平台和jniLibs目录:

externalNativeBuild {
        cmake {
                cppFlags""
        }
        ndk {
                abiFilters"armeabi"
        }
}
sourceSets{
        main{
                jniLibs.srcDirs = ['src/main/jni']
        }
}

五、最好把SDL4Android.c添加到jni根目录下:

#include
#include
#include
#include"SDL.h"
typedef structSprite
{
    SDL_Texture* texture;
    Uint16 w;
    Uint16 h;
} Sprite;
/* Adapted from SDL's testspriteminimal.c */
Sprite LoadSprite(const char* file,SDL_Renderer* renderer)
{
    Sprite result;
    result.texture = NULL;
    result.w =0;
    result.h =0;
    SDL_Surface* temp;
    /* Load the sprite image */
    temp = SDL_LoadBMP(file);
    if(temp == NULL)
    {
        fprintf(stderr,"Couldn't load %s: %s\n",file,SDL_GetError());
        returnresult;
    }
    result.w = temp->w;
    result.h = temp->h;
    /* Create texture from the image */
    result.texture = SDL_CreateTextureFromSurface(renderer,temp);
    if(!result.texture) {
        fprintf(stderr,"Couldn't create texture: %s\n",SDL_GetError());
        SDL_FreeSurface(temp);
        returnresult;
    }
    SDL_FreeSurface(temp);
    returnresult;
    }
    voiddraw(SDL_Window* window,SDL_Renderer* renderer,constSprite       sprite)
{
    intw,h;
    SDL_GetWindowSize(window,&w,&h);
    SDL_Rect destRect = {w/2- sprite.w/2,h/2- sprite.h/2,sprite.w,sprite.h};
    /* Blit the sprite onto the screen */
    SDL_RenderCopy(renderer,sprite.texture,NULL,&destRect);
    }
    intmain(intargc,char*argv[])
    {
        SDL_Window *window;
        SDL_Renderer *renderer;
        if(SDL_CreateWindowAndRenderer(0,0,0,&window,&renderer) <0)
        exit(2);
        Sprite sprite = LoadSprite("zx.bmp",renderer);
        if(sprite.texture == NULL)
            exit(2);
        /* Main render loop */
        Uint8 done =0;
        SDL_Event event;
        while(!done)
            {
                /* Check for events */
                while(SDL_PollEvent(&event))
                {
                    if(event.type == SDL_QUIT || event.type == SDL_KEYDOWN || event.type == SDL_FINGERDOWN)
                    {
                        //done = 1;
                    }
                }
                /* Draw a gray background */
                SDL_SetRenderDrawColor(renderer,0xA0,0xA0,0xA0,0xFF);
                SDL_RenderClear(renderer);
                draw(window,renderer,sprite);
                /* Update the screen! */
                SDL_RenderPresent(renderer);
                SDL_Delay(10);
            }
        exit(0);
}

然后把SDL中的SDLActivity.java中的代码复制到我们的SDLActivity中。最好在main中添加资源文件assets,拷贝一张需要展示的图片来运行demo,这样就完成了移植:

[图片上传中。。。(8)]最终目录结构

运行效果图

就这样了,有疑问的地方可以留言,demo下载地址:Github:SDLforAndroidAS,下一篇就写SDL和FFmpeg的整合。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容