Android

fortune-mod cross-compiling for Android / ARM aarch64

This is mostly a log of the attempts to get fortune-mod to run on my Samsung S7 running LineageOS 14.1. After few hurdles, everything got built.

Recode problems

Trying to get recode to build (required by fortune-mod) I ended up with some errors which I could not figure out how to fix (and all internet posts pointed to being too old macros).

AM_INIT_AUTOMAKE not found in library
AM_WITH_DMALLOC

Switched to recode at https://github.com/pinard/Recode

The thing compiled, but now there were problems linking to fortune-mod:

undefined reference to `program_name'

After checking around -> seems Recode points to a program_name variable that the program that links against it has to define. While trying to add it by myself, I bumped into a patch for fortune-mod-1.99.1 which did it, among other things:

http://www7.frugalware.org/pub/frugalware/frugalware-current/source/apps/fortune-mod/fortune-mod-1.99.1.patch

strfile and rot

While creating fortune-mod, it calls two internal programs that are supposed to have already been built: strfile and rot. Whie these are built using (the ARM aarch64 architecture since cross-compilation), they can’t be executed on the x86-64 build machine.

I figured I could get them by installing the host fortune-mod, but that only came with strfile!
Checking the source code of rot.c is obvious that it can easily be built to x86 architecture:

gcc rot.c -o rot.host

Thus I was able to get the .dat files to build.

Once all the datfiles were copied to the phone into the /system/usr/local/share/games/fortunes/ – the trouble was that fortune did not display anything! Ended up doing a strace on it and while it was finding the cookie files:

newfstatat(AT_FDCWD, "/system/usr/local/share/games/fortunes/linuxcookie.u8", {st_mode=S_IFREG|0644, st_size=19654, ...}, 0) = 0
openat(AT_FDCWD, "/system/usr/local/share/games/fortunes/linuxcookie.u8", O_RDONLY) = 5

and was also reading them properly, it was crashing looking for gconv-modules:

read(11, "* Omnic looks at his 33.6k link "..., 4096) = 4096
openat(AT_FDCWD, "/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/gconv/gconv-modules", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
exit_group(0) = ?
+++ exited with 0 +++

Since the paths did not start with /system (fortunes-mod had the prefix set to /system in the Makefile, to match the Android phone system layout) they must be from a call within the Recode library …

Hmmm. Onto the source code of fortune (fortune.c) to see how this is called, I was lucky:

if(fp->utf8_charset) {
    char *output;
    output = recode_string (request, (const char *)line);
    fputs(output, stdout);
    free(output);
}
else
    fputs((char *)line, stdout);

Checking how the utf8_charset is set to true:

sprintf(testpath, "%s.u8", path);
if(stat(testpath, &statbuf) == 0)
    fp->utf8_charset = TRUE;

If the cookie files had the .u8 links defined, it was assumed they are utf8 and recode was called!

Checking the deployment, darn, I also copied the .u8 files to the phone.

-rw-r--r-- 1 viulian viulian 19654 Nov 15 21:10 linuxcookie
-rw-rw-r-- 1 viulian viulian 444 Nov 15 21:35 linuxcookie.dat
lrwxrwxrwx 1 viulian viulian 11 Nov 16 06:58 linuxcookie.u8 -> linuxcookie

I thus deleted the *.u8 links and now fortune works! The wasted time was getting the build going with the reload library and frustrating to see that the *.u8 files were not processed. ASCII do a good job in fact 🙂

 

Leave a Reply