Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,37 @@ jobs:
with:
command: check ${{ matrix.checks }}

nix:
name: Nix (${{ matrix.system }})
strategy:
matrix:
include:
- system: x86_64-linux
runner: ubuntu-24.04
- system: aarch64-linux
runner: ubuntu-24.04-arm
fail-fast: false
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Free disk space for the Nix store
uses: wimpysworld/nothing-but-nix@v9
- name: Install Nix
uses: cachix/install-nix-action@v31
- name: Restore and save Nix store
uses: nix-community/cache-nix-action@v7
with:
primary-key: nix-${{ matrix.system }}-${{ hashFiles('flake.lock', '**/*.nix', 'Cargo.toml', 'Cargo.lock') }}
restore-prefixes-first-match: nix-${{ matrix.system }}-
gc-max-store-size-linux: 5G
- name: Evaluate flake
run: nix flake check --no-build
- name: Build packages
run: nix build .#objdiff .#objdiff-cli --print-build-logs
- name: Check development shell
run: nix develop --command cargo +nightly --version

test:
name: Test
strategy:
Expand Down
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,37 @@ If specified, objdiff displays a list of objects in the sidebar for easy navigat

## Building

### Nix (Linux)

The flake supports `x86_64-linux` and `aarch64-linux`. Run the GUI or CLI directly:

```shell
nix run .
nix run .#objdiff-cli -- --help
```

Build or install either frontend:

```shell
nix build .#objdiff
nix build .#objdiff-cli
nix profile install .#objdiff
nix profile install .#objdiff-cli
```

Enter the development shell for Rust, Node.js, the WASM toolchain, and the contribution tools:

```shell
nix develop
cargo test
npm -C objdiff-wasm run build
```

The Nix GUI package disables the built-in self-updater because its executable is immutable. Update it
through Nix instead.

### Cargo

Install Rust via [rustup](https://rustup.rs).

```shell
Expand Down
48 changes: 48 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

122 changes: 122 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
description = "A local diffing tool for decompilation projects";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs =
{
self,
nixpkgs,
rust-overlay,
}:
let
systems = [
"x86_64-linux"
"aarch64-linux"
];
forAllSystems = nixpkgs.lib.genAttrs systems;
version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version;
mkPkgs =
system:
import nixpkgs {
inherit system;
overlays = [ rust-overlay.overlays.default ];
};
in
{
packages = forAllSystems (
system:
let
pkgs = mkPkgs system;
rustToolchain = pkgs.rust-bin.stable."1.88.0".default;
rustPlatform = pkgs.makeRustPlatform {
cargo = rustToolchain;
rustc = rustToolchain;
};
mkObjdiff = pkgs.callPackage ./nix/package.nix {
inherit rustPlatform version;
};
in
rec {
objdiff = mkObjdiff {
crateName = "objdiff-gui";
binaryName = "objdiff";
withGui = true;
};
objdiff-cli = mkObjdiff {
crateName = "objdiff-cli";
binaryName = "objdiff-cli";
};
default = objdiff;
}
);

apps = forAllSystems (system: {
default = self.apps.${system}.objdiff;
objdiff = {
type = "app";
program = "${self.packages.${system}.objdiff}/bin/objdiff";
meta.description = "Run the objdiff graphical interface";
};
objdiff-cli = {
type = "app";
program = "${self.packages.${system}.objdiff-cli}/bin/objdiff-cli";
meta.description = "Run the objdiff command-line interface";
};
});

checks = forAllSystems (system: {
inherit (self.packages.${system}) objdiff objdiff-cli;
});

devShells = forAllSystems (
system:
let
pkgs = mkPkgs system;
rustToolchain = pkgs.rust-bin.selectLatestNightlyWith (
toolchain:
toolchain.default.override {
extensions = [
"clippy"
"rust-src"
"rustfmt"
];
targets = [ "wasm32-wasip2" ];
}
);
cargoWrapper = pkgs.writeShellScriptBin "cargo" ''
if [[ "''${1-}" == "+nightly" ]]; then
shift
fi
exec ${rustToolchain}/bin/cargo "$@"
'';
in
{
default = pkgs.mkShell {
inputsFrom = [ self.packages.${system}.objdiff ];
packages = with pkgs; [
cargoWrapper
rustToolchain
cargo-deny
cargo-insta
nodejs
pre-commit
protobuf
rust-analyzer
];
shellHook = ''
export PATH="${cargoWrapper}/bin:$PATH"
'';
};
}
);

formatter = forAllSystems (system: (mkPkgs system).nixfmt);
};
}
109 changes: 109 additions & 0 deletions nix/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
{
lib,
rustPlatform,
pkg-config,
makeWrapper,
makeDesktopItem,
fontconfig,
freetype,
libGL,
libx11,
libxcursor,
libxi,
libxrandr,
libxkbcommon,
vulkan-loader,
wayland,
xdg-utils,
version,
}:
{
crateName,
binaryName,
withGui ? false,
}:
let
desktopItem = makeDesktopItem {
name = "objdiff";
desktopName = "objdiff";
comment = "Compare object files in decompilation projects";
exec = "objdiff";
icon = "objdiff";
categories = [ "Development" ];
startupWMClass = "objdiff";
};
runtimeLibraries = [
libGL
libxkbcommon
vulkan-loader
wayland
libx11
libxcursor
libxi
libxrandr
];
in
rustPlatform.buildRustPackage {
pname = crateName;
inherit version;

src = lib.cleanSourceWith {
src = ../.;
filter =
path: type:
let
name = baseNameOf path;
in
!lib.elem name [
".git"
".worktrees"
"result"
"target"
];
};

# Import registry dependencies directly from Cargo.lock so lock-file updates
# do not require refreshing a single vendor hash.
cargoLock.lockFile = ../Cargo.lock;
cargoBuildFlags = [
"--package"
crateName
];
cargoTestFlags = [
"--package"
crateName
];

nativeBuildInputs = [ pkg-config ] ++ lib.optionals withGui [ makeWrapper ];
buildInputs = lib.optionals withGui [
fontconfig
freetype
wayland
libx11
];

env = lib.optionalAttrs withGui {
OBJDIFF_DISABLE_SELF_UPDATE = "1";
};

postInstall = lib.optionalString withGui ''
wrapProgram "$out/bin/${binaryName}" \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath runtimeLibraries} \
--prefix PATH : ${lib.makeBinPath [ xdg-utils ]}
install -Dm644 objdiff-gui/assets/icon.png \
"$out/share/icons/hicolor/512x512/apps/objdiff.png"
install -Dm644 ${desktopItem}/share/applications/objdiff.desktop \
"$out/share/applications/objdiff.desktop"
'';

meta = {
description = "A local diffing tool for decompilation projects";
homepage = "https://github.com/encounter/objdiff";
license = with lib.licenses; [
asl20
mit
];
mainProgram = binaryName;
platforms = lib.platforms.linux;
};
}
4 changes: 3 additions & 1 deletion objdiff-gui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use crate::{
app_config::{AppConfigVersion, deserialize_config},
config::{ProjectObjectNode, load_project_config},
jobs::{create_objdiff_config, egui_waker, start_build},
update::SELF_UPDATE_ENABLED,
views::{
appearance::{Appearance, appearance_window},
config::{
Expand Down Expand Up @@ -507,7 +508,8 @@ impl App {
if state.config.selected_obj.is_some() {
state.queue_build = true;
}
app.view_state.config_state.queue_check_update = state.config.auto_update_check;
app.view_state.config_state.queue_check_update =
SELF_UPDATE_ENABLED && state.config.auto_update_check;
}
app.appearance.init_fonts(&cc.egui_ctx);
app.appearance.utc_offset = utc_offset;
Expand Down
1 change: 1 addition & 0 deletions objdiff-gui/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub const BIN_NAME_NEW: &str =
pub const BIN_NAME_OLD: &str = formatcp!("objdiff-{}-{}{}", OS, ARCH, std::env::consts::EXE_SUFFIX);
pub const RELEASE_URL: &str =
formatcp!("https://github.com/{}/{}/releases/latest", GITHUB_USER, GITHUB_REPO);
pub const SELF_UPDATE_ENABLED: bool = option_env!("OBJDIFF_DISABLE_SELF_UPDATE").is_none();

pub fn build_updater() -> Result<Box<dyn ReleaseUpdate>> {
Ok(Box::new(
Expand Down
Loading
Loading