Mac Error Unknown Mach-O header with DLLs

18 views
Skip to first unread message

Timothy Breitenfeldt

unread,
Apr 14, 2020, 12:23:06 PM4/14/20
to PyInstaller
Hi, I am working on an application in python 3.7.6 using a library called accessible_output2. I was able to successfully create a Windows executable as a single file, however when I pulled out my mac and tried to build the application, I got this "Unknown Mach-O header" error. I included the full traceback and my .spec file below. The big issue is that accessible_output2 depends on a few DLLs to interface with Windows screen readers. Those DLLs are not necessary on Mac, however even if I do not include the DLLs in the binaries array in my spec file I am still getting this error that seems to be attempting to load the DLLs when the executable is created, at least based on the last line of the traceback.

Here is the traceback:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/bin/pyinstaller", line 8, in <module>
    sys.exit(run())
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/__main__.py", line 114, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/__main__.py", line 65, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 734, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 681, in build
    exec(code, spec_namespace)
  File "src/mtg.spec", line 25, in <module>
    noarchive=False)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 244, in __init__
    self.__postinit__()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/building/datastruct.py", line 160, in __postinit__
    self.assemble()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 470, in assemble
    redirects=self.binding_redirects))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/depend/bindepend.py", line 230, in Dependencies
    for lib, npth in selectImports(pth, xtrapath):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/depend/bindepend.py", line 501, in selectImports
    dlls = getImports(pth)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/depend/bindepend.py", line 742, in getImports
    return _getImports_macholib(pth)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/depend/bindepend.py", line 625, in _getImports_macholib
    m = MachO(pth)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/macholib/MachO.py", line 118, in __init__
    self.load(fp)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/macholib/MachO.py", line 133, in load
    self.load_header(fh, 0, size)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/macholib/MachO.py", line 167, in load_header
    raise ValueError("Unknown Mach-O header: 0x%08x in %r" % (header, fh))
ValueError: Unknown Mach-O header: 0x4d5a9000 in <_io.BufferedReader name='/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/accessible_output2/lib/nvdaControllerClient64.dll'>

The last line mentioning accessible_output2/lib/nvdaControllerClient64.dll, is one of the DLLs that accessible_output2 depends on. In my spec file you can see that I constructed a binaries array to include the DLLs for Windows, and an empty array is being passed for other platforms. I originally did try passing the constructed binaries array on all platforms, but I got the same error as above. I am only concerned with Windows and Mac.

Here is my spec file:

# -*- mode: python ; coding: utf-8 -*-
import os
import platform
block_cipher = None
binaries = []
if platform.system() == "Windows":
    binaries = [(os.path.join('accessible_output2', 'lib', 'nvdaControllerClient32.dll'), '.'), (os.path.join('accessible_output2', 'lib', 'nvdaControllerClient64.dll'), '.'),
                (os.path.join('accessible_output2', 'lib', 'dolapi.dll'), '.'), (os.path.join('accessible_output2', 'lib', 'PCTKUSR.dll'), '.'), (os.path.join('accessible_output2', 'lib', 'PCTKUSR64.dll'), '.'),
                (os.path.join('accessible_output2', 'lib', 'SAAPI32.dll'), '.')]
a = Analysis(['mtg.py'],
             pathex=[SPECPATH],
             binaries= binaries,
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='mtg',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False )

my command to run is:

pyinstaller mtg.spec

I have search everywhere for an answer for this problem, but have not found much. It looks like a ticket was opened for a similar issue, but there is no answer that helped me.


There was also this thread that mentioned this issue, but also no answer that helps me:


This is all that I could find on this problem, does anyone have any ideas how to deal with this issue?

Let me know if I need to include any more information.

Thanks,

Timothy Breitenfeldt

bwoodsend

unread,
Apr 15, 2020, 3:03:53 AM4/15/20
to PyInstaller
Well judging from these lines of the traceback:




  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/PyInstaller/depend/bindepend.py", line 625, in _getImports_macholib
    m = MachO(pth)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/macholib/MachO.py", line 118, in __init__
    self.load(fp)
 
It looks like PyInstaller has special support for MachO. But it's being overeager in trying to load the dll without noticing that it's condintionally used.


Ideally you would tell PyInstaller to exclude those dlls but the options for doing that is in the EXE call which is too late because your build is failing on the Analysis.
https://bitbucket.org/qsoft/accessible_output2/src/default/accessible_output2/__init__.py

On looking at the source code for accessable_output2's  __init__.py.

They have modularised it nicely so you can run the MacOS without touching the MachO stuff. So you can blacklist all the non MacOS submodules. In the Analysis in your spec put:

excludes=["accessible_output2.outputs.voiceover",
 "accessible_output2.outputs.jaws",
 "accessible_output2.outputs.sapi5",
 "accessible_output2.outputs.window_eyes",
 "accessible_output2.outputs.system_access",
 "accessible_output2.outputs.dolphin",
 "accessible_output2.outputs.pc_talker",]

Alternatively if you uninstall macholib temporarily that should also do it.


Eric Fahlgren

unread,
Apr 15, 2020, 3:05:38 AM4/15/20
to pyins...@googlegroups.com
I'd first try adding 'nvdaControllerClient64' to the excludes and see if that does anything.  I suspect it will just chase back to another error, but maybe chase them all back until you've trimmed the tree of pyd/dll/so files that are causing the issue?

--
You received this message because you are subscribed to the Google Groups "PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyinstaller...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyinstaller/9d1d3531-80c3-4046-87d0-c6e17a77eed2%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages