1
0
mirror of https://github.com/irssi/irssi.git synced 2024-12-04 14:46:39 -05:00

Merge pull request #1199 from ailin-nemui/termux

Add support for building in Termux-Android in meson
This commit is contained in:
ailin-nemui 2020-06-17 13:57:30 +02:00 committed by GitHub
commit 964c067b1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 169 additions and 46 deletions

32
INSTALL
View File

@ -2,12 +2,12 @@
Irssi installation instructions Irssi installation instructions
------------------------------- -------------------------------
To compile irssi you need: To compile Irssi you need:
- meson-0.49 build system with ninja-1.5 or greater - meson-0.49 build system with ninja-1.5 or greater
- glib-2.28 or greater - glib-2.28 or greater
- openssl (for ssl support) - 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) - terminfo or ncurses (for text frontend)
For most people, this should work just fine: For most people, this should work just fine:
@ -35,13 +35,13 @@ configure options
--prefix --prefix
Specifies the path where irssi will be installed. Specifies the path where Irssi will be installed.
YES, you can install irssi WITHOUT ROOT permissions YES, you can install Irssi WITHOUT ROOT permissions
by using --prefix=/home/dir by using --prefix=/home/dir
-Dwith-proxy=yes / --with-proxy -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] -Dwith-perl=[yes|no] / --with-perl=[yes|no|module]
@ -70,9 +70,9 @@ configure options
Build without text frontend Build without text frontend
If anything is in non-standard path, you can just give the paths in 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 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 Cygwin
Getting perl scripting to work needs a few things: Getting perl scripting to work needs a few things:

View File

@ -665,6 +665,7 @@ else
want_gregex=no want_gregex=no
fi fi
AC_DEFINE([FHS_PREFIX], [""], [Alternate filesystem prefix for Termux])
AH_TEMPLATE(HAVE_GMODULE) AH_TEMPLATE(HAVE_GMODULE)
AH_TEMPLATE(HAVE_SOCKS_H, [misc..]) AH_TEMPLATE(HAVE_SOCKS_H, [misc..])
AH_TEMPLATE(HAVE_STATIC_PERL) 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('.') rootinc = include_directories('.')
dep = [] dep = []
textui_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') includedir = get_option('includedir')
incdir = 'irssi' incdir = 'irssi'
@ -66,8 +72,13 @@ def_suppress_printf_fallback = '-D' + 'SUPPRESS_PRINTF_FALLBACK'
# Help files # # Help files #
############## ##############
perl = find_program('perl') build_perl = find_program('perl', native : true)
run_command(perl, files('utils/syntax.pl')) 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 # # irssi-version.h #
@ -313,34 +324,46 @@ if want_perl
perl_rpath = '' perl_rpath = ''
#### ccopts #### #### ccopts ####
res = run_command(perl, '-MExtUtils::Embed', '-e', 'ccopts') perl_ccopts = meson.get_cross_property('perl_ccopts', false)
foreach fl : res.stdout().strip().split() if perl_ccopts == false
if fl.startswith('-D') or fl.startswith('-U') or fl.startswith('-I') or fl.startswith('-i') or fl.startswith('-f') or fl.startswith('-m') res = run_command(cross_perl, '-MExtUtils::Embed', '-e', 'ccopts')
perl_cflags += fl perl_ccopts = res.stdout().strip().split()
endif 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 endforeach
perl_cflags += cc.get_supported_arguments('-fPIC') perl_cflags += cc.get_supported_arguments('-fPIC')
#### ldopts #### #### 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'] skip_libs = ['-ldb', '-ldbm', '-lndbm', '-lgdbm', '-lc', '-lposix', '-rdynamic']
foreach fl : res.stdout().strip().split() foreach fl : perl_ldopts
if not fl.startswith('-A') and not skip_libs.contains(fl) if not fl.startswith('-A') and not skip_libs.contains(fl)
if fl.startswith('-Wl,-rpath,') if fl.startswith('-Wl,-rpath,')
perl_rpath = fl.split(',')[2] perl_rpath = fl.split(',')[2]
perl_rpath_flags += fl perl_rpath_flags += fl
else else
perl_ldflags += fl perl_ldflags += fl
endif endif
endif endif
endforeach 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, 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 <EXTERN.h>
#include <perl.h> #include <perl.h>
int main() int main()
@ -349,15 +372,18 @@ int main()
return 0; return 0;
} }
''', args : perl_cflags + perl_ldflags + perl_rpath_flags, ''', args : perl_cflags + perl_ldflags + perl_rpath_flags,
name : 'working Perl support').compiled() name : 'working Perl support')
if require_perl if require_perl
error('error linking with perl libraries') error('error linking with perl libraries')
else else
warning('error linking with perl libraries') warning('error linking with perl libraries')
endif endif
else else
xsubpp_file_c = run_command(perl, '-MExtUtils::ParseXS', '-Eprint $INC{"ExtUtils/ParseXS.pm"} =~ s{ParseXS\\.pm$}{xsubpp}r').stdout() xsubpp_file_c = meson.get_cross_property('perl_xsubpp', false)
xsubpp = generator(perl, 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', output : '@BASENAME@.c',
capture : true, capture : true,
arguments : [ xsubpp_file_c, '@EXTRA_ARGS@', '@INPUT@' ], arguments : [ xsubpp_file_c, '@EXTRA_ARGS@', '@INPUT@' ],
@ -365,7 +391,7 @@ int main()
xsubpp_file = files(xsubpp_file_c) xsubpp_file = files(xsubpp_file_c)
if with_perl_lib == 'module' 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 == '' if perl_install_base == ''
with_perl_lib = '' with_perl_lib = ''
endif endif
@ -381,9 +407,16 @@ int main()
set_perl_use_lib = false set_perl_use_lib = false
perl_library_dir = with_perl_lib + ' default' perl_library_dir = with_perl_lib + ' default'
if with_perl_lib in ['site', 'vendor'] 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' 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 endif
elif with_perl_lib == '' elif with_perl_lib == ''
set_perl_use_lib = true set_perl_use_lib = true
@ -399,7 +432,12 @@ int main()
perl_use_lib = get_option('prefix') / perlmoddir perl_use_lib = get_option('prefix') / perlmoddir
if set_perl_use_lib 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 if not set_perl_use_lib
perl_library_dir += ' - other path in @INC' perl_library_dir += ' - other path in @INC'
else else
@ -460,6 +498,10 @@ dep_cflagsonly = []
foreach d : dep foreach d : dep
dep_cflagsonly += d.partial_dependency(includes : true, compile_args : true) dep_cflagsonly += d.partial_dependency(includes : true, compile_args : true)
endforeach endforeach
dl_cross_dep = []
if need_dl_cross_link
dl_cross_dep = dep
endif
################## ##################
# irssi-config.h # # 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('TERM_TRUECOLOR', want_truecolor, description : 'true color support in terminal')
conf.set('USE_GREGEX', want_gregex, description : 'use GRegex for regular expressions') 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.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 = [ headers = [
'sys/ioctl.h', '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('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('install-glib', type : 'combo', description : 'Download and install GLib for you', choices : ['no', 'yes', 'force'])
option('docdir', type : 'string', description : 'Documentation directory') 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) static void process_exec(PROCESS_REC *rec, const char *cmd)
{ {
const char *shell_args[4] = { "/bin/sh", "-c", NULL, NULL }; const char *shell_args[4] = { FHS_PREFIX "/bin/sh", "-c", NULL, NULL };
char **args; char **args;
int in[2], out[2]; int in[2], out[2];
int n; int n;
@ -316,11 +316,13 @@ static void process_exec(PROCESS_REC *rec, const char *cmd)
/* child process, try to clean up everything */ /* child process, try to clean up everything */
setsid(); setsid();
#ifndef __ANDROID__
if (setuid(getuid()) != 0) if (setuid(getuid()) != 0)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
if (setgid(getgid()) != 0) if (setgid(getgid()) != 0)
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
#endif
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_DFL); signal(SIGQUIT, SIG_DFL);
@ -339,7 +341,7 @@ static void process_exec(PROCESS_REC *rec, const char *cmd)
if (rec->shell) { if (rec->shell) {
execvp(shell_args[0], (char **) shell_args); 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 { } else {
args = g_strsplit(cmd, " ", -1); args = g_strsplit(cmd, " ", -1);
execvp(args[0], args); execvp(args[0], args);

View File

@ -37,7 +37,7 @@
#include <string.h> #include <string.h>
int LLVMFuzzerInitialize(int *argc, char ***argv) { 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; int irssi_argc = sizeof(irssi_argv) / sizeof(char *) - 1;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
g_log_set_null_logger(); g_log_set_null_logger();
@ -57,7 +57,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
THEME_REC *theme; THEME_REC *theme;
gchar *copy = g_strndup((const gchar *)data, size); 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) { if (fp) {
fwrite(copy, strlen(copy), 1, fp); fwrite(copy, strlen(copy), 1, fp);
fclose(fp); fclose(fp);

View File

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

View File

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

View File

@ -4,7 +4,7 @@ perl_signals_list_h = custom_target('perl-signals-list.h',
output : 'perl-signals-list.h', output : 'perl-signals-list.h',
capture : true, capture : true,
depend_files : files('get-signals.pl'), 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', 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'], command : [file2header, '@INPUT@', 'irssi_core_code'],
) )
shared_module('perl_core', libperl_core_a = shared_module('perl_core',
files( files(
'perl-common.c', 'perl-common.c',
'perl-core.c', 'perl-core.c',
@ -35,11 +35,16 @@ shared_module('perl_core',
install_dir : moduledir, install_dir : moduledir,
install_rpath : perl_rpath, install_rpath : perl_rpath,
build_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'], 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( files(
'module-formats.c', 'module-formats.c',
'perl-fe.c', 'perl-fe.c',
@ -52,6 +57,7 @@ shared_module('fe_perl',
install : true, install : true,
install_dir : moduledir, install_dir : moduledir,
dependencies : dep, dependencies : dep,
link_with : dl_cross_perl_core,
) )
subdir('common') subdir('common')

View File

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

View File

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