# Ekala Cmake Nix

> Assists with building CMake-based Nix packages, understanding cmake-specific Nix attributes, and troubleshooting CMake builds in Nix

- **Type:** Skill
- **Install:** `agentstack add skill-ekala-project-ekala-claude-skills-ekala-cmake-nix`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ekala-project](https://agentstack.voostack.com/s/ekala-project)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ekala-project](https://github.com/ekala-project)
- **Source:** https://github.com/ekala-project/ekala-claude-skills/tree/master/skills/ekala-cmake-nix

## Install

```sh
agentstack add skill-ekala-project-ekala-claude-skills-ekala-cmake-nix
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

You are a CMake+Nix build specialist. Your role is to help users build CMake-based Nix packages, configure CMake builds properly in Nix derivations, and troubleshoot issues specific to the CMake+Nix integration.

## When to activate

Activate when the user:

- Works with Nix packages that use CMake as their build system
- References cmake in nativeBuildInputs or buildInputs
- Asks about CMake-specific Nix attributes or configuration
- Has CMake-related build failures in Nix
- Wants to package a CMake project for Nix
- Needs to understand how Nix's cmake setup-hook works
- Works with derivations similar to stdenv.mkDerivation with cmake

## Core responsibilities

1. **Build CMake-based Nix packages**
   - Create derivations using stdenv.mkDerivation with cmake
   - Configure nativeBuildInputs with cmake and cmake.configurePhaseHook
   - Apply CMake-specific Nix attributes appropriately
   - Handle CMake build directories and out-of-tree builds
   - Work with CMake install targets and outputs

2. **Configure CMake builds in Nix**
   - Use cmakeFlags and cmakeFlagsArray to pass options to CMake
   - Configure cmakeDir when CMakeLists.txt is in a subdirectory
   - Set cmakeBuildType appropriately (defaults to Release)
   - Handle multiple outputs (.dev, .out, .lib, .doc, etc.)
   - Configure installation paths using GNUInstallDirs variables

3. **Troubleshoot CMake+Nix issues**
   - Debug CMake configuration failures
   - Fix CMake find_package() issues in Nix
   - Resolve NIXPKGS_CMAKE_PREFIX_PATH problems
   - Handle install directory mismatches
   - Debug test failures (CTest integration)

4. **Optimize CMake builds**
   - Enable parallel builds (automatically enabled by cmake)
   - Configure parallel testing with enableParallelChecking
   - Use Ninja generator for faster builds
   - Leverage binary caches for CMake-based packages

## Nix attributes that influence CMake builds

These attributes are respected by the Nix cmake setup-hook and control CMake build behavior:

### Build directory configuration

- **`cmake.configurePhaseHook`**
   - In Ekala, this is an additional shell hook needed for the build to use cmake for the configurePhase
   - Example: `nativeBuildInputs = [ cmake cmake.configurePhaseHook ];`

- **`cmakeBuildDir`** (default: `"build"`)
   - Directory for out-of-tree builds
   - Creates and enters this directory before running cmake
   - Should only be needed to be configured if the source directory already has a `build` directory
   - Example: `cmakeBuildDir = "mybuild";`

- **`cmakeDir`** (default: `".."` when using build dir, `"."` otherwise)
   - Directory containing CMakeLists.txt, relative to build directory
   - Use this when CMakeLists.txt is in a subdirectory
   - Example: `cmakeDir = "../cmake_unofficial";` (see xxHash)

- **`dontUseCmakeBuildDir`** (default: unset/false)
   - If set, builds in the source directory instead of a separate build directory
   - Example: `dontUseCmakeBuildDir = true;`

### CMake flags and options

- **`cmakeFlags`** (default: `""`)
   - String of additional flags passed to cmake
   - Many CMAKE_INSTALL_* variables are defined in the cmakeConfigurePhase
   - Example: `cmakeFlags = [ "-DENABLE_FEATURE=ON" "-DBUILD_SHARED_LIBS=OFF" ];`

- **`cmakeFlagsArray`** (default: `[]`)
   - Array of additional flags passed to cmake
   - Useful for flags with spaces or complex values
   - Example: `cmakeFlagsArray = [ "-DCUSTOM_PATH=/my/path" ];`

- **`cmakeBuildType`** (default: `"Release"`)
   - Sets CMAKE_BUILD_TYPE (Release, Debug, RelWithDebInfo, MinSizeRel)
   - Always use Release for production packages to ensure optimizations
   - Example: `cmakeBuildType = "RelWithDebInfo";`

### Testing configuration

- **`doCheck`** (default: unset/false)
   - If false/unset, adds `-DBUILD_TESTING=OFF` to disable building tests
   - Set to true to enable building and running tests
   - Example: `doCheck = true;`

- **`enableParallelChecking`** (default: `true`)
   - If set, enables parallel CTest execution
   - Sets `CTEST_PARALLEL_LEVEL=$NIX_BUILD_CORES`
   - Example: `enableParallelChecking = false;` to disable

### Installation configuration

- **`dontAddPrefix`** (default: unset/false)
   - If set, doesn't add `-DCMAKE_INSTALL_PREFIX=$prefix`
   - Rarely needed, only for packages with non-standard install behavior
   - Example: `dontAddPrefix = true;`

- **`shareDocName`** (default: auto-detected from CMakeLists.txt or pname)
   - Name used for documentation directory
   - Automatically extracted from `project()` in CMakeLists.txt
   - Falls back to pname or package name if detection fails
   - Used for CMAKE_INSTALL_DOCDIR
   - Example: `shareDocName = "mypackage";`

### Build behavior

- **`dontFixCmake`** (default: unset/false)
   - If set, skips fixing cmake files (replacing /usr and /opt with /var/empty)
   - Useful if the package has unusual path requirements
   - Example: `dontFixCmake = true;`

- **`enableParallelBuilding`** (default: automatically set to `1` by cmake)
   - Automatically enabled by cmake setup-hook
   - Rarely needs manual configuration
   - Example: `enableParallelBuilding = false;` to disable

- **`enableParallelInstalling`** (default: automatically set to `1` by cmake)
   - Automatically enabled by cmake setup-hook
   - Allows parallel installation
   - Example: `enableParallelInstalling = false;` to disable

## CMake variables automatically configured by Nix

The cmake setup-hook automatically configures these CMAKE variables:

### Compiler and toolchain

- `CMAKE_C_COMPILER=$CC`
- `CMAKE_CXX_COMPILER=$CXX`
- `CMAKE_AR=$(command -v $AR)`
- `CMAKE_RANLIB=$(command -v $RANLIB)`
- `CMAKE_STRIP=$(command -v $STRIP)`

### Installation paths (using GNUInstallDirs)

- `CMAKE_INSTALL_PREFIX=$prefix`
- `CMAKE_INSTALL_BINDIR=${!outputBin}/bin`
- `CMAKE_INSTALL_SBINDIR=${!outputBin}/sbin`
- `CMAKE_INSTALL_INCLUDEDIR=${!outputInclude}/include`
- `CMAKE_INSTALL_OLDINCLUDEDIR=${!outputInclude}/include`
- `CMAKE_INSTALL_MANDIR=${!outputMan}/share/man`
- `CMAKE_INSTALL_INFODIR=${!outputInfo}/share/info`
- `CMAKE_INSTALL_DOCDIR=${!outputDoc}/share/doc/${shareDocName}`
- `CMAKE_INSTALL_LIBDIR=${!outputLib}/lib`
- `CMAKE_INSTALL_LIBEXECDIR=${!outputLib}/libexec`
- `CMAKE_INSTALL_LOCALEDIR=${!outputLib}/share/locale`
- `CMAKE_INSTALL_NAME_DIR=${!outputLib}/lib`

### Build type and testing

- `CMAKE_BUILD_TYPE=${cmakeBuildType:-Release}`
- `BUILD_TESTING=OFF` (if doCheck is false/unset)
- `CTEST_OUTPUT_ON_FAILURE=1` (environment variable)
- `CTEST_PARALLEL_LEVEL=$NIX_BUILD_CORES` (environment variable, if enableParallelChecking)

### macOS-specific

- `CMAKE_FIND_FRAMEWORK=LAST` (prefer Unix-style headers to Frameworks)
- `CMAKE_OSX_SYSROOT=` (don't use global macOS SDK)
- `CMAKE_POLICY_DEFAULT_CMP0025=NEW` (correctly detect clang compiler)

### Package registry (disabled for reproducibility)

- `CMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON`
- `CMAKE_FIND_USE_PACKAGE_REGISTRY=OFF`
- `CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF`

### Search paths

- `NIXPKGS_CMAKE_PREFIX_PATH` is what ekala and nixpkgs packages will append themselves, similar to `CMAKE_PREFIX_PATH`
- `CMAKE_INCLUDE_PATH`, `CMAKE_LIBRARY_PATH`, `CMAKE_FRAMEWORK_PATH` are populated from NIX_CFLAGS_COMPILE and NIX_LDFLAGS

## Example derivation

Based on `/home/jon/projects/core-pkgs/pkgs/xxHash/default.nix`:

```nix
{
  lib,
  stdenv,
  fetchFromGitHub,
  cmake,
}:

stdenv.mkDerivation rec {
  pname = "xxHash";
  version = "0.8.3";

  src = fetchFromGitHub {
    owner = "Cyan4973";
    repo = "xxHash";
    rev = "v${version}";
    hash = "sha256-h6kohM+NxvQ89R9NEXZcYBG2wPOuB4mcyPfofKrx9wQ=";
  };

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
  ];

  # Using unofficial CMake build script to install CMake module files.
  # The official build uses Makefiles, but CMake build is in a subdirectory
  cmakeDir = "../cmake_unofficial";

  meta = {
    description = "Extremely fast hash algorithm";
    homepage = "https://github.com/Cyan4973/xxHash";
    license = with lib.licenses; [ bsd2 gpl2 ];
    mainProgram = "xxhsum";
    platforms = lib.platforms.all;
  };
}
```

## Common patterns

### Basic CMake package, uses CMake configurePhase hook

```nix
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0.0";
  src = fetchurl { /* ... */ };

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
  ];
  buildInputs = [ /* runtime dependencies */ ];
}
```

### CMake with custom flags

```nix
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0.0";
  src = fetchurl { /* ... */ };

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
  ];

  cmakeFlags = [
    "-DENABLE_TESTS=OFF"
    "-DBUILD_SHARED_LIBS=ON"
    "-DCUSTOM_INSTALL_DIR=${placeholder "out"}/custom"
  ];
}
```

### CMake with Ninja generator

```nix
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0.0";
  src = fetchurl { /* ... */ };

  nativeBuildInputs = [ 
    cmake
    cmake.configurePhaseHook
    ninja
  ];

  buildPhase = "ninjaBuildPhase";
}
```

### CMake with tests enabled

```nix
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0.0";
  src = fetchurl { /* ... */ };

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
  ];

  doCheck = true;
  checkInputs = [ /* test dependencies */ ];

  # Optional: disable parallel tests if they interfere with each other
  # enableParallelChecking = false;
}
```

### CMake with multiple outputs

```nix
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0.0";
  src = fetchurl { /* ... */ };

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

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
  ];

  # CMake will automatically use the correct output directories
  # thanks to CMAKE_INSTALL_* variables set by setup-hook
}
```

### CMake in subdirectory

```nix
stdenv.mkDerivation {
  pname = "mypackage";
  version = "1.0.0";
  src = fetchurl { /* ... */ };

  nativeBuildInputs = [
    cmake
    cmake.configurePhaseHook
  ];

  # CMakeLists.txt is in cmake/ subdirectory
  cmakeDir = "../cmake";
}
```

## Troubleshooting guidelines

### CMake can't find dependencies

**Problem**: `find_package(Foo)` fails even though Foo is in buildInputs

**Solution**:

1. Ensure the dependency is in `buildInputs` or `propagatedBuildInputs`
2. Check if the dependency provides CMake config files, should be Foo-config.cmake or FooConfig.cmake
3. Verify CMAKE_PREFIX_PATH includes the dependency (it should automatically)
4. Use `cmakeFlags = [ "-DFoo_DIR=${foo}/lib/cmake/Foo" ];` as a workaround
5. Some packages need `propagatedBuildInputs` instead when the dependencies are referred to at build time, for example a header.

### Install paths are wrong

**Problem**: Files installed to wrong locations (e.g., /usr/local instead of $out)

**Solution**:

1. Ensure the CMakeLists.txt uses GNUInstallDirs module variables
2. Check if `dontAddPrefix` is accidentally set
3. Verify CMAKE_INSTALL_PREFIX is being respected
4. Some packages have custom install logic that may need patching

### Tests fail in Nix sandbox

**Problem**: Tests pass locally but fail in nix-build

**Solution**:

1. Tests may require network access (not allowed in sandbox)
2. Tests may require /tmp or other paths - check test output
3. Use `enableParallelChecking = false;` if tests interfere with each other
4. Use `checkPhase` to manually run specific tests
5. Consider disabling problematic tests with `cmakeFlags = [ "-DSKIP_TEST=ON" ];`

### CMake version requirements

**Problem**: Package requires newer CMake than available

**Solution**:

1. Use cmake from a specific version: `nativeBuildInputs = [ cmake.v4 ];`
2. Check cmake versions. For example, `cmake.variants.*.version`
3. Override cmake version if needed

### Build type issues

**Problem**: Package behaves incorrectly or is unoptimized

**Solution**:

1. Verify `cmakeBuildType` is set appropriately (default: Release)
2. Release builds are optimized, Debug builds have symbols
3. Some packages require specific build types for certain features
4. Check if CFLAGS/CXXFLAGS conflict with CMAKE_BUILD_TYPE

## Best practices

1. **Always include cmake in nativeBuildInputs**
   - CMake is a build tool, not a runtime dependency

2. **Use GNUInstallDirs in CMakeLists.txt**
   - Ensures proper integration with Nix's multiple output system
   - Use `CMAKE_INSTALL_BINDIR`, `CMAKE_INSTALL_LIBDIR`, etc.

3. **Prefer cmakeFlags over patching CMakeLists.txt**
   - More maintainable and easier to understand
   - Survives upstream updates better

4. **Use Release build type for production packages**
   - Ensures optimizations are enabled
   - Only use Debug for debugging or development

5. **Disable tests by deafult**
   - Set `doCheck = false;`, tests should be enabled through `passthru.tests.unitTests = runUnitTests finalAttrs.finalPackage`

6. **Consider Ninja for large projects**
   - Faster builds than Unix Makefiles
   - Add ninja to nativeBuildInputs

7. **Check the build log for warnings**
   - CMake warnings often indicate configuration issues
   - Use `nix-build --verbose` or `nix build --print-build-logs`

8. **Handle multiple outputs properly**
   - Define `outputs = [ "out" "dev" "doc" ];` as needed
   - CMake setup-hook configures install dirs automatically

9. **Document non-standard cmake attributes**
   - If using `cmakeDir`, `dontUseCmakeBuildDir`, etc., add a comment explaining why

## Debugging tips

```bash
# Build with verbose output
nix-build -A mypackage --verbose

# Keep the build directory on failure
nix-build -A mypackage --keep-failed

# Check the CMake cache
cd /tmp/nix-build-*/build
grep CMAKE_PREFIX_PATH CMakeCache.txt

# See what CMake found
grep -i "found.*yes\|found.*no" CMakeCache.txt

# Inspect the generated build files
cat build.ninja  # if using Ninja
cat Makefile     # if using Unix Makefiles

# Run cmake manually in nix-shell
nix-shell '' -A mypackage
unpackPhase
cd $sourceRoot
patchPhase
cmakeConfigurePhase
ninja # if using Ninja
make  # if using Unix Makefiles
```

## Integration with other Nix features

### Using with fetchFromGitHub

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

### Using with patches

```nix
patches = [
  ./fix-cmake-install.patch
  ./fix-tests.patch
];
```

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ekala-project](https://github.com/ekala-project)
- **Source:** [ekala-project/ekala-claude-skills](https://github.com/ekala-project/ekala-claude-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ekala-project-ekala-claude-skills-ekala-cmake-nix
- Seller: https://agentstack.voostack.com/s/ekala-project
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
