aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian "sp1rit"​ <sp1rit@disroot.org>2025-04-16 22:11:38 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2025-04-17 19:01:22 +0300
commit855cf199fc950de3e764a74e7b545c2213aa601c (patch)
treeaaa1c702e0ed75b1fd40554495d9518036bcd4cd
parentda28caa63dc855ad897b259e6dbc1615c847fbf8 (diff)
downloadmeson-855cf199fc950de3e764a74e7b545c2213aa601c.zip
meson-855cf199fc950de3e764a74e7b545c2213aa601c.tar.gz
meson-855cf199fc950de3e764a74e7b545c2213aa601c.tar.bz2
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. mesonbuild#13758 https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/7555/
-rw-r--r--docs/yaml/functions/executable.yaml11
-rw-r--r--mesonbuild/build.py3
-rw-r--r--mesonbuild/interpreter/interpreter.py13
-rw-r--r--mesonbuild/interpreter/kwargs.py1
-rw-r--r--mesonbuild/interpreter/type_checking.py6
-rwxr-xr-xrun_project_tests.py4
-rw-r--r--test cases/android/1 exe_type/exe_type.c5
-rw-r--r--test cases/android/1 exe_type/meson.build15
8 files changed, 56 insertions, 2 deletions
diff --git a/docs/yaml/functions/executable.yaml b/docs/yaml/functions/executable.yaml
index abbc5fe..df71b79 100644
--- a/docs/yaml/functions/executable.yaml
+++ b/docs/yaml/functions/executable.yaml
@@ -21,6 +21,17 @@ varargs_inherit: _build_target_base
kwargs_inherit: _build_target_base
kwargs:
+ android_exe_type:
+ type: str
+ default: "'executable'"
+ since: 1.8.0
+ description: |
+ Specifies the intended target of the executable. This can either be
+ `executable`, if the intended usecase is to run the executable using
+ fork + exec, or `application` if the executable is supposed to be
+ loaded as shared object by the android runtime.
+
+
export_dynamic:
type: bool
since: 0.45.0
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 4f40a62..7320b88 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -112,7 +112,7 @@ known_build_target_kwargs = (
rust_kwargs |
cs_kwargs)
-known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie', 'vs_module_defs'}
+known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie', 'vs_module_defs', 'android_exe_type'}
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions', 'rust_abi'}
known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs', 'rust_abi'}
known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink', 'rust_abi'}
@@ -1996,6 +1996,7 @@ class Executable(BuildTarget):
super().__init__(name, subdir, subproject, for_machine, sources, structured_sources, objects,
environment, compilers, kwargs)
self.win_subsystem = kwargs.get('win_subsystem') or 'console'
+ assert kwargs.get('android_exe_type') is None or kwargs.get('android_exe_type') in {'application', 'executable'}
# Check for export_dynamic
self.export_dynamic = kwargs.get('export_dynamic', False)
if not isinstance(self.export_dynamic, bool):
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 2cd272d..d3bf86d 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -54,6 +54,7 @@ from .type_checking import (
CT_BUILD_BY_DEFAULT,
CT_INPUT_KW,
CT_INSTALL_DIR_KW,
+ _EXCLUSIVE_EXECUTABLE_KWS,
EXECUTABLE_KWS,
JAR_KWS,
LIBRARY_KWS,
@@ -1816,12 +1817,24 @@ class Interpreter(InterpreterBase, HoldableObject):
def func_disabler(self, node, args, kwargs):
return Disabler()
+ def _strip_exe_specific_kwargs(self, kwargs: kwtypes.Executable) -> kwtypes._BuildTarget:
+ kwargs = kwargs.copy()
+ for exe_kwarg in _EXCLUSIVE_EXECUTABLE_KWS:
+ del kwargs[exe_kwarg.name]
+ return kwargs
+
@permittedKwargs(build.known_exe_kwargs)
@typed_pos_args('executable', str, varargs=SOURCES_VARARGS)
@typed_kwargs('executable', *EXECUTABLE_KWS, allow_unknown=True)
def func_executable(self, node: mparser.BaseNode,
args: T.Tuple[str, SourcesVarargsType],
kwargs: kwtypes.Executable) -> build.Executable:
+ for_machine = kwargs['native']
+ m = self.environment.machines[for_machine]
+ if m.is_android() and kwargs.get('android_exe_type') == 'application':
+ holder = self.build_target(node, args, self._strip_exe_specific_kwargs(kwargs), build.SharedLibrary)
+ holder.shared_library_only = True
+ return holder
return self.build_target(node, args, kwargs, build.Executable)
@permittedKwargs(build.known_stlib_kwargs)
diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py
index c0b7440..fb34bbb 100644
--- a/mesonbuild/interpreter/kwargs.py
+++ b/mesonbuild/interpreter/kwargs.py
@@ -393,6 +393,7 @@ class Executable(_BuildTarget):
pie: T.Optional[bool]
vs_module_defs: T.Optional[T.Union[str, File, build.CustomTarget, build.CustomTargetIndex]]
win_subsystem: T.Optional[str]
+ android_exe_type: T.Optional[Literal['application', 'executable']]
class _StaticLibMixin(TypedDict):
diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py
index 1c9953e..78938ba 100644
--- a/mesonbuild/interpreter/type_checking.py
+++ b/mesonbuild/interpreter/type_checking.py
@@ -701,6 +701,12 @@ _EXCLUSIVE_EXECUTABLE_KWS: T.List[KwargInfo] = [
convertor=lambda x: x.lower() if isinstance(x, str) else None,
validator=_validate_win_subsystem,
),
+ KwargInfo(
+ 'android_exe_type',
+ (str, NoneType),
+ validator=in_set_validator({'application', 'executable'}),
+ since='1.8.0'
+ ),
]
# The total list of arguments used by Executable
diff --git a/run_project_tests.py b/run_project_tests.py
index 0dc2871..fa7c8a6 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -76,7 +76,7 @@ if T.TYPE_CHECKING:
v: bool
ALL_TESTS = ['cmake', 'common', 'native', 'warning-meson', 'failing-meson', 'failing-build', 'failing-test',
- 'keyval', 'platform-osx', 'platform-windows', 'platform-linux',
+ 'keyval', 'platform-osx', 'platform-windows', 'platform-linux', 'platform-android',
'java', 'C#', 'vala', 'cython', 'rust', 'd', 'objective c', 'objective c++',
'fortran', 'swift', 'cuda', 'python3', 'python', 'fpga', 'frameworks', 'nasm', 'wasm', 'wayland',
'format',
@@ -1123,6 +1123,8 @@ def detect_tests_to_run(only: T.Dict[str, T.List[str]], use_tmp: bool) -> T.List
TestCategory('platform-osx', 'osx', not mesonlib.is_osx()),
TestCategory('platform-windows', 'windows', not mesonlib.is_windows() and not mesonlib.is_cygwin()),
TestCategory('platform-linux', 'linuxlike', mesonlib.is_osx() or mesonlib.is_windows()),
+ # FIXME, does not actually run in CI, change to run the test if an Android cross toolchain is detected.
+ TestCategory('platform-android', 'android', not mesonlib.is_android()),
TestCategory('java', 'java', backend is not Backend.ninja or not have_java()),
TestCategory('C#', 'csharp', skip_csharp(backend)),
TestCategory('vala', 'vala', backend is not Backend.ninja or not shutil.which(os.environ.get('VALAC', 'valac'))),
diff --git a/test cases/android/1 exe_type/exe_type.c b/test cases/android/1 exe_type/exe_type.c
new file mode 100644
index 0000000..cd9ca7d
--- /dev/null
+++ b/test cases/android/1 exe_type/exe_type.c
@@ -0,0 +1,5 @@
+#include <stdio.h>
+
+int main(void) {
+ return 0;
+}
diff --git a/test cases/android/1 exe_type/meson.build b/test cases/android/1 exe_type/meson.build
new file mode 100644
index 0000000..5b0e64a
--- /dev/null
+++ b/test cases/android/1 exe_type/meson.build
@@ -0,0 +1,15 @@
+project('android exe type', 'c')
+fs = import('fs')
+
+e = executable('executable', 'exe_type.c',
+ android_exe_type : 'executable')
+a = executable('application', 'exe_type.c',
+ android_exe_type : 'application')
+
+if fs.name(e.full_path()).contains('.')
+ error('Executable with exe_type `executable` did have expected filename')
+endif
+
+if not fs.name(a.full_path()).startswith('lib') or not fs.name(a.full_path()).endswith('.so')
+ error('Executable with exe_type `application` did not have expected filename')
+endif