Skip to content

Commit 855cf19

Browse files
sp1ritCSjpakkane
authored andcommitted
android: Added android_exe_type kwargs to executable
By setting android_exe_type to `application`, the executable gets actually built as a shared library instead of an executable. This makes it possible to use an application within an android application process. #13758 https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/7555/
1 parent da28caa commit 855cf19

File tree

8 files changed

+56
-2
lines changed

8 files changed

+56
-2
lines changed

docs/yaml/functions/executable.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ varargs_inherit: _build_target_base
2121
kwargs_inherit: _build_target_base
2222

2323
kwargs:
24+
android_exe_type:
25+
type: str
26+
default: "'executable'"
27+
since: 1.8.0
28+
description: |
29+
Specifies the intended target of the executable. This can either be
30+
`executable`, if the intended usecase is to run the executable using
31+
fork + exec, or `application` if the executable is supposed to be
32+
loaded as shared object by the android runtime.
33+
34+
2435
export_dynamic:
2536
type: bool
2637
since: 0.45.0

mesonbuild/build.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class DFeatures(TypedDict):
112112
rust_kwargs |
113113
cs_kwargs)
114114

115-
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie', 'vs_module_defs'}
115+
known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie', 'vs_module_defs', 'android_exe_type'}
116116
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions', 'rust_abi'}
117117
known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs', 'rust_abi'}
118118
known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink', 'rust_abi'}
@@ -1996,6 +1996,7 @@ def __init__(
19961996
super().__init__(name, subdir, subproject, for_machine, sources, structured_sources, objects,
19971997
environment, compilers, kwargs)
19981998
self.win_subsystem = kwargs.get('win_subsystem') or 'console'
1999+
assert kwargs.get('android_exe_type') is None or kwargs.get('android_exe_type') in {'application', 'executable'}
19992000
# Check for export_dynamic
20002001
self.export_dynamic = kwargs.get('export_dynamic', False)
20012002
if not isinstance(self.export_dynamic, bool):

mesonbuild/interpreter/interpreter.py

+13
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
CT_BUILD_BY_DEFAULT,
5555
CT_INPUT_KW,
5656
CT_INSTALL_DIR_KW,
57+
_EXCLUSIVE_EXECUTABLE_KWS,
5758
EXECUTABLE_KWS,
5859
JAR_KWS,
5960
LIBRARY_KWS,
@@ -1816,12 +1817,24 @@ def func_dependency(self, node: mparser.BaseNode, args: T.Tuple[T.List[str]], kw
18161817
def func_disabler(self, node, args, kwargs):
18171818
return Disabler()
18181819

1820+
def _strip_exe_specific_kwargs(self, kwargs: kwtypes.Executable) -> kwtypes._BuildTarget:
1821+
kwargs = kwargs.copy()
1822+
for exe_kwarg in _EXCLUSIVE_EXECUTABLE_KWS:
1823+
del kwargs[exe_kwarg.name]
1824+
return kwargs
1825+
18191826
@permittedKwargs(build.known_exe_kwargs)
18201827
@typed_pos_args('executable', str, varargs=SOURCES_VARARGS)
18211828
@typed_kwargs('executable', *EXECUTABLE_KWS, allow_unknown=True)
18221829
def func_executable(self, node: mparser.BaseNode,
18231830
args: T.Tuple[str, SourcesVarargsType],
18241831
kwargs: kwtypes.Executable) -> build.Executable:
1832+
for_machine = kwargs['native']
1833+
m = self.environment.machines[for_machine]
1834+
if m.is_android() and kwargs.get('android_exe_type') == 'application':
1835+
holder = self.build_target(node, args, self._strip_exe_specific_kwargs(kwargs), build.SharedLibrary)
1836+
holder.shared_library_only = True
1837+
return holder
18251838
return self.build_target(node, args, kwargs, build.Executable)
18261839

18271840
@permittedKwargs(build.known_stlib_kwargs)

mesonbuild/interpreter/kwargs.py

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ class Executable(_BuildTarget):
393393
pie: T.Optional[bool]
394394
vs_module_defs: T.Optional[T.Union[str, File, build.CustomTarget, build.CustomTargetIndex]]
395395
win_subsystem: T.Optional[str]
396+
android_exe_type: T.Optional[Literal['application', 'executable']]
396397

397398

398399
class _StaticLibMixin(TypedDict):

mesonbuild/interpreter/type_checking.py

+6
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,12 @@ def _convert_darwin_versions(val: T.List[T.Union[str, int]]) -> T.Optional[T.Tup
701701
convertor=lambda x: x.lower() if isinstance(x, str) else None,
702702
validator=_validate_win_subsystem,
703703
),
704+
KwargInfo(
705+
'android_exe_type',
706+
(str, NoneType),
707+
validator=in_set_validator({'application', 'executable'}),
708+
since='1.8.0'
709+
),
704710
]
705711

706712
# The total list of arguments used by Executable

run_project_tests.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class ArgumentType(CompilerArgumentType):
7676
v: bool
7777

7878
ALL_TESTS = ['cmake', 'common', 'native', 'warning-meson', 'failing-meson', 'failing-build', 'failing-test',
79-
'keyval', 'platform-osx', 'platform-windows', 'platform-linux',
79+
'keyval', 'platform-osx', 'platform-windows', 'platform-linux', 'platform-android',
8080
'java', 'C#', 'vala', 'cython', 'rust', 'd', 'objective c', 'objective c++',
8181
'fortran', 'swift', 'cuda', 'python3', 'python', 'fpga', 'frameworks', 'nasm', 'wasm', 'wayland',
8282
'format',
@@ -1123,6 +1123,8 @@ def __init__(self, category: str, subdir: str, skip: bool = False, stdout_mandat
11231123
TestCategory('platform-osx', 'osx', not mesonlib.is_osx()),
11241124
TestCategory('platform-windows', 'windows', not mesonlib.is_windows() and not mesonlib.is_cygwin()),
11251125
TestCategory('platform-linux', 'linuxlike', mesonlib.is_osx() or mesonlib.is_windows()),
1126+
# FIXME, does not actually run in CI, change to run the test if an Android cross toolchain is detected.
1127+
TestCategory('platform-android', 'android', not mesonlib.is_android()),
11261128
TestCategory('java', 'java', backend is not Backend.ninja or not have_java()),
11271129
TestCategory('C#', 'csharp', skip_csharp(backend)),
11281130
TestCategory('vala', 'vala', backend is not Backend.ninja or not shutil.which(os.environ.get('VALAC', 'valac'))),
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <stdio.h>
2+
3+
int main(void) {
4+
return 0;
5+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
project('android exe type', 'c')
2+
fs = import('fs')
3+
4+
e = executable('executable', 'exe_type.c',
5+
android_exe_type : 'executable')
6+
a = executable('application', 'exe_type.c',
7+
android_exe_type : 'application')
8+
9+
if fs.name(e.full_path()).contains('.')
10+
error('Executable with exe_type `executable` did have expected filename')
11+
endif
12+
13+
if not fs.name(a.full_path()).startswith('lib') or not fs.name(a.full_path()).endswith('.so')
14+
error('Executable with exe_type `application` did not have expected filename')
15+
endif

0 commit comments

Comments
 (0)