Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mesonbuild/compilers/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> Rust
else:
linker = type(cc.linker)(compiler, for_machine, cc.LINKER_PREFIX,
always_args=always_args, version=cc.linker.version,
**extra_args)
**extra_args) # type: ignore
elif 'link' in override[0]:
linker = guess_win_linker(env,
override, cls, version, for_machine, use_linker_prefix=False)
Expand Down
4 changes: 2 additions & 2 deletions mesonbuild/envconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,9 @@ def is_linux(self) -> bool:

def is_darwin(self) -> bool:
"""
Machine is Darwin (iOS/tvOS/OS X)?
Machine is a Darwin kernel (macOS/iOS/tvOS/watchOS)?
"""
return self.system in {'darwin', 'ios', 'tvos'}
return self.system in {'darwin', 'ios', 'tvos', 'watchos'}

def is_android(self) -> bool:
"""
Expand Down
3 changes: 3 additions & 0 deletions mesonbuild/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,9 @@ def detect_cpu(compilers: CompilersDict) -> str:
'linux': 'linux',
'cygwin': 'nt',
'darwin': 'xnu',
'ios': 'xnu',
'tvos': 'xnu',
'watchos': 'xnu',
'dragonfly': 'dragonfly',
'haiku': 'haiku',
'gnu': 'gnu',
Expand Down
10 changes: 8 additions & 2 deletions mesonbuild/linkers/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,10 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
elif 'xtools-' in o.split('\n', maxsplit=1)[0]:
xtools = o.split(' ', maxsplit=1)[0]
v = xtools.split('-', maxsplit=2)[1]
linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
linker = linkers.AppleDynamicLinker(
compiler, for_machine, comp_class.LINKER_PREFIX, override,
system=env.machines[for_machine].system, version=v
)
# detect linker on MacOS - must be after other platforms because the
# "(use -v to see invocation)" will match clang on other platforms,
# but the rest of the checks will fail and call __failed_to_detect_linker.
Expand All @@ -241,7 +244,10 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty
break
else:
__failed_to_detect_linker(compiler, check_args, o, e)
linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)
linker = linkers.AppleDynamicLinker(
compiler, for_machine, comp_class.LINKER_PREFIX, override,
system=env.machines[for_machine].system, version=v
)
else:
__failed_to_detect_linker(compiler, check_args, o, e)
return linker
12 changes: 9 additions & 3 deletions mesonbuild/linkers/linkers.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,11 @@ def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]:

def __init__(self, exelist: T.List[str],
for_machine: mesonlib.MachineChoice, prefix_arg: T.Union[str, T.List[str]],
always_args: T.List[str], *, version: str = 'unknown version'):
always_args: T.List[str], *, system: str = 'unknown system',
version: str = 'unknown version'):
self.exelist = exelist
self.for_machine = for_machine
self.system = system
self.version = version
self.prefix_arg = prefix_arg
self.always_args = always_args
Expand Down Expand Up @@ -809,10 +811,14 @@ def get_asneeded_args(self) -> T.List[str]:
return self._apply_prefix('-dead_strip_dylibs')

def get_allow_undefined_args(self) -> T.List[str]:
return self._apply_prefix('-undefined,dynamic_lookup')
# iOS doesn't allow undefined symbols when linking
if self.system == 'ios':
return []
else:
return self._apply_prefix('-undefined,dynamic_lookup')

def get_std_shared_module_args(self, target: 'BuildTarget') -> T.List[str]:
return ['-dynamiclib'] + self._apply_prefix('-undefined,dynamic_lookup')
return ["-dynamiclib"] + self.get_allow_undefined_args()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change from single to double quotes looks unrelated (and we generally prefer single quotes)


def get_pie_args(self) -> T.List[str]:
return []
Expand Down
15 changes: 15 additions & 0 deletions mesonbuild/utils/universal.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class _VerPickleLoadable(Protocol):
'is_freebsd',
'is_haiku',
'is_hurd',
'is_ios',
'is_irix',
'is_linux',
'is_netbsd',
Expand All @@ -127,6 +128,8 @@ class _VerPickleLoadable(Protocol):
'is_parent_path',
'is_qnx',
'is_sunos',
'is_tvos',
'is_watchos',
'is_windows',
'is_wsl',
'iter_regexin_iter',
Expand Down Expand Up @@ -625,6 +628,18 @@ def is_osx() -> bool:
return platform.system().lower() == 'darwin'


def is_ios() -> bool:
return platform.system().lower() == 'ios'


def is_tvos() -> bool:
return platform.system().lower() == 'tvos'


def is_watchos() -> bool:
return platform.system().lower() == 'watchos'


Comment on lines +631 to +642
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run Meson on these platforms, ie, can you use ios, tvos, and watchos to compile? If the answer is no then these can never be correct, since they will always point at the build machine.

Side note: I'd really like to get rid of these because they often end up creating bugs for cross compilation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't run Meson on iOS, as there's no compiler tooling that is run on device. However, you can set up a cross platform build environment that pretends to be iOS, and I've successfully used that approach to build binary Python wheels for Pillow, Numpy, and a handful of other packages. It might be possible to build a full iOS app with Meson, but I haven't tried. My interest here is entirely tied to meson-python and the use of Meson in the Python ecosystem to manage the compilation of binary wheels.

I haven't tried using Meson with tvOS and watchOS, but the situation there will be much the same (i.e., cross compilation environments). I added entries for those platforms here because there are already references to tvOS and watchOS in other sections of the code, so I figured I'd retain the symmetry.

Copy link
Member

@eli-schwartz eli-schwartz Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could rephrase the question.

universal.py contains some logic for determining what operating system the meson application is running on. This is sometimes important to know how to interact with the operating system, to take one example we use mesonlib.is_windows() to determine whether ninja files need to use cmd /c, and in programs.py we use it to determine whether to add hacks for Windows Store Python or otherwise how to handle parsing shebang lines on platforms where simply execing a script may not actually work.

These are obvious cases where it doesn't matter what the build machine or host machine is. It's not about what we're compiling, it's about how we're communicating with the operating system / filesystem / task scheduler. And that much is a constant, even if I'm running on Windows (!) and rigged a cross platform build environment that identifies itself as FreeBSD (!!!). I still need to communicate with cmd, run del instead of rm, and use funny backwards paths that have drive letters but aren't my automobile that I used to drive to New York and attend a FreeBSD convention. (This analogy may have run away from me a bit at some point.)

For other purposes, it's probably not very useful to ask what the operating system platform is, but rather ask what the build machine and host machine claim to be. And that includes, what does the build machine masquerade as via running in a simulator such as wine or the iOS simulator or qemu-user.

We currently don't clearly separate these cases. We have a lot of code that queries mesonlib, rather than querying an interpreter env object. We should probably convert some of it, rather than adding more.

So, I guess the question to ask is, are there situations where we'd want to write new code in meson which asks "am I running the meson application on an iPhone and it's important to distinguish this from a MacBook"? Or do we just want to write new code that knows "we are natively building an iOS artifact" / "we are cross compiling an iOS artifact"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And since we aren't currently using these new functions, it's easy to defer the decision to add them until some other time, when someone comes up with a good reason why they definitely need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - I think I understand the intention; there's definitely a gap here in terms of identifying cross-platform build environments and differentiating the build and host environment, but that's way outside my pay grade :-)

FWIW, meson won't ever be running on an iOS device (or, if it is, it would be mostly pointless, because there's no compiler or ability to call subprocess). The situation on Android is a little different, but

But - I've gone back and checked my original usage, and it turns out I'm not actually using these methods anyway - all the practical usage is checking the env object. On that basis, I'll strip these methods out.

def is_linux() -> bool:
return platform.system().lower() == 'linux'

Expand Down
Loading