Repository: pyinstaller/pyinstaller

Issue:
inconsistencies for Darwin in v4.4 leads to Bad CPU type in executable 
<!--
Welcome to the PyInstaller issue tracker! Before creating an issue, please heed the following:

1. This tracker should only be used to report bugs and request features / enhancements to PyInstaller
    - For questions and general support, use the mailing list, see
	  <http://www.pyinstaller.org/support.html#mailing-list>
2. Use the search function before creating a new issue. Duplicates will be closed and directed to
   the original discussion.
3. When making a bug report, make sure you provide all required information. The easier it is for
   maintainers to reproduce, the faster it'll be fixed.
-->

<!-- +++ ONLY TEXT +++ DO NOT POST IMAGES +++ -->

## Description of the issue
pyinstaller chooses wrong architecture on darwin/arm64. `Bad CPU type in executable` error messages due to pyinstaller trying to run `arm64` python interpreter as `amd64` binary.

### Context information (for bug reports)

* Output of `pyinstaller --version`: ```4.4```
* Version of Python: 3.9.6
* Platform: OS X (Darwin/arm64)
* How you installed Python: macports

### A minimal example program which shows the error

hello.py:
```
import urllib3
print("Hello world!")
```

### Stacktrace / full error message

When running `pyinstaller hello.py`:
```
22 INFO: PyInstaller: 4.4
22 INFO: Python: 3.9.6
28 INFO: Platform: macOS-11.4-arm64-arm-64bit
29 INFO: wrote /private/tmp/bla/hello.spec
31 INFO: UPX is not available.
32 INFO: Extending PYTHONPATH with paths
['/private/tmp/bla', '/private/tmp/bla']
35 INFO: checking Analysis
35 INFO: Building Analysis because Analysis-00.toc is non existent
35 INFO: Initializing module dependency graph...
36 INFO: Caching module graph hooks...
39 INFO: Analyzing base_library.zip ...
arch: posix_spawnp: /opt/local/bin/python3.9: Bad CPU type in executable
arch: posix_spawnp: /opt/local/bin/python3.9: Bad CPU type in executable
1077 INFO: Processing pre-find module path hook distutils from '/Users/nopid/Library/Python/3.9/lib/python/site-packages/PyInstaller/hooks/pre_find_module_path/hook-distutils.py'.
1078 INFO: distutils: retargeting to non-venv dir '/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9'
2357 INFO: Caching module dependency graph...
2402 INFO: running Analysis Analysis-00.toc
2407 INFO: Analyzing /private/tmp/bla/hello.py
2468 INFO: Processing pre-safe import module hook urllib3.packages.six.moves from '/Users/nopid/Library/Python/3.9/lib/python/site-packages/PyInstaller/hooks/pre_safe_import_module/hook-urllib3.packages.six.moves.py'.
arch: posix_spawnp: /opt/local/bin/python3.9: Bad CPU type in executable
pre-safe-import-module hook failed, needs fixing.
```

### bugfix
The problem comes from inconsistencies in between `_shared_with_waf.py` and `compat.py`

The first one assumes `machine` should be `None`:
https://github.com/pyinstaller/pyinstaller/blob/6ab2c07cb1638ce0f84dfb181c2a9750a82d97b1/PyInstaller/_shared_with_waf.py#L56-L66

The second one tests `machine` against `arm` to decide to execute as `arm64` or as `amd64`:
https://github.com/pyinstaller/pyinstaller/blob/6ab2c07cb1638ce0f84dfb181c2a9750a82d97b1/PyInstaller/compat.py#L523-L528

Replacing line https://github.com/pyinstaller/pyinstaller/blob/6ab2c07cb1638ce0f84dfb181c2a9750a82d97b1/PyInstaller/_shared_with_waf.py#L56
with
```
if system != "Linux" and system != "Darwin":
```
fixes the problem.


Discussion:
`compat.machine` is only supposed to be used in the bootloader's filename. And because the macOS bootloaders are dual arch, we intentionally want `compat.machine` to always be None on mac so that the derived path to the bootloaders is unchanged.

> if system != "Linux" and system != "Darwin":

Surely this will then break later on because it'll look for the bootloaders in `PyInstaller/bootloader/Darwin-64bit-arm` which won't exist? Or did you move them or recompile them?

I'd have thought that the fix should be to replace:
https://github.com/pyinstaller/pyinstaller/blob/6ab2c07cb1638ce0f84dfb181c2a9750a82d97b1/PyInstaller/compat.py#L525
with:
```python
    if platform.machine() == "arm64":
```
Yours is certainly better. It works with my quick patch because of https://github.com/pyinstaller/pyinstaller/blob/6ab2c07cb1638ce0f84dfb181c2a9750a82d97b1/PyInstaller/__init__.py#L69-L74

Ah yes, well spotted. I forgot we had that second, previously redundant condition in place to ensure that the machine never makes it into the bootloader path on mac.

Resolving patch:
diff --git a/PyInstaller/compat.py b/PyInstaller/compat.py
--- a/PyInstaller/compat.py
+++ b/PyInstaller/compat.py
@@ -522,7 +522,7 @@ def __wrap_python(args, kwargs):
     # It is necessary to run binaries with 'arch' command.
     if is_darwin:
         if architecture == '64bit':
-            if machine == 'arm':
+            if platform.machine() == 'arm64':
                 py_prefix = ['arch', '-arm64']  # Apple M1
             else:
                 py_prefix = ['arch', '-x86_64']  # Intel


Test patch: