Both variants

pull/14121/head
Marco Rebhan 1 month ago
commit 7f0a58ae0d
No known key found for this signature in database
  1. 2
      mesonbuild/backend/backends.py
  2. 6
      mesonbuild/backend/ninjabackend.py
  3. 69
      mesonbuild/build.py
  4. 3
      mesonbuild/interpreter/interpreter.py
  5. 3
      mesonbuild/interpreter/interpreterobjects.py
  6. 75
      mesonbuild/modules/nsbundle.py

@ -303,6 +303,8 @@ class Backend:
filename = t.get_outputs()[0]
elif isinstance(t, build.CustomTargetIndex):
filename = t.get_outputs()[0]
elif isinstance(t, build.BundleTarget):
filename = t.get_filename()
else:
assert isinstance(t, build.BuildTarget), t
filename = t.get_filename()

@ -895,6 +895,8 @@ class NinjaBackend(backends.Backend):
self.generate_custom_target(target)
if isinstance(target, build.RunTarget):
self.generate_run_target(target)
if isinstance(target, build.BundleTarget):
return self.generate_bundle_target3(target)
compiled_sources: T.List[str] = []
source2object: T.Dict[str, str] = {}
name = target.get_id()
@ -1594,6 +1596,10 @@ class NinjaBackend(backends.Backend):
self.add_build(elem)
def generate_bundle_target3(self, target: build.BundleTarget) -> None:
main_exe = os.path.join(self.get_target_dir(target.main_exe), target.main_exe.get_filename())
self.generate_bundle_target(target, main_exe)
def generate_cs_resource_tasks(self, target) -> T.Tuple[T.List[str], T.List[str]]:
args = []
deps = []

@ -3109,6 +3109,75 @@ class FrameworkBundle(SharedLibrary, BundleTargetBase):
return self.environment.get_framework_dir(), '{frameworkdir}'
class BundleTarget(BundleTargetBase):
def __init__(self, name: str, subdir: str, subproject: str, environment: environment.Environment, main_exe: T.Union[Executable, SharedLibrary], bundle_type: BundleType):
super().__init__(name, subdir, subproject, True, main_exe.for_machine, environment)
self.main_exe: T.Union[Executable, SharedLibrary] = main_exe
self.bundle_type: BundleType = bundle_type
self.install_dir: T.Optional[str] = None
self.bundle_info: BundleInfo = BundleInfo(self)
if bundle_type == BundleType.APPLICATION:
assert isinstance(main_exe, Executable)
elif bundle_type == BundleType.FRAMEWORK:
assert isinstance(main_exe, SharedLibrary)
def __repr__(self):
repr_str = "<{0} {1}: {2}>"
return repr_str.format(self.__class__.__name__, self.get_id(), self.get_filename())
def __str__(self):
return f"{self.name}"
def get_default_install_dir(self) -> T.Union[T.Tuple[str, str], T.Tuple[None, None]]:
if self.bundle_type == BundleType.APPLICATION:
return self.environment.get_app_dir(), '{appdir}'
elif self.bundle_type == BundleType.FRAMEWORK:
return self.environment.get_framework_dir(), '{frameworkdir}'
else:
return (None, None)
def get_custom_install_dir(self) -> T.List[T.Union[str, Literal[False]]]:
return self.install_dir
def type_suffix(self) -> str:
if self.bundle_type == BundleType.APPLICATION:
return '@nsapp'
elif self.bundle_type == BundleType.FRAMEWORK:
return '@nsframework'
else:
return '@nsbundle'
@property
def typename(self) -> str:
if self.bundle_type == BundleType.APPLICATION:
return 'nsapp'
elif self.bundle_type == BundleType.FRAMEWORK:
return 'nsframework'
else:
return 'nsbundle'
def get_bundle_info(self) -> BundleInfo:
return self.bundle_info
def get_bundle_type(self) -> BundleType:
return self.bundle_type
def get_executable_name(self) -> str:
return self.main_exe.get_filename()
def get_filename(self) -> str:
return self.bundle_info.get_wrapper_name()
def can_output_be_directory(self, output: str) -> bool:
return output == self.get_filename()
def get_outputs(self) -> T.List[str]:
return [self.get_filename()]
@dataclass(eq=False)
class CustomTargetIndex(CustomTargetBase, HoldableObject):

@ -433,6 +433,7 @@ class Interpreter(InterpreterBase, HoldableObject):
build.Jar: OBJ.JarHolder,
build.AppBundle: OBJ.AppBundleHolder,
build.FrameworkBundle: OBJ.FrameworkBundleHolder,
build.BundleTarget: OBJ.BundleTargetHolder,
build.CustomTarget: OBJ.CustomTargetHolder,
build.CustomTargetIndex: OBJ.CustomTargetIndexHolder,
build.Generator: OBJ.GeneratorHolder,
@ -489,7 +490,7 @@ class Interpreter(InterpreterBase, HoldableObject):
for v in invalues:
if isinstance(v, ObjectHolder):
raise InterpreterException('Modules must not return ObjectHolders')
if isinstance(v, (build.BuildTarget, build.CustomTarget, build.RunTarget)):
if isinstance(v, (build.BuildTarget, build.CustomTarget, build.RunTarget, build.BundleTarget)):
self.add_target(v.name, v)
elif isinstance(v, list):
self.process_new_values(v)

@ -1041,6 +1041,9 @@ class AppBundleHolder(BuildTargetHolder[build.AppBundle]):
class FrameworkBundleHolder(BuildTargetHolder[build.FrameworkBundle]):
pass
class BundleTargetHolder(ObjectHolder[build.BundleTarget]):
pass
class CustomTargetIndexHolder(ObjectHolder[build.CustomTargetIndex]):
def __init__(self, target: build.CustomTargetIndex, interp: 'Interpreter'):
super().__init__(target, interp)

@ -6,15 +6,52 @@ from __future__ import annotations
import typing as T
from . import NewExtensionModule, ModuleInfo, ModuleReturnValue
from mesonbuild import build, dependencies
from mesonbuild.build import AppBundle, FrameworkBundle
from mesonbuild.interpreter.type_checking import NSAPP_KWS, NSFRAMEWORK_KWS, SOURCES_VARARGS
from mesonbuild.interpreterbase.decorators import FeatureNew, typed_kwargs, typed_pos_args
from mesonbuild.interpreter.type_checking import KwargInfo, NoneType, NSAPP_KWS, NSFRAMEWORK_KWS, SOURCES_VARARGS
from mesonbuild.interpreterbase.decorators import ContainerTypeInfo, FeatureNew, typed_kwargs, typed_pos_args
from mesonbuild.nsbundle import BundleType
if T.TYPE_CHECKING:
from typing_extensions import TypedDict
from . import ModuleState
from mesonbuild.interpreter.type_checking import SourcesVarargsType
from mesonbuild.interpreter import Interpreter, kwargs as kwtypes
class CommonKws(TypedDict):
contents: T.Optional[build.StructuredSources]
resources: T.Optional[build.StructuredSources]
extra_binaries: T.List[T.Union[str, build.File, build.Executable, build.CustomTarget, build.CustomTargetIndex]]
info_plist: T.Optional[T.Union[str, build.File, build.CustomTarget, build.CustomTargetIndex]]
class ApplicationKws(CommonKws):
layout: T.Optional[str]
executable_folder_name: T.Optional[str]
class FrameworkKws(CommonKws):
headers: T.Optional[build.StructuredSources]
COMMON_KWS: T.List[KwargInfo] = [
KwargInfo('contents', (NoneType, build.StructuredSources)),
KwargInfo('resources', (NoneType, build.StructuredSources)),
KwargInfo('extra_binaries', ContainerTypeInfo(list, (str, build.File, build.Executable, build.CustomTarget,
build.CustomTargetIndex)), default=[], listify=True),
KwargInfo('info_plist', (NoneType, str, build.File, build.CustomTarget, build.CustomTargetIndex))
]
APPLICATION_KWS: T.List[KwargInfo] = [
*COMMON_KWS,
KwargInfo('layout', (NoneType, str)),
KwargInfo('executable_folder_name', (NoneType, str)),
]
FRAMEWORK_KWS: T.List[KwargInfo] = [
*COMMON_KWS,
KwargInfo('headers', (NoneType, build.StructuredSources)),
]
def initialize(*args: T.Any, **kwargs: T.Any) -> NSBundleModule:
return NSBundleModule(*args, **kwargs)
@ -28,6 +65,8 @@ class NSBundleModule(NewExtensionModule):
self.methods.update({
'application': self.application,
'framework': self.framework,
'wrap_application': self.wrap_application,
'wrap_framework': self.wrap_framework,
})
@FeatureNew('nsbundle.application', '1.7.99')
@ -45,3 +84,35 @@ class NSBundleModule(NewExtensionModule):
) -> ModuleReturnValue:
tgt = state.create_build_target(FrameworkBundle, args, kwargs)
return ModuleReturnValue(tgt, [tgt])
@FeatureNew('nsbundle.wrap_application', '1.7.99')
@typed_pos_args('nsbundle.wrap_application', build.Executable)
@typed_kwargs('nsbundle.wrap_application', *APPLICATION_KWS)
def wrap_application(self, state: ModuleState, args: T.Tuple[build.Executable], kwargs: ApplicationKws
) -> ModuleReturnValue:
(main_exe,) = args
tgt = build.BundleTarget(main_exe.name, state.subdir, state.subproject, state.environment, main_exe, BundleType.APPLICATION)
tgt.bundle_info.resources = kwargs['resources']
tgt.bundle_info.contents = kwargs['contents']
tgt.bundle_info.extra_binaries = kwargs['extra_binaries']
if kwargs['info_plist'] is not None:
tgt.bundle_info.info_dict_file = build._source_input_to_file(tgt, 'info_plist', kwargs['info_plist'])
return ModuleReturnValue(tgt, [tgt])
@FeatureNew('nsbundle.wrap_framework', '1.7.99')
@typed_pos_args('nsbundle.wrap_framework', (build.SharedLibrary, dependencies.InternalDependency))
@typed_kwargs('nsbundle.wrap_framework', *FRAMEWORK_KWS)
def wrap_framework(self, state: ModuleState,
args: T.Tuple[T.Union[build.SharedLibrary, dependencies.InternalDependency]],
kwargs: FrameworkKws) -> ModuleReturnValue:
(main_lib,) = args
# TODO
if not isinstance(main_lib, dependencies.InternalDependency):
main_lib = dependencies.InternalDependency(state.project_version, [], [], [], [main_lib], [], [], [], [],
{}, [], [], [])
return ModuleReturnValue(main_lib, [])

Loading…
Cancel
Save