-
-
Save Kvnbbg/84871ae4d642c2dd896e0423471b1b52 to your computer and use it in GitHub Desktop.
| #!/bin/sh | |
| # References | |
| # https://www.pythonguis.com/tutorials/packaging-pyqt5-applications-pyinstaller-macos-dmg/ | |
| # https://medium.com/@jackhuang.wz/in-just-two-steps-you-can-turn-a-python-script-into-a-macos-application-installer-6e21bce2ee71 | |
| # --------------------------------------- | |
| # Clean up previous builds | |
| # --------------------------------------- | |
| echo "Cleaning up previous builds..." | |
| rm -rf build dist/* | |
| # --------------------------------------- | |
| # Step 1: Convert Python script to an application bundle | |
| # --------------------------------------- | |
| echo "Converting Python script to macOS app bundle..." | |
| # The following command will create a standalone .app from your Python script | |
| pyinstaller --name 'CryptoSafePDF' \ | |
| --icon 'CryptoSafePDF.ico' \ | |
| --windowed \ | |
| --add-data='./strong_beat.wav:.' \ | |
| --add-data='./sub_strong_beat.wav:.' \ | |
| --add-data='./weak_beat.wav:.' \ | |
| main.py | |
| # --------------------------------------- | |
| # Step 2: Convert the application bundle to a DMG (macOS disk image) | |
| # --------------------------------------- | |
| echo "Creating DMG installer..." | |
| # Prepare the folder for DMG creation | |
| mkdir -p dist/dmg | |
| rm -rf dist/dmg/* | |
| cp -r "dist/CryptoSafePDF.app" dist/dmg | |
| # Create the DMG | |
| # Ensure you have 'create-dmg' installed. If not, install using 'brew install create-dmg' | |
| create-dmg \ | |
| --volname "CryptoSafePDF" \ | |
| --volicon "CryptoSafePDF.ico" \ | |
| --window-pos 200 120 \ | |
| --window-size 600 300 \ | |
| --icon-size 100 \ | |
| --icon "CryptoSafePDF.app" 175 120 \ | |
| --hide-extension "CryptoSafePDF.app" \ | |
| --app-drop-link 425 120 \ | |
| "dist/CryptoSafePDF.dmg" \ | |
| "dist/dmg/" | |
| echo "Packaging complete. You can find the DMG installer in the dist/ directory." |
| #!/bin/bash | |
| # CryptoSafePDF Setup and Packaging Script for macOS | |
| # 1. Install Homebrew (if not installed) | |
| if ! command -v brew &>/dev/null; then | |
| echo "Installing Homebrew..." | |
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| else | |
| echo "Homebrew already installed." | |
| fi | |
| # 2. Install create-dmg | |
| if ! brew list create-dmg &>/dev/null; then | |
| echo "Installing create-dmg..." | |
| brew install create-dmg | |
| else | |
| echo "create-dmg already installed." | |
| fi | |
| # 3. Install pyinstaller | |
| if ! pip list | grep pyinstaller &>/dev/null; then | |
| echo "Installing pyinstaller..." | |
| pip install pyinstaller | |
| else | |
| echo "pyinstaller already installed." | |
| fi | |
| # 4. Clean up previous builds | |
| echo "Cleaning up previous builds..." | |
| rm -rf build dist/* | |
| # 5. Convert Python script to an application bundle | |
| echo "Converting Python script to macOS app bundle..." | |
| pyinstaller --name 'CryptoSafePDF' \ | |
| --icon 'CryptoSafePDF.ico' \ | |
| --windowed \ | |
| --add-data='./strong_beat.wav:.' \ | |
| --add-data='./sub_strong_beat.wav:.' \ | |
| --add-data='./weak_beat.wav:.' \ | |
| main.py | |
| # 6. Create the DMG installer | |
| echo "Creating DMG installer..." | |
| mkdir -p dist/dmg | |
| rm -rf dist/dmg/* | |
| cp -r "dist/CryptoSafePDF.app" dist/dmg | |
| create-dmg \ | |
| --volname "CryptoSafePDF" \ | |
| --volicon "CryptoSafePDF.ico" \ | |
| --window-pos 200 120 \ | |
| --window-size 600 300 \ | |
| --icon-size 100 \ | |
| --icon "CryptoSafePDF.app" 175 120 \ | |
| --hide-extension "CryptoSafePDF.app" \ | |
| --app-drop-link 425 120 \ | |
| "dist/CryptoSafePDF.dmg" \ | |
| "dist/dmg/" | |
| echo "Packaging complete. You can find the DMG installer in the dist/ directory." | |
To call and run installer.py from main.py, you can use one of the following methods:
-
Using the
execFunction:
This method allows you to execute a string as Python code. It's a straightforward way to run another Python script from within a script.# main.py with open('installer.py', 'r') as file: exec(file.read())
-
Using the
subprocessModule:
This method runs the script as a separate process. It's more versatile and allows for better control over the execution, capturing output, and error handling.# main.py import subprocess subprocess.run(["python", "installer.py"])
Note: Replace
pythonwithpython3if that's the command you use to run Python scripts on your system. -
Importing as a Module:
Ifinstaller.pyis structured in a way that allows it to be imported (i.e., it doesn't execute code when imported), you can simply import it and call its functions.# main.py import installer # Call functions from installer.py if needed
For this to work without modifications, you'd typically structure
installer.pywith a main guard:# installer.py def main(): # All the main code of installer.py if __name__ == "__main__": main()
Then, in
main.py, you can call themain()function ofinstaller.py:# main.py import installer installer.main()
Certainly! If
pyinstalleris causing issues, there are other tools and methods to package Python applications:cx_Freeze:
It's a set of scripts and modules for freezing Python scripts into executables in a manner similar to
pyinstaller,py2exe, etc.Install with:
Basic usage:
py2app (for macOS specifically):
It's a Python setuptools command which will allow you to make standalone macOS application bundles.
Install with:
Basic usage involves creating a
setup.pyscript:Then, run:
Briefcase:
This is a tool by the BeeWare project that packages Python projects as native apps. It has the advantage of supporting multiple platforms.
Install with:
Usage involves more steps as it's intended to be used with a full BeeWare application, but the BeeWare tutorial can guide you through it.
Docker:
While not a native packaging tool, Docker can help you create a containerized version of your application, ensuring it runs consistently across different environments. This would require the end-user to have Docker installed, though.
Remember: Each tool might have its peculiarities, and the packaging process might need adjustments depending on the complexity of your application, especially regarding dependencies, data files, and binary extensions.