Repository: mesonbuild/meson

Issue:
host_machine.cpu() on armv6 differs between FreeBSD and Linux
On FreeBSD a number of architectures have different values for `uname -m` (aka`platform.machine()`)  and `uname -p` (aka `platform.processor()`). Some (e.g., `arm64`, `powerpc`) have workarounds but many don't.
```
$ make targets -C /usr/src | awk -F/ '$1 !~ $2'
Supported TARGET/TARGET_ARCH pairs for world and kernel targets
    arm/armv6
    arm/armv7
    arm64/aarch64
    mips/mipsel
    mips/mips64el
    mips/mips64
    mips/mipsn32
    mips/mipselhf
    mips/mipshf
    mips/mips64elhf
    mips/mips64hf
    powerpc/powerpc64
    powerpc/powerpcspe
    riscv/riscv64
```

For example, a project may want to add `-march=armv7-a` only to armv6 or lower because  `-march=` on armv7 or 32-bit armv8 may not be a good idea.

```
$ cc --version
FreeBSD clang version 6.0.1 (tags/RELEASE_601/final 335540) (based on LLVM 6.0.1)
Target: armv6-unknown-freebsd12.0-gnueabihf
Thread model: posix
InstalledDir: /usr/bin

$ meson _build
[...]
Build machine cpu family: arm
Build machine cpu: arm
Compiler for C supports arguments -mfpu=neon: YES
Message: neon_args = -mfpu=neon
[...]

$ cat meson.build
project('foo', 'c')

cc = meson.get_compiler('c')

# Excerpt from https://gitlab.freedesktop.org/mstoeckl/waypipe/blob/c341ce9d4c79/meson.build#L104-119
if host_machine.cpu_family() == 'aarch64' or cc.has_argument('-mfpu=neon')
	neon_args = host_machine.cpu_family() == 'aarch64' ? [] : ['-mfpu=neon']

	# Clang additionally enforces that NEON code only be compiled
	# to target a CPU that actually supports NEON instructions,
	# so bump the host CPU version for the optionally executed code only.
	if host_machine.cpu_family() == 'arm' and cc.get_id() == 'clang'
		host_cpu = host_machine.cpu()
		if host_cpu.contains('4') or host_cpu.contains('5') or host_cpu.contains('6')
			neon_args += ['-march=armv7-a']
		endif
	endif

	message('neon_args = ' + ' '.join(neon_args))
endif
```



Discussion:

Resolving patch:
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -215,33 +215,22 @@ def detect_cpu_family(compilers: CompilersDict) -> str:
     """
     if mesonlib.is_windows():
         trial = detect_windows_arch(compilers)
+    elif mesonlib.is_freebsd() or mesonlib.is_openbsd():
+        trial = platform.processor().lower()
     else:
         trial = platform.machine().lower()
     if trial.startswith('i') and trial.endswith('86'):
         trial = 'x86'
     elif trial == 'bepc':
         trial = 'x86'
-    # OpenBSD's 64 bit arm architecute identifies as 'arm64'
-    elif trial == 'arm64':
-        trial = 'aarch64'
     elif trial.startswith('arm'):
         trial = 'arm'
-    elif trial.startswith('ppc64'):
+    elif trial.startswith(('powerpc64', 'ppc64')):
         trial = 'ppc64'
-    elif trial == 'macppc':
+    elif trial.startswith(('powerpc', 'ppc')):
         trial = 'ppc'
-    elif trial == 'powerpc':
+    elif trial == 'macppc':
         trial = 'ppc'
-        # FreeBSD calls both ppc and ppc64 "powerpc".
-        # https://github.com/mesonbuild/meson/issues/4397
-        try:
-            p, stdo, _ = Popen_safe(['uname', '-p'])
-        except (FileNotFoundError, PermissionError):
-            # Not much to go on here.
-            if sys.maxsize > 2**32:
-                trial = 'ppc64'
-        if 'powerpc64' in stdo:
-            trial = 'ppc64'
     elif trial in ('amd64', 'x64', 'i86pc'):
         trial = 'x86_64'
 
@@ -271,6 +260,8 @@ def detect_cpu_family(compilers: CompilersDict) -> str:
 def detect_cpu(compilers: CompilersDict):
     if mesonlib.is_windows():
         trial = detect_windows_arch(compilers)
+    elif mesonlib.is_freebsd() or mesonlib.is_openbsd():
+        trial = platform.processor().lower()
     else:
         trial = platform.machine().lower()
     if trial in ('amd64', 'x64', 'i86pc'):


Test patch: