> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/rtr46/meikipop/llms.txt
> Use this file to discover all available pages before exploring further.

# Building from source

> Create standalone executables for meikipop using PyInstaller

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

## Prerequisites

Before building, ensure you have:

<Steps>
  ### Development environment

  Complete the [development setup](/development/development-setup) first, including:

  * Python 3.10+
  * All dependencies from `requirements.txt`
  * Dictionary file (`jmdict_enhanced.pkl`)

  ### Verify the app works

  Test that meikipop runs correctly from source:

  ```bash theme={null}
  python -m src.main
  ```

  Make sure you can:

  * See the system tray icon
  * Trigger OCR with the hotkey
  * See dictionary popups
</Steps>

## Running from source

For development and testing, always run meikipop as a module:

<CodeGroup>
  ```bash Windows theme={null}
  python -m src.main
  pause
  ```

  ```bash Linux/macOS theme={null}
  python3 -m src.main
  ```
</CodeGroup>

<Info>
  The project includes convenience scripts:

  * `meikipop.run.bat` (Windows) - Runs from source
  * `meikipop.install.bat` (Windows) - Installs dependencies
</Info>

## Building executables with PyInstaller

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

### Install PyInstaller

```bash theme={null}
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:

```python theme={null}
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
)
```

<Note>
  OCR providers are included as data files because they're discovered dynamically at runtime using `importlib`. Without explicit inclusion, PyInstaller would miss them.
</Note>

#### Executable configuration

```python theme={null}
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

<Tabs>
  <Tab title="Windows">
    <Steps>
      ### Open terminal in project directory

      Navigate to the meikipop root folder.

      ### Run PyInstaller with the spec file

      ```bash theme={null}
      pyinstaller meikipop.win.x64.spec
      ```

      This creates:

      * `build/` - Temporary build files
      * `dist/meikipop.exe` - The final executable

      ### Copy required data files

      The executable needs the dictionary file:

      ```bash theme={null}
      # 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\
      ```

      ### Test the executable

      ```bash theme={null}
      cd meikipop-windows-x64
      meikipop.exe
      ```
    </Steps>
  </Tab>

  <Tab title="Linux">
    <Steps>
      ### Open terminal in project directory

      Navigate to the meikipop root folder.

      ### Run PyInstaller with the spec file

      ```bash theme={null}
      pyinstaller meikipop.linux.x64.spec
      ```

      This creates:

      * `build/` - Temporary build files
      * `dist/meikipop` - The final executable

      ### Copy required data files

      The executable needs the dictionary file:

      ```bash theme={null}
      # Create a distribution folder
      mkdir -p meikipop-linux-x64/data
      cp dist/meikipop meikipop-linux-x64/
      cp data/jmdict_enhanced.pkl meikipop-linux-x64/data/
      chmod +x meikipop-linux-x64/meikipop
      ```

      ### Test the executable

      ```bash theme={null}
      cd meikipop-linux-x64
      ./meikipop
      ```
    </Steps>
  </Tab>

  <Tab title="macOS">
    <Warning>
      There's currently no official macOS spec file. macOS builds are experimental. You can adapt the Linux spec file, but expect issues with the system tray and permissions.
    </Warning>

    For macOS, it's recommended to run from source:

    ```bash theme={null}
    python3 -m src.main
    ```
  </Tab>
</Tabs>

## 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
```

<Warning>
  The executable will not work without `jmdict_enhanced.pkl` in the `data/` subdirectory. The app will exit with "Failed to load dictionary" error.
</Warning>

## Build optimization

### Reducing executable size

The default build can be quite large (100+ MB). To optimize:

<Steps>
  ### Enable UPX compression

  UPX is already enabled in the spec files:

  ```python theme={null}
  upx=True,
  upx_exclude=[],
  ```

  Install UPX for your platform:

  * **Windows**: Download from [upx.github.io](https://upx.github.io/) and add to PATH
  * **Linux**: `sudo apt-get install upx` or `sudo pacman -S upx`

  ### Exclude unnecessary modules

  Add to the `excludes` list in your spec file:

  ```python theme={null}
  excludes=['tkinter', 'matplotlib', 'numpy', 'scipy'],
  ```

  ### Remove unused OCR providers

  If you only need specific OCR providers, remove unused ones from:

  * `datas=[]` list
  * `hiddenimports=[]` list
  * `src/ocr/providers/` directory
</Steps>

## Troubleshooting builds

<AccordionGroup>
  <Accordion title="ImportError when running executable">
    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`:

    ```python theme={null}
    hiddenimports=['missing.module.name'],
    ```
  </Accordion>

  <Accordion title="FileNotFoundError: icon.ico">
    Icons aren't being bundled correctly. Verify the `datas` section includes:

    ```python theme={null}
    datas=[
        ('src/resources/icon.ico', '.'),
        ('src/resources/icon.ico', 'src/resources'),
    ],
    ```

    And ensure the icon files exist in `src/resources/`.
  </Accordion>

  <Accordion title="No OCR providers found!">
    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.
  </Accordion>

  <Accordion title="RuntimeError: Failed to load dictionary">
    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
  </Accordion>

  <Accordion title="Executable crashes on startup (Windows)">
    Common causes:

    * ONNX runtime version mismatch (pinned to 1.20.1 for Windows)
    * Missing Visual C++ Redistributables

    Try:

    ```bash theme={null}
    # Reinstall onnxruntime
    pip uninstall onnxruntime
    pip install onnxruntime==1.20.1

    # Rebuild
    pyinstaller --clean meikipop.win.x64.spec
    ```
  </Accordion>

  <Accordion title="Linux: error while loading shared libraries">
    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
  </Accordion>
</AccordionGroup>

## Advanced: Custom builds

### Adding custom OCR providers

If you've created a [custom OCR provider](/development/creating-custom-provider), include it in the build:

<Steps>
  ### Add provider files to datas

  ```python theme={null}
  datas=[
      # Your custom provider
      ('src/ocr/providers/myprovider/provider.py', 'src/ocr/providers/myprovider'),
      ('src/ocr/providers/myprovider/__init__.py', 'src/ocr/providers/myprovider'),
  ],
  ```

  ### Add to hiddenimports

  ```python theme={null}
  hiddenimports=['src.ocr.providers.myprovider'],
  ```

  ### Include provider dependencies

  If your provider has external dependencies (models, configs), add them:

  ```python theme={null}
  datas=[
      ('src/ocr/providers/myprovider/model.onnx', 'src/ocr/providers/myprovider'),
  ],
  ```
</Steps>

### Building with debug logging

For troubleshooting, enable console output:

```python theme={null}
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:

<CodeGroup>
  ```bash Windows theme={null}
  # Create a ZIP archive
  tar -a -c -f meikipop-windows-x64.zip meikipop-windows-x64
  ```

  ```bash Linux theme={null}
  # Create a tarball
  tar -czf meikipop-linux-x64.tar.gz meikipop-linux-x64/
  ```
</CodeGroup>

## 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!

<Tip>
  For official releases, builds should be created on GitHub Actions to ensure reproducibility and consistency across platforms.
</Tip>
