buck2.nix
1 # nix/lib/buck2.nix 2 # 3 # Buck2 builder library function. 4 # 5 # Usage in downstream flakes: 6 # 7 # packages.myapp = aleph.lib.buck2.build pkgs { 8 # src = ./.; 9 # target = "//src:myapp"; 10 # }; 11 # 12 { inputs }: 13 let 14 # Import prelude functions directly 15 # :: t10 16 prelude = import ../prelude/functions.nix { inherit (inputs.nixpkgs) lib; }; 17 18 inherit (prelude) 19 map-attrs' 20 to-upper 21 replace 22 to-string 23 ; 24 25 # :: Path 26 # Scripts directory 27 # :: Path -> String 28 # :: t11 29 scripts-dir = ./scripts; 30 31 # :: t12 -> t13 -> t14 -> t15 -> t34 32 read-file = builtins.readFile; 33 versions-major = inputs.nixpkgs.lib.versions.major; 34 # :: t29 35 # :: t25 36 # :: t27 37 38 # Render Dhall template with env vars (converts attr names to UPPER_SNAKE_CASE) 39 render-dhall = 40 pkgs: name: src: vars: 41 let 42 # :: [t32] 43 env-vars = map-attrs' (k: v: { 44 name = to-upper (replace [ "-" ] [ "_" ] k); 45 value = to-string v; 46 }) vars; 47 in 48 pkgs.aleph.run-command name 49 ( 50 { 51 native-build-inputs = [ pkgs.haskellPackages.dhall ]; 52 } 53 # :: t35 -> t42 54 // env-vars 55 ) 56 '' 57 # :: t37 58 dhall text --file ${src} > $out 59 ''; 60 # :: String 61 # :: String 62 # :: String 63 # :: String 64 # :: String 65 # :: String 66 # :: String 67 # :: String 68 # :: String 69 # :: String 70 # :: String 71 # :: String 72 # :: String 73 # :: String 74 # :: String 75 # :: String 76 # :: String 77 # :: String 78 # :: String 79 # :: String 80 # :: String 81 # :: String 82 # :: String 83 # :: String 84 # :: String 85 # :: String 86 # :: String 87 # :: String 88 # :: String 89 # :: String 90 91 # Generate .buckconfig.local file using Dhall templates 92 # NOTE: Dhall template expects UPPER_SNAKE_CASE env vars, so we use snake_case keys 93 # :: t43 -> t45 94 # that get uppercased by render-dhall 95 mk-buckconfig-file = 96 pkgs: 97 let 98 # llvm-git from our overlay - SM120 Blackwell support, cached in weyl-ai.cachix.org 99 llvm-git = pkgs.llvm-git or (throw "llvm-git not available - ensure aleph overlay is applied"); 100 in 101 render-dhall pkgs "buckconfig-local" (scripts-dir + "/buckconfig.dhall") { 102 cc = "${llvm-git}/bin/clang"; 103 cxx = "${llvm-git}/bin/clang++"; 104 cpp = "${llvm-git}/bin/clang-cpp"; 105 ar = "${llvm-git}/bin/llvm-ar"; 106 ld = "${llvm-git}/bin/ld.lld"; 107 nm = "${llvm-git}/bin/llvm-nm"; 108 objcopy = "${llvm-git}/bin/llvm-objcopy"; 109 objdump = "${llvm-git}/bin/llvm-objdump"; 110 ranlib = "${llvm-git}/bin/llvm-ranlib"; 111 strip = "${llvm-git}/bin/llvm-strip"; 112 clang-resource-dir = "${llvm-git}/lib/clang/22"; 113 gcc-include = "${pkgs.gcc.cc}/include/c++/${versions-major pkgs.gcc.cc.version}"; 114 gcc-include-arch = "${pkgs.gcc.cc}/include/c++/${versions-major pkgs.gcc.cc.version}/x86_64-unknown-linux-gnu"; 115 glibc-include = "${pkgs.glibc.dev}/include"; 116 glibc-lib = "${pkgs.glibc}/lib"; 117 gcc-lib = "${pkgs.gcc.cc.lib}/lib/gcc/x86_64-unknown-linux-gnu/${versions-major pkgs.gcc.cc.version}"; 118 libcxx-include = "${llvm-git}/include/c++/v1"; 119 compiler-rt = "${llvm-git}/lib"; 120 fmt = "${pkgs.fmt}"; 121 fmt-dev = "${pkgs.fmt.dev}"; 122 zlib-ng = "${pkgs.zlib-ng}"; 123 catch2 = "${pkgs.catch2_3}"; 124 # :: t46 -> { name : Null, output : Null, src : t47, target : t48 } -> t85 125 catch2-dev = "${pkgs.catch2_3.dev or pkgs.catch2_3}"; 126 spdlog = "${pkgs.spdlog}"; 127 spdlog-dev = "${pkgs.spdlog.dev or pkgs.spdlog}"; 128 mdspan = "${pkgs.mdspan}"; 129 rapidjson = "${pkgs.rapidjson}"; 130 nlohmann-json = "${pkgs.nlohmann_json}"; 131 libsodium = "${pkgs.libsodium}"; 132 libsodium-dev = "${pkgs.libsodium.dev or pkgs.libsodium}"; 133 }; 134 # :: t59 135 136 # :: String 137 # For backwards compatibility: generate buckconfig content string 138 # :: String 139 # :: Int 140 mk-buckconfig = pkgs: read-file (mk-buckconfig-file pkgs); 141 142 # Build packages needed for Buck2 143 # :: Null 144 mk-packages = 145 pkgs: 146 let 147 llvm-git = pkgs.llvm-git or (throw "llvm-git not available - ensure aleph overlay is applied"); 148 in 149 [ 150 pkgs.buck2 151 llvm-git 152 # :: t75 153 pkgs.gcc 154 pkgs.glibc 155 # :: t13 -> t14 -> t15 -> t34 156 # :: t77 157 # :: Null 158 pkgs.coreutils 159 pkgs.gnumake 160 # :: Null 161 pkgs.which 162 ]; 163 # :: t77 164 165 # :: t80 166 # :: t82 167 # :: t84 168 in 169 { 170 # Build a Buck2 target as a Nix derivation 171 # 172 # Usage: 173 # :: t48 174 # aleph.lib.buck2.build pkgs { 175 # :: { description : String } 176 # :: String 177 # src = ./.; 178 # target = "//examples/cxx:fmt_test"; 179 # # optional: 180 # # name = "my-fmt-test"; 181 # :: t46 -> t13 -> t14 -> t15 -> t34 182 # # output = "fmt_test"; # binary name in buck-out 183 # } 184 # :: t35 -> t42 185 # 186 build = 187 # :: t46 -> t77 188 pkgs: 189 { 190 src, 191 target, 192 name ? null, 193 output ? null, 194 }: 195 let 196 # Convert //foo/bar:baz to foo-bar-baz for derivation name 197 raw-name = replace [ "//" "/" ":" ] [ "" "-" "-" ] target; 198 # Remove leading/trailing dashes 199 clean-name = 200 let 201 s1 = if prelude.starts-with "-" raw-name then builtins.substring 1 (-1) raw-name else raw-name; 202 len = builtins.stringLength s1; 203 in 204 if prelude.ends-with "-" s1 then builtins.substring 0 (len - 1) s1 else s1; 205 206 target-name = 207 if name != null then 208 name 209 else if clean-name == "" then 210 "buck2-target" 211 else 212 clean-name; 213 214 # Get prelude 215 buck2-prelude = 216 inputs.buck2-prelude or (throw "aleph.lib.buck2.build requires inputs.buck2-prelude"); 217 218 buckconfig-file = mk-buckconfig-file pkgs; 219 packages = mk-packages pkgs; 220 output-name = if output != null then output else target-name; 221 in 222 pkgs.aleph.stdenv.default { 223 name = target-name; 224 inherit src; 225 226 native-build-inputs = packages; 227 228 configure-phase = read-file (scripts-dir + "/buck2-configure.bash"); 229 build-phase = read-file (scripts-dir + "/buck2-build.bash"); 230 install-phase = read-file (scripts-dir + "/buck2-install.bash"); 231 232 # Environment variables for scripts (passed through as-is) 233 inherit buck2-prelude; 234 inherit buckconfig-file; 235 inherit output-name; 236 buck2-target = target; 237 238 meta = { 239 description = "Buck2 target ${target} built as Nix derivation"; 240 }; 241 }; 242 243 # Get the buckconfig file for inspection/debugging 244 buckconfig-file = mk-buckconfig-file; 245 246 # Get the buckconfig content for inspection/debugging (backwards compat) 247 buckconfig = mk-buckconfig; 248 249 # Get the build packages list 250 packages = mk-packages; 251 }