😜
Nix で import std をする
はじめに
CMake が import std を実装している。
なら Nix で使わざるを得ないだろう。
import std で必要なのは二つ
- CMake ≥ 3.30
- llvm ≥ 19
- 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;
}
を書いてコンパイルするだけ!



Discussion