2022-09-08 17:19:20 -04:00
# objdiff [![Build Status]][actions]
[Build Status]: https://github.com/encounter/objdiff/actions/workflows/build.yaml/badge.svg
[actions]: https://github.com/encounter/objdiff/actions
2023-11-24 23:17:35 -05:00
A local diffing tool for decompilation projects. Inspired by [decomp.me ](https://decomp.me ) and [asm-differ ](https://github.com/simonlindholm/asm-differ ).
Features:
2024-09-09 19:34:50 -06:00
2025-08-30 23:56:46 -06:00
- Compare entire object files: functions and data
- Built-in C++ symbol demangling (GCC, MSVC, CodeWarrior, Itanium)
- Automatic rebuild on source file changes
- Project integration via [configuration file ](#configuration )
- Search and filter objects with quick switching
- Click-to-highlight values and registers
- Detailed progress reporting (powers [decomp.dev ](https://decomp.dev ))
- WebAssembly API, [web interface ](https://github.com/encounter/objdiff-web ) and [Visual Studio Code extension ](https://marketplace.visualstudio.com/items?itemName=decomp-dev.objdiff ) (WIP)
2022-09-08 17:19:20 -04:00
2023-08-12 14:18:09 -04:00
Supports:
2024-09-09 19:34:50 -06:00
2024-06-21 02:36:25 +02:00
- ARM (GBA, DS, 3DS)
2025-05-06 23:25:29 -06:00
- ARM64 (Switch)
- MIPS (N64, PS1, PS2, PSP)
2025-07-21 21:01:03 -06:00
- PowerPC (GameCube, Wii, PS3, Xbox 360)
2025-05-06 23:25:29 -06:00
- SuperH (Saturn, Dreamcast)
2025-06-17 13:03:14 -06:00
- x86, x86_64 (PC)
2022-09-08 17:19:20 -04:00
2023-08-12 14:18:09 -04:00
See [Usage ](#usage ) for more information.
2024-09-09 19:34:50 -06:00
## Downloads
To build from source, see [Building ](#building ).
### GUI
- [Windows (x86_64) ](https://github.com/encounter/objdiff/releases/latest/download/objdiff-windows-x86_64.exe )
- [Linux (x86_64) ](https://github.com/encounter/objdiff/releases/latest/download/objdiff-linux-x86_64 )
- [macOS (arm64) ](https://github.com/encounter/objdiff/releases/latest/download/objdiff-macos-arm64 )
- [macOS (x86_64) ](https://github.com/encounter/objdiff/releases/latest/download/objdiff-macos-x86_64 )
For Linux and macOS, run `chmod +x objdiff-*` to make the binary executable.
### CLI
2025-08-30 23:56:46 -06:00
CLI binaries are available on the [releases page ](https://github.com/encounter/objdiff/releases ).
2024-09-09 19:34:50 -06:00
## Screenshots
2022-09-08 19:46:19 -04:00


2022-09-08 17:19:20 -04:00
2023-08-12 14:18:09 -04:00
## Usage
2025-08-30 23:56:46 -06:00
objdiff compares two relocatable object files (`.o` ). Here's how it works:
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
1. **Create an `objdiff.json` configuration file ** in your project root (or generate it with your build script).
This file lists **all objects in the project ** with their target ("expected") and base ("current") paths.
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
2. **Load the project ** in objdiff.
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
3. **Select an object ** from the sidebar to begin diffing.
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
4. **objdiff automatically: **
- Executes the build system to compile the base object (from current source code)
- Compares the two objects and displays the differences
- Watches for source file changes and rebuilds when detected
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
The configuration file allows complete flexibility in project structure - your build directories can have any layout as long as the paths are specified correctly.
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
See [Configuration ](#configuration ) for setup details.
2023-08-12 14:18:09 -04:00
## Configuration
2025-08-30 23:56:46 -06:00
Projects can add an `objdiff.json` file to configure the tool automatically. The configuration file must be located in
2023-08-12 14:41:19 -04:00
the root project directory.
2025-08-30 23:56:46 -06:00
If your project has a generator script (e.g. `configure.py` ), it's highly recommended to generate the objdiff configuration
2023-08-12 14:41:19 -04:00
file as well. You can then add `objdiff.json` to your `.gitignore` to prevent it from being committed.
2023-08-12 14:18:09 -04:00
2024-09-03 20:48:45 -06:00
``` json
2023-08-12 14:18:09 -04:00
{
2024-09-03 20:48:45 -06:00
"$schema" : "https://raw.githubusercontent.com/encounter/objdiff/main/config.schema.json" ,
2023-08-12 14:18:09 -04:00
"custom_make" : "ninja" ,
2024-05-16 02:53:14 +02:00
"custom_args" : [
2024-05-15 19:01:55 -06:00
"-d" ,
"keeprsp"
2024-05-16 02:53:14 +02:00
] ,
2024-09-03 20:48:45 -06:00
"build_target" : false ,
"build_base" : true ,
2023-08-12 14:18:09 -04:00
"watch_patterns" : [
"*.c" ,
2025-08-23 17:37:34 -04:00
"*.cc" ,
2023-08-12 14:18:09 -04:00
"*.cp" ,
"*.cpp" ,
2024-09-03 20:48:45 -06:00
"*.cxx" ,
2025-08-23 17:37:34 -04:00
"*.c++" ,
2023-08-12 14:18:09 -04:00
"*.h" ,
2025-08-23 17:37:34 -04:00
"*.hh" ,
2024-09-03 20:48:45 -06:00
"*.hp" ,
2023-08-12 14:18:09 -04:00
"*.hpp" ,
2024-09-03 20:48:45 -06:00
"*.hxx" ,
2025-08-23 17:37:34 -04:00
"*.h++" ,
"*.pch" ,
"*.pch++" ,
"*.inc" ,
2024-09-03 20:48:45 -06:00
"*.s" ,
"*.S" ,
"*.asm" ,
"*.py" ,
"*.yml" ,
"*.txt" ,
"*.json"
2023-08-12 14:18:09 -04:00
] ,
2025-08-15 16:24:26 -06:00
"ignore_patterns" : [
"build/**/*"
] ,
2024-09-03 20:48:45 -06:00
"units" : [
2023-08-12 14:18:09 -04:00
{
2023-09-03 09:28:22 -04:00
"name" : "main/MetroTRK/mslsupp" ,
"target_path" : "build/asm/MetroTRK/mslsupp.o" ,
"base_path" : "build/src/MetroTRK/mslsupp.o" ,
2024-09-03 20:48:45 -06:00
"metadata" : { }
}
2023-08-12 14:18:09 -04:00
]
}
```
2024-09-03 20:48:45 -06:00
### Schema
2025-08-30 23:56:46 -06:00
> [!NOTE]
> View [config.schema.json](config.schema.json) for all available options. Below is a summary of the most important options.
2024-09-03 20:48:45 -06:00
2025-08-30 23:56:46 -06:00
#### Build Configuration
2024-05-15 19:01:55 -06:00
2025-08-30 23:56:46 -06:00
* * `custom_make` ** _ (optional, default: `"make"`) _
If the project uses a different build system (e.g. `ninja` ), specify it here. The build command will be `[custom_make] [custom_args] path/to/object.o` .
2023-09-03 09:28:22 -04:00
2025-08-30 23:56:46 -06:00
* * `custom_args` ** _ (optional) _
Additional arguments to pass to the build command prior to the object path.
2023-09-03 09:28:22 -04:00
2025-08-30 23:56:46 -06:00
* * `build_target` ** _ (default: `false`) _
If true, objdiff will build the target objects before diffing (e.g. `make path/to/target.o` ). Useful if target objects are not built by default or can change based on project configuration. Requires proper build system configuration.
2024-09-03 20:48:45 -06:00
2025-08-30 23:56:46 -06:00
* * `build_base` ** _ (default: `true`) _
If true, objdiff will build the base objects before diffing (e.g. `make path/to/base.o` ). It's unlikely you'll want to disable this unless using an external tool to rebuild the base object.
2023-09-03 09:28:22 -04:00
2025-08-30 23:56:46 -06:00
#### File Watching
2025-08-15 16:24:26 -06:00
2025-08-30 23:56:46 -06:00
* * `watch_patterns` ** _ (optional, default: listed above) _
A list of glob patterns to watch for changes ([supported syntax ](https://docs.rs/globset/latest/globset/#syntax )). When these files change, objdiff automatically rebuilds and re-compares objects.
2023-09-03 09:28:22 -04:00
2025-08-30 23:56:46 -06:00
* * `ignore_patterns` ** _ (optional, default: listed above) _
A list of glob patterns to explicitly ignore when watching for changes ([supported syntax ](https://docs.rs/globset/latest/globset/#syntax )).
#### Units (Objects)
* * `units` ** _ (optional) _
If specified, objdiff displays a list of objects in the sidebar for easy navigation. Each unit contains:
- **`name` ** _ (optional) _ - The display name in the UI. Defaults to the object's `path` .
- **`target_path` ** _ (optional) _ - Path to the "target" or "expected" object (the **intended result ** ).
- **`base_path` ** _ (optional) _ - Path to the "base" or "current" object (built from **current source code ** ). Omit if there is no source object yet.
- **`metadata.auto_generated` ** _ (optional) _ - Hides the object from the sidebar but includes it in progress reports.
- **`metadata.complete` ** _ (optional) _ - Marks the object as "complete" (linked) when `true` or "incomplete" when `false` .
2023-09-03 09:28:22 -04:00
2023-11-27 19:52:12 -05:00
## Building
2023-09-03 09:28:22 -04:00
2023-11-27 19:52:12 -05:00
Install Rust via [rustup ](https://rustup.rs ).
``` shell
2025-08-30 23:56:46 -06:00
git clone https://github.com/encounter/objdiff.git
cd objdiff
cargo run --release
2023-11-27 19:52:12 -05:00
```
2023-08-12 14:18:09 -04:00
2025-08-30 23:56:46 -06:00
Or install directly with cargo:
2024-09-09 21:38:06 -04:00
``` shell
2025-08-30 23:56:46 -06:00
cargo install --locked --git https://github.com/encounter/objdiff.git objdiff-gui objdiff-cli
2024-09-09 21:38:06 -04:00
```
2025-08-30 23:56:46 -06:00
Binaries will be installed to `~/.cargo/bin` as `objdiff` and `objdiff-cli` .
2024-09-09 19:41:29 -06:00
2025-08-30 23:56:46 -06:00
## Contributing
2025-03-18 21:25:50 -06:00
2025-08-30 23:56:46 -06:00
Install `pre-commit` to run linting and formatting automatically:
2025-03-18 21:25:50 -06:00
``` shell
2025-08-30 23:56:46 -06:00
rustup toolchain install nightly # Required for cargo fmt/clippy
cargo install --locked cargo-deny # https://github.com/EmbarkStudios/cargo-deny
uv tool install pre-commit # https://docs.astral.sh/uv, or use pipx or pip
pre-commit install
2025-03-18 21:25:50 -06:00
```
2023-08-12 14:18:09 -04:00
## License
2022-09-08 17:19:20 -04:00
Licensed under either of
2024-09-09 19:34:50 -06:00
- Apache License, Version 2.0, ([LICENSE-APACHE ](LICENSE-APACHE ) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT ](LICENSE-MIT ) or <http://opensource.org/licenses/MIT>)
2022-09-08 17:19:20 -04:00
at your option.
### Contribution
2023-08-12 14:41:19 -04:00
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as
defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.