Skip to content
cccskills
FreePublished on GitHub

packaging

corepkgs packaging conventions. Use when writing or reviewing any pkgs/<name>/default.nix — covers package organization (auto-registration, top-level.nix, alternative implementations), the finalAttrs pattern, meta attributes, where each kind of dependency belongs, fetchers, patching, install phases, multiple outputs, and passthru.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94 stars(GitHub 94 + cccskills 0)
Works withGitLab

Run score Not tested

See how to install

Files included (1)

  • SKILL.md7.9 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Packaging Conventions

Package Organization

Packages in pkgs/ and pkgs-many/ are automatically added to the pkgs.* scope based on their directory name. No explicit entry in top-level.nix is needed.

When to add an explicit top-level.nix entry:

  • Only when inputs deviate from those declared in the nix expression
  • Or when overriding default arguments / providing additional configuration
# top-level.nix — only if inputs deviate
libxslt = callPackage ./pkgs/libxslt {
  pythonSupport = false;
  cryptoSupport = true;
};

Alternative Implementations

Keep alternative implementations in the same package directory using multiple files: default.nix (short selector), generic.nix (usual implementation), darwin.nix (Apple's implementation).

Keep selection logic inside the package folder using ordinary if expressions and callPackage, forwarding explicit overrides. Avoid separate apple-<package> entries.

Expose libpcap.apple when callers need to choose an implementation. Preserve .override and .overrideAttrs on each implementation. For pkgs-many/ families, dispatch to separate implementation files from generic.nix. Use short variant names (real, darwin, v3_3); don't repeat the package name in package-local aliases.

Rules

  • Never set meta.maintainers or meta.teams — neither is a recognised meta key; setting one fails check-meta. Simply omit them.
  • __structuredAttrs = true is the default — never set it explicitly. If phases break, fix them instead of disabling. See structured-attrs.
  • doCheck = false and doInstallCheck = false are defaults — don't set them explicitly. Use passthru.tests for test coverage.

Package Structure

Use finalAttrs pattern for self-referencing:

stdenv.mkDerivation (finalAttrs: {
  pname = "example";
  version = "1.0.0";

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

  passthru.tests = {
    unittests = runUnitTests finalAttrs.finalPackage;
  };
})

Meta Attributes

Required fields:

meta = {
  description = "Brief description";
  license = lib.licenses.mit;
  platforms = lib.platforms.linux;
};

Common licenses:

license = lib.licenses.mit;
license = lib.licenses.gpl3Plus;
license = with lib.licenses; [ gpl2Plus lgpl21Plus ];

Platform options:

platforms = lib.platforms.linux;    # Linux only
platforms = lib.platforms.unix;     # Unix-like
platforms = lib.platforms.darwin;   # macOS only
platforms = lib.platforms.all;      # All platforms

Testing

Goal: Keep builds as fast as possible by disabling in-build tests. Use passthru.tests to preserve test coverage without slowing every build.

Defaults

doCheck = false; and doInstallCheck = false; are the defaults across all build systems (stdenv.mkDerivation, buildPythonPackage, buildRustPackage, buildGoModule, buildPerlPackage). Don't set them explicitly.

Auto-Generated passthru.tests.build

buildRustPackage and buildGoModule automatically provide passthru.tests.build — a variant that re-runs the build with doCheck = true. User-supplied passthru.tests entries are merged alongside, not replaced.

For stdenv.mkDerivation packages, add passthru.tests manually:

passthru.tests = {
  withChecks = finalAttrs.finalPackage.overrideAttrs { doCheck = true; };
};

Python: testPaths (Preferred)

Set testPaths to auto-generate passthru.tests.python and a test_src output:

nativeCheckInputs = [ pytestCheckHook ];
testPaths = [ "tests" ];

The test_src output bundles the listed paths plus config files (conftest.py, pyproject.toml, etc.). A standalone test derivation runs the suite against the installed package.

For suites that need extra files (helper modules, fixture data):

testPaths = [ "tests" "src/helpers" "README.rst" ];

Test configuration attributes are forwarded automatically:

  • disabledTests, disabledTestPaths, enabledTestPaths
  • pytestFlags, pytestFlagsArray, unittestFlagsArray
  • preCheck, postCheck, preInstallCheck, postInstallCheck

Python: Manual tests.nix (Fallback)

When testPaths is not suitable (e.g., circular dependencies with pytest), create a separate tests.nix:

# default.nix
passthru.tests = {
  pytest = callPackage ./tests.nix { };
};

Acceptable In-Build Checks

doInstallCheck = true; is acceptable for:

  • versionCheckHook — verifies the built binary runs and prints expected version
  • pythonImportsCheck — runs automatically in buildPythonPackage, no need to enable explicitly

Dependencies

nativeBuildInputs = [    # Build tools (build platform)
  pkg-config
  cmake
];

buildInputs = [          # Libraries (host platform)
  zlib
  openssl
];

checkInputs = [          # Test dependencies
  pytest
];

propagatedBuildInputs = [ # Runtime deps for dependents
  python3
];

Cross-compilation:

strictDeps = true;

depsBuildBuild = [ pkg-config ];    # Build -> build tools
nativeBuildInputs = [ cmake ];      # Build -> host tools
buildInputs = [ zlib ];             # Host libraries

Fetching Sources

GitHub:

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

GitLab:

src = fetchFromGitLab {
  domain = "gitlab.com";
  owner = "example";
  repo = "example";
  tag = finalAttrs.version;
  hash = "sha256-...";
};

Tarball:

src = fetchurl {
  url = "https://example.com/releases/example-${finalAttrs.version}.tar.gz";
  hash = "sha256-...";
};

Patching

Substitutions:

postPatch = ''
  substituteInPlace Makefile \
    --replace '/usr/local' "$out" \
    --replace 'python' '${python3}/bin/python3'
'';

Patch files:

patches = [
  ./fix-build.patch
  (fetchpatch {
    url = "https://github.com/example/example/commit/abc123.patch";
    hash = "sha256-...";
  })
];

Install Phase

installPhase = ''
  runHook preInstall

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

  runHook postInstall
'';

Post-install fixups:

postInstall = ''
  wrapProgram $out/bin/example \
    --prefix PATH : ${lib.makeBinPath [ coreutils ]}
'';

Multiple Outputs

outputs = [ "out" "dev" "doc" ];

postInstall = ''
  moveToOutput include $dev
  moveToOutput share/doc $doc
'';

Passthru

passthru = {
  tests = {
    unittests = runUnitTests finalAttrs.finalPackage;
  };

  plugins = {
    foo = callPackage ./plugins/foo.nix { };
  };
};

Porting from nixpkgs

Remove:

  • updateScript from passthru
  • Maintainers list (set to [ ])
  • nixpkgs-specific test infrastructure

Add TODO for missing deps:

buildInputs = [
  zlib
  # TODO(corepkgs): Port openssl for TLS support
];

Complete Example

{
  lib,
  stdenv,
  fetchFromGitHub,
  cmake,
  pkg-config,
  zlib,
}:

stdenv.mkDerivation (finalAttrs: {
  pname = "example";
  version = "2.1.0";

  src = fetchFromGitHub {
    owner = "example-org";
    repo = "example";
    tag = "v${finalAttrs.version}";
    hash = "sha256-...";
  };

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
    pkg-config
  ];

  buildInputs = [ zlib ];

  strictDeps = true;
  cmakeBuildType = "Release";

  passthru.tests = {
    unittests = runUnitTests finalAttrs.finalPackage;
  };

  meta = {
    description = "Example library";
    homepage = "https://github.com/example-org/example";
    license = lib.licenses.mit;
    platforms = lib.platforms.unix;
  };
})

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Review a package expression for best-practices compliance. Use when reviewing PRs or auditing existing packages — checks meta completeness, build-system idioms (cmakeEntries, mesonEntries, pyproject), dependency placement, and packaging conventions.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94Updated Oct 26, 2026

cmake

Free

Package a CMake-based project for corepkgs. Use when a source tree has a CMakeLists.txt — covers the minimal derivation, cmakeEntries, cross-compilation, and diagnosing CMake configure failures.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94Updated Oct 26, 2026

Fix all broken package builds in the repository. Runs a full build of ci/packages.nix in the background while iterating on failures in the foreground until everything builds.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94Updated Oct 26, 2026

go

Free

Package a Go module for corepkgs. Use when writing or editing a buildGoModule derivation — covers vendorHash, ldflags, subPackages, tags, env.CGO_ENABLED, proxyVendor, shell completions, and pinning a Go version.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94Updated Oct 26, 2026

meson

Free

Package a Meson/Ninja project for corepkgs. Use when a source tree has a meson.build — covers mesonFlags, auto features, cross-compilation, and diagnosing Meson setup failures.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94Updated Oct 26, 2026

Work with multi-version packages under pkgs-many (guile, go, erlang, perl, openssl, ...). Use when adding or changing a package that ships several versions side by side — covers the default.nix/variants.nix/generic.nix three-file pattern, the packageOlder/packageAtLeast version helpers, and mkVariantPassthru.

The English summary is being prepared. Showing the original description.

ekala-project/corepkgs94Updated Oct 26, 2026

See all skills by ekala-project

Report a problem with this skill