😜

Nix で import std をする

2024/08/06に公開

はじめに

CMake が import std を実装している。
なら Nix で使わざるを得ないだろう。
import std で必要なのは二つ

  1. CMake ≥ 3.30
  2. llvm ≥ 19
  3. ninja

CMake

現状 nix には “3.29” の CMake しか存在しない、なので

(pkgs.cmake.overrideAttrs (oldAttrs: {
  version = "3.30.2";
  src = oldAttrs.src.overrideAttrs {
    outputHash = "sha256-RgdMeB7M68Qz6Y8Lv6Jlyj/UOB8kXKOxQOdxFTHWDbI=";
  };
}))

こう書くと、新しい “3.30.2” が使えるようになる。

LLVM

nixpkgs の llvm ではまだ import std に必要な module のソースを適切な場所にインストールすることができていない。なので、自分で書いてあげる必要がある。

(pkgs.llvmPackages_19.libcxxClang.overrideAttrs (oldAttrs: {
  postFixup =
    oldAttrs.postFixup
    + ''
      ln -sf  ${oldAttrs.passthru.libcxx}/lib/libc++.modules.json $out/resource-root/libc++.modules.json
      ln -sf  ${oldAttrs.passthru.libcxx}/share $out
    '';
}))

ざっとこんな感じだ

まとめ

ざっとまとめると packages の設定を以下のようにすれば良い。

packages = [
  pkgs.llvmPackages_19.clang-tools
  (pkgs.llvmPackages_19.libcxxClang.overrideAttrs (oldAttrs: {
    postFixup =
      oldAttrs.postFixup
      + ''
        ln -sf  ${oldAttrs.passthru.libcxx}/lib/libc++.modules.json $out/resource-root/libc++.modules.json
        ln -sf  ${oldAttrs.passthru.libcxx}/share $out
      '';
  }))
  (pkgs.cmake.overrideAttrs (oldAttrs: {
    version = "3.30.2";
    src = oldAttrs.src.overrideAttrs {
      outputHash = "sha256-RgdMeB7M68Qz6Y8Lv6Jlyj/UOB8kXKOxQOdxFTHWDbI=";
    };
  }))
  pkgs.ninja
];

あとは

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.29.20240416 FATAL_ERROR)

set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")

project(import_std LANGUAGES CXX)
set(CMAKE_CXX_MODULE_STD 1)

add_executable(main)
target_compile_features(
  main
  PRIVATE cxx_std_23
  INTERFACE cxx_std_20)
target_sources(main PRIVATE main.cc)
  • main.cc
import std;


auto main() -> int
{
  std::println("Hello, {}!", "world");
  return 0;
}

を書いてコンパイルするだけ!

GitHubで編集を提案

Discussion