Android 使用cmake 编译SDL2

SDL2官网下载

img

如这里解压得到 SDL2-2.0.12:

在这里插入图片描述

几个重要的目录与文件说明

android-project: Android 项目的模板项目
docs:说明文档
include:SDL2的头文件
src:SDL2的源文件
Android.mk: makefile的构建脚本,编译动态库和静态库
CmakeLists.txt: CMake的构建脚本,编译动态库和静态库
123456

1、搭建项目

使用android-project 作为一个模板搭建一个项目,必须包名一致(SDLActivity 里声明了native方法,如果包名不一致,本地方法与jni层的映射的方法对应不上,会报错,可以修改,不过先别管这么多,先跑起来再说)

1、新建一个项目,包名取org.libsdl.app

2、把模板项目android-project 下的文件复制过来,org.libsdl.app 下的所有文件,AndroidManifest.xml, app的build.gradle,复制后如下:

在这里插入图片描述

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.0"

    defaultConfig {
        applicationId "org.libsdl.app"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {

//            ndkBuild {
//                arguments "APP_PLATFORM=android-21"
//                abiFilters 'armeabi-v7a'
//            }

            cmake {
                arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static"
                cppFlags ""
                abiFilters 'armeabi-v7a'
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets.main {
        jniLibs.srcDir 'libs'
    }
    externalNativeBuild {

//        ndkBuild {
//            path 'src/main/jni/Android.mk'
//        }

        cmake {
            //这里需要指定到 jni/CMakeLists.txt 文件
            path "src/main/jni/CMakeLists.txt"
            version "3.10.2"
        }
    }
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152

(想用cmake 编译就打开cmake,想用makefile 方式就打开ndkBuild,这里使用了cmake方式)

AndroidManifest.xml 文件不贴了,原样照搬

3、

  1. 新建jni 文件夹,在jni 文件中新建SDL文件夹,把解压文件(SDL2-2.0.12)中的cmake、include、src文件夹直接复制到SDL文件夹中
  2. 把解压文件夹(SDL2-2.0.12) 中的所有 .in 结尾的文件和Android.mk、CMakeLists.txt也复制到SDL 文件中
  3. 在把模板项目中SDL2-2.0.12\android-project\app\jni 下的所有文件复制到jni 文件夹下

完成后项目结构如下:

在这里插入图片描述

(这里也把.mk 文件放进来,如果只是想用cmake 方式也不复制过来)

4、新建SDL2Android.c文件放到 jni/SDL/src 中

在这里插入图片描述

这里SDL2Android.c 文件作用是绘制一张图片,内容如下:SDL详细使用

文件中使用了zx.bmp图片,建一个assets文件,随便把一张图片放进去就行

在这里插入图片描述

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include "SDL.h"

typedef struct Sprite
{
    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());
        return result;
    }
    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);
        return result;
    }
    SDL_FreeSurface(temp);

    return result;
}

void draw(SDL_Window* window, SDL_Renderer* renderer, const Sprite sprite)
{
    int w, 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);
}

/**
 * 图片绘制,一定是个main方法
 * SDL 会自动调用这个方法,完成图片绘制与显示
 * @param argc
 * @param argv
 * @return
 */
int main(int argc, 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);
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101

5、修改 jni/src/CMakeLists.txt 文件,修改后如下,注释已经说明了

cmake_minimum_required(VERSION 3.4.1)

project(MY_APP)

#这里添加了头文件查找目录
include_directories(${CMAKE_SOURCE_DIR}/SDL/include)

#生成main.so 需要引用SDL2.so库 (SDL2.so是脚本文件jni/SDL/CMakeLists.txt 生成的)
find_library(SDL2 SDL2)

add_library(main SHARED)

#添加这个main.so 的原文件,把 SDL2Android.c 放到这个so库中(SDL_android_main.c 是自带的一个空文件,其他也可以直接使用这个文件)
target_sources(main PRIVATE ${CMAKE_SOURCE_DIR}/SDL/src/main/android/SDL_android_main.c
        ${CMAKE_SOURCE_DIR}/SDL/src/SDL2Android.c)

#把SDL2.so 加入main.so 中
target_link_libraries(main SDL2)

12345678910111213141516171819

6、jni/CMakeLists.txt 文件内容

cmake_minimum_required(VERSION 3.4.1)

project(GAME)

#编译 SDL 目录下的cmake文件
add_subdirectory(SDL)

#编译 src 目录下的cmake文件
add_subdirectory(src)
123456789

7、记得把app 中build.gradle 中cmake 指定到 jni/CMakeLists.txt 文件

在这里插入图片描述

8、编译项目,会在build/intermediates/cmake/debug/obj/armeabi-v7a 下生成想要的动态库与静态库(这里只编译了armv7a的)

在这里插入图片描述

9、运行项目:
在这里插入图片描述


https://blog.csdn.net/qq_37382732/article/details/108796638

发表评论

邮箱地址不会被公开。 必填项已用*标注