1
0
Fork 0

Add support for building in Termux-Android in meson

- introduce cross perl
- workaround for the android linker
This commit is contained in:
ailin-nemui 2020-05-27 22:28:07 +02:00
parent 4b2c710ebe
commit 01ecb879a6
12 changed files with 167 additions and 46 deletions

32
INSTALL
View File

@ -2,12 +2,12 @@
Irssi installation instructions
-------------------------------
To compile irssi you need:
To compile Irssi you need:
- meson-0.49 build system with ninja-1.5 or greater
- glib-2.28 or greater
- openssl (for ssl support)
- perl-5.6 or greater (for perl support)
- perl-5.6 or greater (for Perl support)
- terminfo or ncurses (for text frontend)
For most people, this should work just fine:
@ -35,13 +35,13 @@ configure options
--prefix
Specifies the path where irssi will be installed.
YES, you can install irssi WITHOUT ROOT permissions
Specifies the path where Irssi will be installed.
YES, you can install Irssi WITHOUT ROOT permissions
by using --prefix=/home/dir
-Dwith-proxy=yes / --with-proxy
Build the irssi proxy (see startup-HOWTO).
Build the Irssi proxy (see startup-HOWTO).
-Dwith-perl=[yes|no] / --with-perl=[yes|no|module]
@ -70,9 +70,9 @@ configure options
Build without text frontend
If anything is in non-standard path, you can just give the paths in
CPPFLAGS and LIBS environment variable, eg.:
the -Dc_args and -Dc_link_args options variable, eg.:
CPPFLAGS=-I/opt/openssl/include LDFLAGS=-L/opt/openssl/lib ./configure
meson Build -Dc_args='-I/opt/openssl/include' -Dc_link_args='-L/opt/openssl/lib'
@ -112,6 +112,24 @@ perl static core fe
System specific notes
---------------------
Android
When cross compiling Irssi for Android, you can specify the path of
the cross-perl in the cross file.
You may not have a cross-perl available. In that case, you will have
to manually supply the required Perl arguments in the cross file. See
the commented properties in the example cross file.
An example cross file can be found in the docs folder. To use it, you
would call:
meson Build --cross-file cross-android-aarch64.txt \
--prefix /data/data/com.termux/files/usr \
--libdir lib \
-Dfhs-prefix=/data/data/com.termux/files/usr \
Cygwin
Getting perl scripting to work needs a few things:

View File

@ -665,6 +665,7 @@ else
want_gregex=no
fi
AC_DEFINE([FHS_PREFIX], [""], [Alternate filesystem prefix for Termux])
AH_TEMPLATE(HAVE_GMODULE)
AH_TEMPLATE(HAVE_SOCKS_H, [misc..])
AH_TEMPLATE(HAVE_STATIC_PERL)

View File

@ -0,0 +1,47 @@
[binaries]
ar = 'aarch64-linux-android-ar'
c = 'aarch64-linux-android-clang'
cpp = 'aarch64-linux-android-clang++'
ld = 'aarch64-linux-android-ld'
pkgconfig = '/home/builder/.termux-build/_cache/android-r20-api-24-v3/bin/aarch64-linux-android-pkg-config'
strip = 'aarch64-linux-android-strip'
;; you have to substitute 5.30.2 with the Perl version, that can be
;; obtained by running ` miniperl -e 'print substr $^V, 1' `
perl = ['/home/builder/.termux-build/perl/src/miniperl', '-I/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android', '-I/data/data/com.termux/files/usr/lib/perl5/5.30.2']
[properties]
needs_exe_wrapper = true
c_args = ['-fstack-protector-strong', '-Oz', '-I/data/data/com.termux/files/usr/include']
cpp_args = ['-fstack-protector-strong', '-Oz', '-I/data/data/com.termux/files/usr/include']
c_link_args = ['-L/data/data/com.termux/files/usr/lib', '-Wl,-rpath=/data/data/com.termux/files/usr/lib', '-Wl,--enable-new-dtags', '-Wl,--as-needed', '-Wl,-z,relro,-z,now', '-landroid-glob']
cpp_link_args = ['-L/data/data/com.termux/files/usr/lib', '-Wl,-rpath=/data/data/com.termux/files/usr/lib', '-Wl,--enable-new-dtags', '-Wl,--as-needed', '-Wl,-z,relro,-z,now', '-landroid-glob']
;; if you do not have a cross-perl like miniperl available, you have
;; to specify the required options by uncommenting the following
;; properties
;; you can get the proper values by running the commands on your
;; Android device:
;; ` perl -V::version: `
; perl_version = '5.30.2'
;; ` perl -MExtUtils::Embed -o ccopts `
; perl_ccopts = ['-I/data/data/com.termux/files/usr/include', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-I/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android/CORE']
;; ` perl -MExtUtils::Embed -o ldopts `
; perl_ldopts = ['-Wl,-E', '-I/data/data/com.termux/files/usr/include', '-L/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android/CORE', '-lperl', '-lm', '-ldl']
;; ` perl -V::archname: `
; perl_archname = 'aarch64-android'
;; ` perl -V::installsitearch: `
; perl_installsitearch = '/data/data/com.termux/files/usr/lib/perl5/site_perl/5.30.2/aarch64-android'
;; ` perl -V::installvendorarch: `
; perl_installvendorarch = ''
;; ` perl -E 'say for @INC' `
; perl_inc = ['/data/data/com.termux/files/usr/lib/perl5/site_perl/5.30.2/aarch64-android', '/data/data/com.termux/files/usr/lib/perl5/site_perl/5.30.2', '/data/data/com.termux/files/usr/lib/perl5/5.30.2/aarch64-android', '/data/data/com.termux/files/usr/lib/perl5/5.30.2']
[host_machine]
cpu_family = 'arm'
cpu = 'aarch64'
endian = 'little'
system = 'android'

View File

@ -11,6 +11,12 @@ cc = meson.get_compiler('c')
rootinc = include_directories('.')
dep = []
textui_dep = []
need_dl_cross_link = false
# The Android environment requires that all modules are linked to each other.
# See https://github.com/android/ndk/issues/201
if host_machine.system() == 'android'
need_dl_cross_link = true
endif
includedir = get_option('includedir')
incdir = 'irssi'
@ -66,8 +72,13 @@ def_suppress_printf_fallback = '-D' + 'SUPPRESS_PRINTF_FALLBACK'
# Help files #
##############
perl = find_program('perl')
run_command(perl, files('utils/syntax.pl'))
build_perl = find_program('perl', native : true)
if meson.is_cross_build()
cross_perl = find_program('perl')
else
cross_perl = build_perl
endif
run_command(build_perl, files('utils/syntax.pl'))
###################
# irssi-version.h #
@ -313,34 +324,46 @@ if want_perl
perl_rpath = ''
#### ccopts ####
res = run_command(perl, '-MExtUtils::Embed', '-e', 'ccopts')
foreach fl : res.stdout().strip().split()
if fl.startswith('-D') or fl.startswith('-U') or fl.startswith('-I') or fl.startswith('-i') or fl.startswith('-f') or fl.startswith('-m')
perl_cflags += fl
endif
perl_ccopts = meson.get_cross_property('perl_ccopts', false)
if perl_ccopts == false
res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ccopts')
perl_ccopts = res.stdout().strip().split()
endif
foreach fl : perl_ccopts
if fl.startswith('-D') or fl.startswith('-U') or fl.startswith('-I') or fl.startswith('-i') or fl.startswith('-f') or fl.startswith('-m')
perl_cflags += fl
endif
endforeach
perl_cflags += cc.get_supported_arguments('-fPIC')
#### ldopts ####
res = run_command(perl, '-MExtUtils::Embed', '-e', 'ldopts')
perl_ldopts = meson.get_cross_property('perl_ldopts', false)
if perl_ldopts == false
res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ldopts')
perl_ldopts = res.stdout().strip().split()
endif
skip_libs = ['-ldb', '-ldbm', '-lndbm', '-lgdbm', '-lc', '-lposix', '-rdynamic']
foreach fl : res.stdout().strip().split()
if not fl.startswith('-A') and not skip_libs.contains(fl)
if fl.startswith('-Wl,-rpath,')
perl_rpath = fl.split(',')[2]
perl_rpath_flags += fl
else
perl_ldflags += fl
endif
endif
foreach fl : perl_ldopts
if not fl.startswith('-A') and not skip_libs.contains(fl)
if fl.startswith('-Wl,-rpath,')
perl_rpath = fl.split(',')[2]
perl_rpath_flags += fl
else
perl_ldflags += fl
endif
endif
endforeach
perl_version = meson.get_cross_property('perl_version', false)
if perl_version == false
perl_version = run_command(cross_perl, '-V::version:').stdout().split('\'')[1]
endif
perl_dep = declare_dependency(compile_args : perl_cflags, link_args : perl_ldflags,
version : run_command(perl, '-V::version:').stdout().split('\'')[1])
version : perl_version)
####
if not cc.run('''
if not cc.compiles('''
#include <EXTERN.h>
#include <perl.h>
int main()
@ -349,15 +372,18 @@ int main()
return 0;
}
''', args : perl_cflags + perl_ldflags + perl_rpath_flags,
name : 'working Perl support').compiled()
name : 'working Perl support')
if require_perl
error('error linking with perl libraries')
else
warning('error linking with perl libraries')
endif
else
xsubpp_file_c = run_command(perl, '-MExtUtils::ParseXS', '-Eprint $INC{"ExtUtils/ParseXS.pm"} =~ s{ParseXS\\.pm$}{xsubpp}r').stdout()
xsubpp = generator(perl,
xsubpp_file_c = meson.get_cross_property('perl_xsubpp', false)
if xsubpp_file_c == false
xsubpp_file_c = run_command(build_perl, '-MExtUtils::ParseXS', '-Eprint $INC{"ExtUtils/ParseXS.pm"} =~ s{ParseXS\\.pm$}{xsubpp}r').stdout()
endif
xsubpp = generator(build_perl,
output : '@BASENAME@.c',
capture : true,
arguments : [ xsubpp_file_c, '@EXTRA_ARGS@', '@INPUT@' ],
@ -365,7 +391,7 @@ int main()
xsubpp_file = files(xsubpp_file_c)
if with_perl_lib == 'module'
perl_install_base = run_command(perl, '-MText::ParseWords=shellwords', '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}').stdout()
perl_install_base = run_command(build_perl, '-MText::ParseWords=shellwords', '-e', 'grep { s/^INSTALL_BASE=// && print && exit } shellwords $ENV{PERL_MM_OPT}').stdout()
if perl_install_base == ''
with_perl_lib = ''
endif
@ -381,9 +407,16 @@ int main()
set_perl_use_lib = false
perl_library_dir = with_perl_lib + ' default'
if with_perl_lib in ['site', 'vendor']
perlmoddir = run_command(perl, '-V::install' + with_perl_lib + 'arch:').stdout().split('\'')[1]
perlmoddir = meson.get_cross_property('perl_install' + with_perl_lib + 'arch', false)
if perlmoddir == false
perlmoddir = run_command(cross_perl, '-V::install' + with_perl_lib + 'arch:').stdout().split('\'')[1]
endif
elif with_perl_lib == 'module'
perlmoddir = perl_install_base / 'lib' / 'perl5' / run_command(perl, '-V::archname:').stdout().split('\'')[1]
perl_archname = meson.get_cross_property('perl_archname', false)
if perl_archname == false
perl_archname = run_command(cross_perl, '-V::archname:').stdout().split('\'')[1]
endif
perlmoddir = perl_install_base / 'lib' / 'perl5' / perl_archname
endif
elif with_perl_lib == ''
set_perl_use_lib = true
@ -399,7 +432,12 @@ int main()
perl_use_lib = get_option('prefix') / perlmoddir
if set_perl_use_lib
set_perl_use_lib = run_command(perl, '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', perl_use_lib).returncode() != 0
perl_inc = meson.get_cross_property('perl_inc', false)
if perl_inc == false
set_perl_use_lib = run_command(cross_perl, '-e', 'exit ! grep $_ eq $ARGV[0], grep /^\\//, @INC', perl_use_lib).returncode() != 0
else
set_perl_use_lib = not perl_inc.contains(perl_use_lib)
endif
if not set_perl_use_lib
perl_library_dir += ' - other path in @INC'
else
@ -460,6 +498,10 @@ dep_cflagsonly = []
foreach d : dep
dep_cflagsonly += d.partial_dependency(includes : true, compile_args : true)
endforeach
dl_cross_dep = []
if need_dl_cross_link
dl_cross_dep = dep
endif
##################
# irssi-config.h #
@ -473,6 +515,7 @@ conf.set('HAVE_SOCKS', false, description : 'Build with socks support')
conf.set('TERM_TRUECOLOR', want_truecolor, description : 'true color support in terminal')
conf.set('USE_GREGEX', want_gregex, description : 'use GRegex for regular expressions')
conf.set10('_DARWIN_USE_64_BIT_INODE', true, description : 'Enable large inode numbers on Mac OS X 10.5.')
conf.set_quoted('FHS_PREFIX', get_option('fhs-prefix'))
headers = [
'sys/ioctl.h',

View File

@ -14,3 +14,4 @@ option('with-capsicum', type : 'combo', description : 'Build with Capsicum
option('static-dependency', type : 'combo', description : 'Request static dependencies', choices : ['no', 'yes'])
option('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes', 'force'])
option('docdir', type : 'string', description : 'Documentation directory')
option('fhs-prefix', type : 'string', description : 'System prefix for Termux')

View File

@ -281,8 +281,8 @@ static void exec_show_list(void)
static void process_exec(PROCESS_REC *rec, const char *cmd)
{
const char *shell_args[4] = { "/bin/sh", "-c", NULL, NULL };
char **args;
const char *shell_args[4] = { FHS_PREFIX "/bin/sh", "-c", NULL, NULL };
char **args;
int in[2], out[2];
int n;
@ -341,7 +341,7 @@ static void process_exec(PROCESS_REC *rec, const char *cmd)
if (rec->shell) {
execvp(shell_args[0], (char **) shell_args);
fprintf(stderr, "Exec: /bin/sh: %s\n", g_strerror(errno));
fprintf(stderr, "Exec: " FHS_PREFIX "/bin/sh: %s\n", g_strerror(errno));
} else {
args = g_strsplit(cmd, " ", -1);
execvp(args[0], args);

View File

@ -37,7 +37,7 @@
#include <string.h>
int LLVMFuzzerInitialize(int *argc, char ***argv) {
char *irssi_argv[] = {*argv[0], "--home", "/tmp/irssi", NULL};
char *irssi_argv[] = { *argv[0], "--home", FHS_PREFIX "/tmp/irssi", NULL };
int irssi_argc = sizeof(irssi_argv) / sizeof(char *) - 1;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
g_log_set_null_logger();
@ -57,7 +57,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
THEME_REC *theme;
gchar *copy = g_strndup((const gchar *)data, size);
FILE *fp = fopen("/tmp/irssi/fuzz.theme", "wb");
FILE *fp = fopen(FHS_PREFIX "/tmp/irssi/fuzz.theme", "wb");
if (fp) {
fwrite(copy, strlen(copy), 1, fp);
fclose(fp);

View File

@ -1,4 +1,5 @@
libperl_common_a = shared_module('Irssi',
libperl_Irssi_a = shared_module('Irssi',
[ xsubpp.process(
files(
'Channel.xs',
@ -24,6 +25,7 @@ libperl_common_a = shared_module('Irssi',
include_directories : rootinc,
implicit_include_directories : true,
dependencies : dep + [ perl_dep ],
link_with : dl_cross_perl_core,
)
install_headers(

View File

@ -1,4 +1,4 @@
libperl_irc_a = shared_module('Irc',
libperl_Irssi_Irc_a = shared_module('Irc',
[ xsubpp.process(
files(
'Channel.xs',
@ -26,6 +26,7 @@ libperl_irc_a = shared_module('Irc',
include_directories : rootinc,
implicit_include_directories : true,
dependencies : dep + [ perl_dep ],
link_with : dl_cross_perl_core,
)
install_headers(

View File

@ -4,7 +4,7 @@ perl_signals_list_h = custom_target('perl-signals-list.h',
output : 'perl-signals-list.h',
capture : true,
depend_files : files('get-signals.pl'),
command : [perl, files('get-signals.pl'), '@INPUT@'],
command : [build_perl, files('get-signals.pl'), '@INPUT@'],
)
irssi_core_pl_h = custom_target('irssi-core.pl.h',
@ -14,7 +14,7 @@ irssi_core_pl_h = custom_target('irssi-core.pl.h',
command : [file2header, '@INPUT@', 'irssi_core_code'],
)
shared_module('perl_core',
libperl_core_a = shared_module('perl_core',
files(
'perl-common.c',
'perl-core.c',
@ -35,11 +35,16 @@ shared_module('perl_core',
install_dir : moduledir,
install_rpath : perl_rpath,
build_rpath : perl_rpath,
dependencies : dep_cflagsonly + [ perl_dep ],
dependencies : dep_cflagsonly + [ perl_dep ] + dl_cross_dep,
override_options : ['b_asneeded=false'],
)
shared_module('fe_perl',
dl_cross_perl_core = []
if need_dl_cross_link
dl_cross_perl_core += libperl_core_a
endif
libfe_perl_a = shared_module('fe_perl',
files(
'module-formats.c',
'perl-fe.c',
@ -52,6 +57,7 @@ shared_module('fe_perl',
install : true,
install_dir : moduledir,
dependencies : dep,
link_with : dl_cross_perl_core,
)
subdir('common')

View File

@ -1,4 +1,4 @@
libperl_textui_a = shared_module('TextUI',
libperl_Irssi_TextUI_a = shared_module('TextUI',
[ xsubpp.process(
files(
'Statusbar.xs',
@ -22,6 +22,7 @@ libperl_textui_a = shared_module('TextUI',
include_directories : rootinc,
implicit_include_directories : true,
dependencies : dep + [ perl_dep ],
link_with : dl_cross_perl_core,
)
install_headers(

View File

@ -1,4 +1,4 @@
libperl_ui_a = shared_module('UI',
libperl_Irssi_UI_a = shared_module('UI',
[ xsubpp.process(
files(
'Formats.xs',
@ -20,6 +20,7 @@ libperl_ui_a = shared_module('UI',
include_directories : rootinc,
implicit_include_directories : true,
dependencies : dep + [ perl_dep ],
link_with : dl_cross_perl_core,
)
install_headers(