New Pkg

Create a new Nix package derivation for existing software with automatic dependency detection and validation.

olafkfreund 1 updated 1mo ago
Claude CodeGeneric
View source ↗
# Package Existing Software for Nix

Create a new Nix package derivation for existing software with automatic dependency detection and validation.

## Quick Start

Just tell me:
1. **Software name** (e.g., "mycli", "awesome-tool")
2. **Source location** (GitHub URL, tarball URL, or "help me find it")
3. **Programming language** (C/C++, Python, Rust, Go, etc.)

I'll guide you through the rest interactively.

## What I'll Do

### 1. Research & Planning (Automatic)
- Analyze the software's build system (autoconf, cmake, meson, cargo, etc.)
- Identify likely dependencies from build files
- Determine appropriate fetcher (fetchFromGitHub, fetchurl, etc.)
- Check if package already exists in nixpkgs

### 2. Choose Package Location
**Options:**
- `pkgs/` directory in your project (recommended for custom packages)
- Overlay in `overlays/` (for extending nixpkgs)
- Standalone `default.nix` (for testing)

### 3. Create Package Derivation

Using this proven structure:
```nix
{ lib
, stdenv
, fetchFromGitHub
, # ... build dependencies
}:

stdenv.mkDerivation rec {
  pname = "package-name";
  version = "1.0.0";

  src = fetchFromGitHub {
    owner = "owner-name";
    repo = "repo-name";
    rev = "v${version}";
    hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
  };

  nativeBuildInputs = [
    # Build-time dependencies (compilers, build tools)
  ];

  buildInputs = [
    # Runtime dependencies (libraries)
  ];

  # Custom build phases if needed
  # configurePhase, buildPhase, installPhase

  meta = with lib; {
    description = "Short description";
    homepage = "https://example.com";
    license = licenses.mit;
    maintainers = with maintainers; [ your-name ];
    platforms = platforms.all;
    mainProgram = "binary-name";
  };
}

4. Hash Calculation (Automatic)

  • Generate correct hash using nix-prefetch-url or nix hash
  • Handle hash format conversion (sha256 to SRI format)
  • Update derivation with correct hash

5. Dependency Detection (Interactive)

  • Build the package and capture error messages
  • Identify missing dependencies from build failures
  • Search nixpkgs for required packages
  • Add dependencies iteratively

6. Build Phase Customization (If Needed)

  • Override phases for non-standard build systems
  • Add custom install steps
  • Handle special cases (no install target, custom paths)

7. Testing & Validation

  • Build the package: nix-build -A package-name
  • Test the binary: ./result/bin/program --version
  • Verify all dependencies are included
  • Check for runtime errors

8. Integration

  • Add to pkgs/default.nix or overlay
  • Create usage example
  • Document any special requirements

Packaging Workflow

Phase 1: Source Fetching

For GitHub repositories (recommended):

src = fetchFromGitHub {
  owner = "username";
  repo = "project";
  rev = "v1.0.0";  # or git commit hash
  hash = "";  # Leave empty initially
};

For release tarballs:

src = fetchurl {
  url = "https://example.com/software-1.0.0.tar.gz";
  hash = "";  # Leave empty initially
};

For other sources:

  • fetchgit - Git repositories (non-GitHub)
  • fetchzip - ZIP archives
  • fetchPatch - Patches

Phase 2: Hash Generation

I'll automatically:

  1. Build with empty hash
  2. Extract correct hash from error message
  3. Convert to SRI format if needed
  4. Update derivation

Manual command:

nix-prefetch-url --unpack https://github.com/owner/repo/archive/v1.0.0.tar.gz

Phase 3: Dependency Discovery

Build and iterate:

  1. Run nix-build
  2. Read error messages for missing files/libraries
  3. Search nixpkgs: nix search nixpkgs package-name
  4. Add to buildInputs or nativeBuildInputs
  5. Repeat until build succeeds

Common dependencies:

  • C/C++: pkg-config, cmake, autoconf, gcc, clang
  • Python: python3, python3Packages.*
  • Rust: cargo, rustc, rustPlatform.buildRustPackage
  • Go: buildGoModule
  • Node: nodejs, nodePackages.*

Phase 4: Build System Detection

I'll identify and configure:

Autotools (./configure && make):

nativeBuildInputs = [ pkg-config ];
configureFlags = [ "--enable-feature" ];

CMake:

nativeBuildInputs = [ cmake ];
cmakeFlags = [ "-DOPTION=ON" ];

Meson:

nativeBuildInputs = [ meson ninja ];
mesonFlags = [ "-Dfeature=enabled" ];

Make only:

makeFlags = [ "PREFIX=$(out)" ];

Custom build:

buildPhase = ''
  runHook preBuild
  ./custom-build.sh
  runHook postBuild
'';

Phase 5: Custom Installation

When software lacks standard install:

installPhase = ''
  runHook preInstall

  mkdir -p $out/bin
  cp program $out/bin/

  mkdir -p $out/share/doc/${pname}
  cp README.md LICENSE $out/share/doc/${pname}/

  runHook postInstall
'';

Common install patterns:

  • Binaries → $out/bin/
  • Libraries → $out/lib/
  • Headers → $out/include/
  • Documentation → $out/share/doc/
  • Man pages → $out/share/man/

Language-Specific Helpers

Rust Packages

{ rustPlatform, fetchFromGitHub }:

rustPlatform.buildRustPackage rec {
  pname = "rust-tool";
  version = "1.0.0";

  src = fetchFromGitHub {
    owner = "owner";
    repo = "repo";
    rev = "v${version}";
    hash = "sha256-...";
  };

  cargoHash = "sha256-...";  # Run with empty string first

  meta = { ... };
}

Python Packages

{ python3Packages, fetchPypi }:

python3Packages.buildPythonPackage rec {
  pname = "python-package";
  version = "1.0.0";

  src = fetchPypi {
    inherit pname version;
    hash = "sha256-...";
  };

  propagatedBuildInputs = with python3Packages; [
    requests
    click
  ];

  meta = { ... };
}

Go Packages

{ buildGoModule, fetchFromGitHub }:

buildGoModule rec {
  pname = "go-tool";
  version = "1.0.0";

  src = fetchFromGitHub {
    owner = "owner";
    repo = "repo";
    rev = "v${version}";
    hash = "sha256-...";
  };

  vendorHash = "sha256-...";  # or null f

Maintain New Pkg?

Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.

[New Pkg on getagentictools](https://getagentictools.com/loops/olafkfreund-package-existing-software-for-nix?ref=badge)