esp-binary-pack 1.0.3
Extract compiled .a library files from ESP-IDF projects and generate binary-only projects
Requires Python: >=3.6
Keywords: esp-idf, esp32, binary, pack, embedded

# ESP-IDF Binary Pack

ESP-IDF Project Prebuilt Library Packaging Tool - Converts source code projects into prebuilt library projects.

## Features

- 📦 **Automatic Library Extraction**: Extracts `.a` library files from built ESP-IDF projects.
- 🔧 **Smart Component Classification**: Automatically identifies prebuilt components, managed components, etc.
- 🗂️ **Clear Directory Structure**: Separates prebuilt components from source components.
- 🔗 **Automatic Linking Configuration**: Generates correct `CMakeLists.txt` and manages dependencies.

## Directory Structure

The generated project contains the following directories:

```text
your_project_binary/
├── CMakeLists.txt              # Root configuration, automatically sets EXTRA_COMPONENT_DIRS
├── sdkconfig                   # SDK configuration
├── main/                       # Main directory (stub, links to prebuilt main)
│   ├── CMakeLists.txt
│   └── main.c
├── components/                 # Non-prebuilt components
│   ├── managed_component1/     # ESP Component Manager components (if not packed)
│   ├── excluded_component/     # Manually excluded components
│   └── prebuilt_component/     # Originally prebuilt components (already had .a)
└── prebuild_components/        # Prebuilt components generated by this tool
    ├── main/                   # main prebuilt library
    │   ├── CMakeLists.txt
    │   └── libmain.a
    ├── component1/
    │   ├── CMakeLists.txt
    │   └── libcomponent1.a
    └── component2/
        ├── CMakeLists.txt
        └── libcomponent2.a
```

## Usage

### 1. Build Original Project

```bash
cd your_project
idf.py build
```

### 2. Run Packaging Script

First, install the package:
```bash
pip install esp-binary-pack
```

Then run the tool using the `esp-binary-pack` command:

```bash
# Basic usage
esp-binary-pack

# Exclude components (keep as source)
esp-binary-pack --exclude comp1,comp2

# Specify output directory
esp-binary-pack --output-dir my_output

# Extract headers
esp-binary-pack --extract-headers

# Specify build directory (default is 'build')
esp-binary-pack --build-dir build_esp32s3

# Pack managed components as libraries
esp-binary-pack --pack-managed-components
```

### 3. Build Generated Project

```bash
cd your_project_binary
idf.py build
```

## Command Line Arguments

| Argument | Description | Default |
|----------|-------------|---------|
| `--exclude` | Components to exclude (comma separated), kept as source | - |
| `--include` | Components to force include (comma separated) | - |
| `--output-dir` | Output directory name | `{project_name}_binary` |
| `--idf-path` | Path to IDF_PATH | Read from environment |
| `--extract-headers` | Extract header files to include directory | false |
| `--build-dir` | Build directory to read from | `build` |
| `--pack-managed-components` | Pack managed components as libraries instead of copying source | false |

## Component Classification

The script automatically identifies and classifies components:

### 1. Prebuilt Components → `prebuild_components/`
- User components (non-ESP-IDF official).
- `.a` library files extracted by the script.
- Managed components if `--pack-managed-components` is enabled.

### 2. Source Components → `components/`
- **Managed Components**: From ESP Component Manager (if `--pack-managed-components` is disabled).
- **Excluded Components**: Specified via `--exclude`.
- **Original Prebuilt Components**: Components that were already prebuilt (contained `.a` files).
- **No-Lib Components**: Components where no corresponding `.a` file was found.

### 3. Main Component
- **Prebuilt (`prebuild_components/`)**: If the original project's `main` component is compiled (has a library file), it is placed in `prebuild_components/main/`. The `main/` directory will then contain a stub.
- **Source (`main/`)**: If the original project's `main` component is NOT compiled (no library file found), the original source component is kept in `main/`.

## Recent Updates

### 2026-01-11
- **Main Component Handling**: `libmain.a` is now placed in `prebuild_components/main/`, and the `main` directory contains a stub.
- **Directory Restructuring**: Managed components moved to `components/`, prebuilt libraries to `prebuild_components/`.
- **Auto Configuration**: `EXTRA_COMPONENT_DIRS` is automatically configured.

## File Exclusion Rules

When copying components as source, the following are automatically excluded:

| Pattern | Reason |
|---------|--------|
| `build/` | Build output directory |
| `.git/` | Version control |
| `*.o` | Compiled object files |
| `*.d` | Make dependency files |
| `*.pyc` | Python compiled files |
| `__pycache__/` | Python cache directory |
| `.DS_Store` | macOS system file |

**Note**: `.a` files are **not** excluded when copying source components, to preserve any original prebuilt libraries.

## Dependencies

- Python 3.6+
- ESP-IDF Environment
- Built ESP-IDF Project (requires `build/project_description.json`)

## Troubleshooting

### Issue: Library file not found for a component
**Solution**:
1. Ensure project is fully built: `idf.py build`.
2. Check if the component's library exists in `build/esp-idf/`.
3. Use `--exclude` to keep the component as source.

### Issue: Generated project fails to compile
**Solution**:
1. Check `EXTRA_COMPONENT_DIRS` in `CMakeLists.txt`.
2. Ensure all dependent components are included.
3. Check `components/` for missing managed components.

## License

MIT License