-
Notifications
You must be signed in to change notification settings - Fork 0
/
README_android.txt
398 lines (284 loc) · 13.1 KB
/
README_android.txt
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
Android
=======
This port should support Android 3.1 (Honeycomb, API level 13) and above.
Dependencies
============
This port depends on having CMake, the Android SDK, the Android NDK and
a Java JDK.
We assume you are building on Linux or otherwise a Unix-like system,
including MSYS.
Install the SDK
===============
The most simple way is to install Android Studio which by default will
place a copy of the SDK into ~/Android/Sdk. Set the ANDROID_HOME
environment variable to point to it:
export ANDROID_HOME=$HOME/Android/Sdk
Alternatively you can also download the command-line SDK tools. In that
case you will have to accept the licenses, for example like this:
~/Android/Sdk/tools/bin/sdkmanager --licenses
Install the NDK
===============
The most simple way is again to use Android Studio. Create a new project
with C++ support and it will ask you if you want to install the NDK and
will then proceed to place it into ~/Android/Sdk/ndk-bundle.
Alternatively you can download the NDK and place anywhere you like.
Make NDK standalone toolchain
=============================
Next you need to setup a standalone NDK toolchain. Set an environment
variable to point to the desired location of the Android toolchain:
export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-toolchain-arm
export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-toolchain-arm64
export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-toolchain-x86
export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-toolchain-x86_64
export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-toolchain-mips
export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android-toolchain-mips64
If you do not want to distribute your game for all 6 supported Android
architectures you can probably do it just for arm (most actual devices)
amd x86_64 (the Android emulator).
Assuming the NDK was extracted into ~/Android/Sdk/ndk-bundle run the following
command:
python ~/Android/Sdk/ndk-bundle/build/tools/make_standalone_toolchain.py \
--api=15 --install-dir=$ANDROID_NDK_TOOLCHAIN_ROOT --arch=arm
You can use any api 9 or higher but 15 is the lowest this was tested
with.
Use the --arch parameter according to the toolchain you are creating:
--arch=arm
--arch=arm64
--arch=x86
--arch=x64_64
--arch=mips
--arch=mips64
Build dependencies for Allegro
==============================
Now you should build the dependencies for the Allegro addons that you want
(you can skip this if just want to try out some simple examples). Most of
the libraries use the standard GNU build system, and follow the same pattern.
For example, to build libpng:
tar zxf libpng-1.6.6.tar.xz
cd libpng-1.6.6
./configure --host=x86_64-linux-androideabi \
--prefix=$HOME/allegro/build/deps
make
make install
For host you will generally use the following host for each architecture:
if arch == "x86" then host = "i686-linux-android"
if arch == "x86_64" then host = "x86_64-linux-android"
if arch == "arm" then host = "arm-linux-androideabi"
if arch == "arm64" then host = "aarch64-linux-android"
if arch == "mips" then host = "mipsel-linux-android"
if arch == "mips64" then host = "mips64el-linux-android"
If you get an error during configure about the system being unrecognised then
update the `config.guess` and `config.sub` files. The files in libpng-1.6.6
are known to work.
The above commands will usually install both static and shared libraries into
the `deps` directory where it can be found by CMake, next. You could install
into the toolchain directory instead. If you want only static or shared
libraries, you can usually pass `--disable-static` or `--disable-shared` to
configure.
The static libraries should be easier to use (though I often had problems with
unresolved symbols when it came to run the programs, to investigate later).
If you wish to use shared libraries, be aware that shared objects must be
named like "libFOO.so", despite standard practice. Most libraries you build
will have version suffixes by default, e.g. libpng16.so.1.6. Renaming the
file after it is produced will not work as the versions are embedded as the
soname. For libraries built using libtool, you can avoid the version suffixes
as follows:
make LDFLAGS=-avoid-version
make LDFLAGS=-avoid-version install
though you may want to edit the Makefiles instead to avoid overriding
important flags in LDFLAGS.
You need to ensure that CMake finds the the library file that matches the
soname. Either delete the symlinks (e.g. libpng.so -> libpng16.so)
or modify the paths in CMake variables manually.
Building Allegro
================
The following steps will build Allegro for Android. Note that you still
need ANDROID_NDK_TOOLCHAIN_ROOT (see above) in your environment, and
repeat for each of the architectures you want to build for.
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-android.cmake
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_TARGET=android-15
-DARM_TARGETS=armeabi-v7a
make
make install
Under Windows append -G"MSYS Makefiles" to the cmake options.
Change ANDROID_TARGETS to whichever architecture you are building for.
The recognized architectures are:
armeabi
armeabi-v7a
arm64-v8a
x86
x86_64
mips
mips64
See here for more information: https://developer.android.com/ndk/guides/abis.html
This produces the normal Allegro native libraries (liballegro-*.so) as
well as allegro-release.aar.
Run `make install` to install the headers into the toolchain directory
and can be found when compiling Allegro code later.
You may want to add -DWANT_MONOLITH=ON if you prefer a single Allegro library
instead of one for each addon.
NOTE: On OS X, add -DCMAKE_INSTALL_NAME_TOOL=/usr/bin/install_name_tool to
the cmake command line.
Running examples
================
You need the adb tool (the Android Debug Bridge) set up, and USB debugging
enabled on your device. This can be quite involved, so please refer to the
Android tool documentation.
There are makefile targets named "run_FOO", so you can install and run
examples easily by typing, e.g.
make run_speed
Many demos and examples do work, minimally, but most do not support touch
input or react to orientation changes, etc. Good examples to try are
ex_draw_bitmap and ex_touch_input.
If you want to build just the .apk for an example, there are targets
for that as well:
make ex_draw_bitmap_apk
adb install -r examples/ex_draw_bitmap.project/bin/ex_draw_bitmap-debug.apk
adb -d shell 'am start -n org.liballeg.examples.ex_draw_bitmap/.Activity'
How startup works on Android
============================
The startup process begins with your application's MainActivity class.
In the static initialiser for the Activity, you must manually load the
shared libraries that you require, i.e. Allegro and its addons,
with dependencies loaded first. For a C++ program, you may need to load
the shared library of your chosen STL implementation.
After that the onCreate method of the AllegroActivity will be executed, which
does some Allegro initialisation. Allegro will then load your application
from another shared library. The library name can be specified by overriding
the constructor in your Activity class, otherwise the default is "libapp.so".
After loading, the `main` function in the library is finally called.
Poking around in the android/example directory may help.
Using Allegro in your game
==========================
If you build with examples or demos, look into your build folder for
any of them, for example
build/demos/speed
It will have a folder called speed.project which is a gradle project
ready to compile for Android. You can use it as a template for your
own game code. (Either by opening it in Android Studio or by using
commandline gradle to compile.)
Read the next section if you would like to create an Android project
using Allegro from scratch.
Using Allegro in a new project
==============================
Start Android Studio.
Note: Android Studio is not strictly required, you can edit the files mentioned
below with any text editor instead of in Android Studio and run ./gradlew instead
of rebuilding from within the IDE.
Android Studio just is usually more convenient to use when porting a game to Android.
On the welcome dialog, select "Start a new Android Studio project".
On the "Create Android Project" screen, make sure to check the
"Include C++ support" checkbox and click Next.
On the "Target Android Devices" screen leave everything at the defaults
and click Next.
On the "Add an Activity to Mobile" screen pick "Empty Activity".
On the "Configure Activity" screen leave the defaults and click Next.
On the "Customize C++ Support" screen leave everything at defaults
and click Finish.
You should be able to click the green arrow at the top and run your
application. If not make sure to fix any problems in your Android
Studio setup - usually it will prompt you to download any missing
components like the NDK or (the special Android) CMake. After that you
should be able to run your new Android app, either in an emulator or on
a real device.
The program we now have already shows how to mix native code and Java
code, it just does not use Allegro yet.
Find MainActivity.java and adapt it to look like this (do not
modify your package line at the top though):
import org.liballeg.android.AllegroActivity;
public class MainActivity extends AllegroActivity {
static {
System.loadLibrary("allegro");
System.loadLibrary("allegro_primitives");
System.loadLibrary("allegro_image");
System.loadLibrary("allegro_font");
System.loadLibrary("allegro_ttf");
System.loadLibrary("allegro_audio");
System.loadLibrary("allegro_acodec");
System.loadLibrary("allegro_color");
}
public MainActivity() {
super("libnative-lib.so");
}
}
If you used the monolith library, you only need a single
System.loadLibrary for that.
The "import org.liballeg.android.AllegroActivity" line will be red.
Let's fix that. Find the allegro-release.aar from build/lib, where
build is the build folder you used when building Allegro. Open your
Project-level build.gradle and make your "allprojects" section look
like this:
allprojects {
repositories {
google()
jcenter()
flatDir { dirs 'libs' }
}
}
Then copy allegro-release.aar into the app/libs folder of your Android
Studio project. For example I did the following:
cp ~/allegro-build/lib/allegro-release.aar ~/AndroidStudioProjects/MyApplication/app/libs/
Now open your app-level build.gradle and add this line inside of the
dependencies section:
implementation "org.liballeg.android:allegro-release:1.0@aar"
On older versions of Android studio use this instead:
compile "org.liballeg.android:allegro-release:1.0@aar"
Next hit the "Sync Now" link that should have appeared at the top of
Android Studio. If you look back at MainActivity.java, nothing should
be red any longer.
Now run your app again.
It will open but crash right away. That is because we are still using
the sample C++ code. Let's instead use some Allegro code. Find the
native-lib.cpp and replace its code with this:
#include <allegro5/allegro5.h>
int main(int argc, char **argv) {
al_init();
auto display = al_create_display(0, 0);
auto queue = al_create_event_queue();
auto timer = al_create_timer(1 / 60.0);
auto redraw = true;
al_register_event_source(queue, al_get_display_event_source(display));
al_register_event_source(queue, al_get_timer_event_source(timer));
al_start_timer(timer);
while (true) {
if (redraw) {
al_clear_to_color(al_map_rgb_f(1, al_get_time() - (int)(al_get_time()), 0));
al_flip_display();
redraw = false;
}
ALLEGRO_EVENT event;
al_wait_for_event(queue, &event);
if (event.type == ALLEGRO_EVENT_TIMER) {
redraw = true;
}
}
return 0;
}
The #include <allegro5/allegro5.h> will be red. Oh no. Again, let's fix
it. Find CMakeLists.txt under External Build Files and add a line like
this:
include_directories(${ANDROID_NDK_TOOLCHAIN_ROOT}/user/{ARCH}/include)
Where ${ANDROID_NDK_TOOLCHAIN_ROOT}/user/{ARCH} should be the path where
the Allegro headers were installed during Allegro's "make install", for
example:
include_directories($HOME/android-toolchain-arm/user/arm/include)
Then add a line like this:
target_link_libraries(native-lib ${ANDROID_NDK_TOOLCHAIN_ROOT}/user/{ARCH}/lib/liballegro.so)
For example:
target_link_libraries(native-lib $HOME/android-toolchain-arm/user/arm/lib/liballegro.so)
Finally, create these folders in your project:
app/src/main/jniLibs/armeabi-v7a
app/src/main/jniLibs/arm64-v8a
app/src/main/jniLibs/x86
app/src/main/jniLibs/x86_64
app/src/main/jniLibs/mips
app/src/main/jniLibs/mips64
And copy the .so files in the corresponding folder for its architecture.
You may have to use "Build->Refresh Linked C++ Projects" for Android
Studio to pick up the CMakeLists.txt changes.
Run the app again. If it worked, congratulations! You just ran your
first Allegro program on Android!
(The sample code will just flash your screen yellow and red with no way to quit, so you will have to force quit it.)