Skip to main content
This guide covers the complete process of building meikipop from source, including creating standalone executables for distribution.

Prerequisites

Before building, ensure you have:
1
Development environment
2
Complete the development setup first, including:
3
  • Python 3.10+
  • All dependencies from requirements.txt
  • Dictionary file (jmdict_enhanced.pkl)
  • 4
    Verify the app works
    5
    Test that meikipop runs correctly from source:
    6
    python -m src.main
    
    7
    Make sure you can:
    8
  • See the system tray icon
  • Trigger OCR with the hotkey
  • See dictionary popups
  • Running from source

    For development and testing, always run meikipop as a module:
    python -m src.main
    pause
    
    The project includes convenience scripts:
    • meikipop.run.bat (Windows) - Runs from source
    • meikipop.install.bat (Windows) - Installs dependencies

    Building executables with PyInstaller

    Meikipop uses PyInstaller to create standalone executables that bundle Python and all dependencies into a single file.

    Install PyInstaller

    pip install pyinstaller
    

    Understanding the spec files

    Meikipop includes platform-specific PyInstaller spec files that configure the build process:
    • meikipop.win.x64.spec - Windows 64-bit
    • meikipop.linux.x64.spec - Linux 64-bit

    Windows spec file breakdown

    Here’s the meikipop.win.x64.spec configuration:
    a = Analysis(
        ['src\\main.py'],              # Entry point
        pathex=[],
        binaries=[],
        datas=[
            # OCR provider modules (dynamically loaded)
            ('src/ocr/providers/glensv2/provider.py', 'src/ocr/providers/glensv2'),
            ('src/ocr/providers/owocr/provider.py', 'src/ocr/providers/owocr'),
            ('src/ocr/providers/meikiocr/provider.py', 'src/ocr/providers/meikiocr'),
            ('src/ocr/providers/screenai/provider.py', 'src/ocr/providers/screenai'),
            # ... (supporting files for each provider)
            
            # Application icons
            ('src/resources/icon.ico', '.'),
            ('src/resources/icon.ico', 'src/resources'),
            ('src/resources/icon.inactive.ico', '.'),
            ('src/resources/icon.inactive.ico', 'src/resources'),
        ],
        hiddenimports=[
            'src.ocr.providers.glensv2',
            'src.ocr.providers.owocr',
            'src.ocr.providers.meikiocr',
            'src.ocr.providers.screenai'
        ],
        # ... other settings
    )
    
    OCR providers are included as data files because they’re discovered dynamically at runtime using importlib. Without explicit inclusion, PyInstaller would miss them.

    Executable configuration

    exe = EXE(
        pyz,
        a.scripts,
        a.binaries,
        a.datas,
        [],
        name='meikipop',               # Output filename
        debug=False,                    # No debug console
        bootloader_ignore_signals=False,
        strip=False,                    # Don't strip symbols
        upx=True,                       # Compress with UPX
        upx_exclude=[],
        icon='src\\resources\\icon.ico',  # Executable icon
        runtime_tmpdir=None,
        console=True,                   # Show console window (for logging)
        # ... other settings
    )
    

    Build process

    1
    Open terminal in project directory
    2
    Navigate to the meikipop root folder.
    3
    Run PyInstaller with the spec file
    4
    pyinstaller meikipop.win.x64.spec
    
    5
    This creates:
    6
  • build/ - Temporary build files
  • dist/meikipop.exe - The final executable
  • 7
    Copy required data files
    8
    The executable needs the dictionary file:
    9
    # Create a distribution folder
    mkdir meikipop-windows-x64
    copy dist\meikipop.exe meikipop-windows-x64\
    mkdir meikipop-windows-x64\data
    copy data\jmdict_enhanced.pkl meikipop-windows-x64\data\
    
    10
    Test the executable
    11
    cd meikipop-windows-x64
    meikipop.exe
    

    Distribution package structure

    A complete distribution should include:
    meikipop-{platform}-x64/
    ├── meikipop.exe (or meikipop)    # The executable
    ├── data/
    │   └── jmdict_enhanced.pkl        # Dictionary (required!)
    ├── README.txt                     # Usage instructions
    └── LICENSE                        # GPL v3.0 license
    
    The executable will not work without jmdict_enhanced.pkl in the data/ subdirectory. The app will exit with “Failed to load dictionary” error.

    Build optimization

    Reducing executable size

    The default build can be quite large (100+ MB). To optimize:
    1
    Enable UPX compression
    2
    UPX is already enabled in the spec files:
    3
    upx=True,
    upx_exclude=[],
    
    4
    Install UPX for your platform:
    5
  • Windows: Download from upx.github.io and add to PATH
  • Linux: sudo apt-get install upx or sudo pacman -S upx
  • 6
    Exclude unnecessary modules
    7
    Add to the excludes list in your spec file:
    8
    excludes=['tkinter', 'matplotlib', 'numpy', 'scipy'],
    
    9
    Remove unused OCR providers
    10
    If you only need specific OCR providers, remove unused ones from:
    11
  • datas=[] list
  • hiddenimports=[] list
  • src/ocr/providers/ directory
  • Troubleshooting builds

    A module wasn’t included in the build. Check:
    1. Is it in hiddenimports in the spec file?
    2. Are there any dynamically imported modules?
    Add missing imports to hiddenimports:
    hiddenimports=['missing.module.name'],
    
    Icons aren’t being bundled correctly. Verify the datas section includes:
    datas=[
        ('src/resources/icon.ico', '.'),
        ('src/resources/icon.ico', 'src/resources'),
    ],
    
    And ensure the icon files exist in src/resources/.
    OCR provider modules weren’t included as data files. The spec must include:
    1. All .py files in datas list
    2. Provider packages in hiddenimports list
    See the Windows spec file for the complete list.
    The executable can’t find jmdict_enhanced.pkl. Make sure:
    1. The data/ folder exists next to the executable
    2. jmdict_enhanced.pkl is inside data/
    3. The file has read permissions
    Common causes:
    • ONNX runtime version mismatch (pinned to 1.20.1 for Windows)
    • Missing Visual C++ Redistributables
    Try:
    # Reinstall onnxruntime
    pip uninstall onnxruntime
    pip install onnxruntime==1.20.1
    
    # Rebuild
    pyinstaller --clean meikipop.win.x64.spec
    
    The executable was built on a system with different library versions. PyInstaller bundles libraries, but sometimes they conflict.Solutions:
    • Build on the oldest Linux version you want to support
    • Or build in a Docker container with specific library versions

    Advanced: Custom builds

    Adding custom OCR providers

    If you’ve created a custom OCR provider, include it in the build:
    1
    Add provider files to datas
    2
    datas=[
        # Your custom provider
        ('src/ocr/providers/myprovider/provider.py', 'src/ocr/providers/myprovider'),
        ('src/ocr/providers/myprovider/__init__.py', 'src/ocr/providers/myprovider'),
    ],
    
    3
    Add to hiddenimports
    4
    hiddenimports=['src.ocr.providers.myprovider'],
    
    5
    Include provider dependencies
    6
    If your provider has external dependencies (models, configs), add them:
    7
    datas=[
        ('src/ocr/providers/myprovider/model.onnx', 'src/ocr/providers/myprovider'),
    ],
    

    Building with debug logging

    For troubleshooting, enable console output:
    exe = EXE(
        # ...
        console=True,      # Keep console window open
        debug=True,        # Enable debug output
        # ...
    )
    

    Creating distributable archives

    Once you have a working build, create an archive for distribution:
    # Create a ZIP archive
    tar -a -c -f meikipop-windows-x64.zip meikipop-windows-x64
    

    Next steps

    After building:
    • Test on a clean system without Python installed
    • Verify all OCR providers work
    • Check the system tray and settings dialog
    • Test with different hotkey configurations
    • Distribute to users!
    For official releases, builds should be created on GitHub Actions to ensure reproducibility and consistency across platforms.

    Build docs developers (and LLMs) love