fman works again on macOS Mojave
fman wouldn't start on macOS Mojave. I just released fman 1.6.9 that fixes this. Because of fman's auto-update mechanism, this caused problems for many people. I'm very sorry for the trouble.
Here's the back story: The latest version of macOS, Catalina, introduced a new requirement called Notarization for app developers. Basically, if you want to publish an application, then you need to send your binaries to Apple for verification before you can give it to your users. Otherwise, anybody who downloads your app gets a very ugly warning "this app needs to be updated by its developer".
To make fman ready for Catalina, I released version 1.6.7 a few days ago. It worked fine on my test systems running macOS Sierra, High Sierra, Mojave and Catalina. Unfortunately, it didn't work for quite a few of fman's users, particularly on Mojave.
The mistake I had made in notarizing fman was that I didn't supply an entitlements file. Here are the gory technical details in case you are a developer who found this page on Google:
fman is a PyQt application. When its users tried to start it on Mojave, the following error occurred. (You can see this by launching your app via the Terminal):
$ /Applications/fman.app/Contents/MacOS/fman Traceback (most recent call last): File "PyInstaller/loader/pyiboot01_bootstrap.py", line 127, inFile " ", line 971, in _find_and_load File " ", line 955, in _find_and_load_unlocked File " ", line 665, in _load_unlocked File ".../PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module File "ctypes/__init__.py", line 538, in File "ctypes/__init__.py", line 273, in _reset_cache MemoryError [13379] Failed to execute script pyiboot01_bootstrap
The fix for this is to supply an entitlements file when code signing your application. Here is the file which fman uses:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <!-- Avoid ctypes MemoryError: --> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/> <!-- Required for loading unsigned .so files from plugins: --> <key>com.apple.security.cs.disable-library-validation</key> <true/> </dict> </plist>
You save this to a file (say entitlements.plist
) and supply
it when invoking the codesign
command:
codesign ... --entitlements entitlements.plist ...
As you can see in the code comment above, the
allow-unsigned-executable-memory
is required to fix the
MemoryError
. In addition to this, fman requires the
disable-library-validation
entitlement. The reason for this
is that fman has a
plugin system and
plugins may load (unsigned) .so
library files. In
particular this entitlement fixes the following error, which I
encountered:
ImportError: dlopen(.../osxtrash.cpython-36m-darwin.so, 2): no suitable image found. Did find: .../osxtrash.cpython-36m-darwin.so: code signature in .../osxtrash.cpython-36m-darwin.so not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
Hopefully this helps someone else. If you are a PyQt developer, you may be interested in fman's build system. It hugely simplifies the deployment and packaging of PyQt apps.