Содержание блога
Если у вас не установлены Android SDK, NDK, JDK, и т.д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т.д.
Сборка примера
- Скачайте этот пример. На всякий случай, я прикрепил его в виде архива: sdlcross-text.zip
- Извлеките пример из архива. Можете открыть папку с извлечённым примером в редакторе кода Sublime Text 4: https://www.sublimetext.com/download

- Скачайте архив SDL3-devel-3.4.0-android.zip. Этот архив можно найти по ссылке
- Скачайте архив SDL3_ttf-devel-3.2.2-android.zip. Этот архив можно найти по ссылке
- Оба архива выше содержат файлы формата .aar
- Файлы формата .arr из этих архивов нужно скопировать в папку "android-project/app/libs":

- Нужно прописать пути к этим библиотекам в скаченном ранее примере. Откройте файл "android-project/app/build.gradle", и пропишите пути к библиотекам. Должно выглядеть так:
| Code | 1
2
3
4
5
| dependencies {
implementation files('libs/SDL3-3.4.0.aar')
implementation files('libs/SDL3_ttf-3.2.2.aar')
implementation 'androidx.appcompat:appcompat:1.5.1'
} |
|
- В этом же файле есть секция externalNativeBuild:
| Code | 1
2
3
4
5
6
7
| externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared', '-DWITH_IMAGE=ON', '-DWITH_MIXER=OFF', '-DWITH_NET=OFF', '-DWITH_BOX2D=OFF'
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
// abiFilters 'arm64-v8a'
}
} |
|
- Здесь же в секции externalNativeBuild нужно закомментировать строку "abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'" и убрать комментарий со строки "abiFilters 'arm64-v8a'":
| Code | 1
2
3
4
5
6
7
| externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared', '-DWITH_IMAGE=ON', '-DWITH_MIXER=OFF', '-DWITH_NET=OFF', '-DWITH_BOX2D=OFF'
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'arm64-v8a'
}
} |
|
- В той же секции externalNativeBuild нужно отключить DWITH_IMAGE, исправив ON на OFF и нужно добавить '-DWITH_TTF=ON' для включения TTF, вот так:
| Code | 1
2
3
4
5
6
7
| externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared', '-DWITH_TTF=ON', '-DWITH_IMAGE=OFF', '-DWITH_MIXER=OFF', '-DWITH_NET=OFF', '-DWITH_BOX2D=OFF'
// abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
abiFilters 'arm64-v8a'
}
} |
|
- Скачайте прикреплённый архив font.zip, в котором лежит бесплатный шрифт, взятый по ссылке, и перенесите папку "fonts" в папку "android-project/app/src/main/assets":

- Откройте в редакторе кода файл CMakeLists.txt и добавьте строку новые строки:
| Code | 1
2
3
4
5
6
7
8
9
10
| option(WITH_TTF "Enable SDL3_ttf" ON)
if(WITH_TTF)
find_package(SDL3_ttf CONFIG REQUIRED)
endif()
if(WITH_TTF)
target_compile_definitions(sdlcross PRIVATE WITH_TTF)
target_link_libraries(sdlcross PRIVATE SDL3_ttf::SDL3_ttf)
endif() |
|
- Откройте в редакторе кода файл src/context.h и добавьте строку новые строки. Я скопировал немного лишнего, чтобы понимать куда копировать новые строки кода:
| C | 1
2
3
4
5
6
7
8
9
10
| #ifdef WITH_TTF
#include <SDL3_ttf/SDL_ttf.h>
#endif
typedef struct {
// ...
#ifdef WITH_TTF
SDL_Texture *textTexture;
#endif
// ... |
|
- Откройте в редакторе кода файл src/main.c и добавьте строку новые строки:
| C | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
| #if defined(WITH_TTF)
#include <SDL3_ttf/SDL_ttf.h>
#endif
SDL_AppResult SDLCALL SDL_AppInit(void **appstate, int argc, char *argv[]) {
(void) argc;
(void) argv;
// ...
#ifdef WITH_TTF
if (!TTF_Init())
{
SDL_Log("TTF_Init failed: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
TTF_Font *font = TTF_OpenFont("fonts/LiberationSans-Regular.ttf", 60);
if (!font)
{
SDL_Log("TTF_OpenFont failed: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
const char *text = "Привет, Мир!"; // Hello World!
SDL_Color textColor = (SDL_Color) { 100, 255, 100, 255 };
SDL_Surface *surface = TTF_RenderText_Blended(font, text, 0, textColor);
state->textTexture = SDL_CreateTextureFromSurface(state->renderer, surface);
SDL_DestroySurface(surface);
#endif
show_important_message(1, "Entering the loop");
return SDL_APP_CONTINUE;
}
SDL_AppResult SDLCALL SDL_AppIterate(void *appstate)
{
SdlCrossState *const state = appstate;
#ifdef WITH_TTF
SDL_FRect textRect;
textRect.x = 200.f;
textRect.y = 200.f;
SDL_GetTextureSize(state->textTexture, &textRect.w, &textRect.h);
// Draw the text
SDL_RenderTexture(state->renderer, state->textTexture, NULL, &textRect);
#endif
SDL_RenderPresent(state->renderer);
}
return SDL_APP_CONTINUE;
void SDLCALL SDL_AppQuit(void *appstate, SDL_AppResult result)
{
SdlCrossState *const state = appstate;
(void) result;
// ...
#if defined(WITH_TTF)
if (state->textTexture)
{
SDL_DestroyTexture(state->textTexture);
state->textTexture = NULL;
}
#endif
// ...
SDL_free(state);
TTF_Quit();
SDL_Quit();
} |
|
- Откройте CMD в папке apdroid-project и выполните команду для сборки программы в APK:
- Откройте вторую консоль в папке "android-project/app/build/outputs/apk/debug" и выполните команду для установки приложения на устройство, которое подключено по USB-кабелю к компьютеру:
| Bash | 1
| adb install -r app-debug.apk |
|
- Приложение будет установлено. Запустите приложение. Должен быть выведен текст "Привет, Мир!" зелёного цвета:

- Если текста нет или приложение закрывается, то выполните команду в консоли:
| Bash | 1
| adb logcat SDL:V DEBUG:I *:S |
|
- Эта команда выводит лог из устройства в консоль. Если непонятно в чём дело, то копируйте лог в ИИ, например, в Gemini, ChatGPT, DeepSeek и т.д.
- Примечание. Вы можете использовать программу scrcpy для вывода экрана смартфона на экран компьютера, чтобы делать скриншоты для форума. При этом смартфон должен быть подключён USB-кабелем.
|