The extension for one PostgreSQL major (contract §3): the :ext tree
(lib/postjevsql.so, the control file and the install SQL generated
from the .so) built by buck2 inside the sandbox, the same graph the
tests build. Called per major as postgresql_NN.pkgs.callPackage.
Crates: third-party/BUCK fetches each crate with http_archive, which needs the network. Every one is fetched here instead, by the url and sha256 that file records (read at eval, so no IFD and no second lock), and nix/offline_archive.bzl stands in for http_archive in the sandbox.
10{ 11 lib, 12 stdenv, 13 fetchurl, 14 linkFarm, 15 buck2, 16 rustc, 17 rustfmt, 18 clang, 19 lld, 20 python3, 21 gnutar, 22 gzip, 23 cacert, 24 bubblewrap, 25 coreutils, 26 rustPlatform, 27 postgresql, 28}: 29let 30 # pgrx compiles against one major's headers, chosen by a cargo 31 # feature. third-party/Cargo.toml selects the default major for buck's 32 # own graph; for any other supported one the feature is swapped below. 33 majors = import ./majors.nix { inherit lib; }; 34 major = lib.versions.major postgresql.version;
Only what //crates/postjevsql:ext reads, so editing docs, tests or
the other nix files does not change the hash and rebuild through buck.
A new directory the build reads must be added here, or buck fails to
find it in the sandbox.
40 src = lib.fileset.toSource { 41 root = ../.; 42 fileset = lib.fileset.difference (lib.fileset.unions [ 43 ../.buckconfig 44 ../build 45 ../crates 46 ../platforms 47 ../third-party 48 ../toolchains 49 ../tools 50 ./offline_archive.bzl 51 # Not read by buck: the notices installed beside the binaries 52 # (THIRD-PARTY-sidecar by nix/sidecar-cli.nix). 53 ../THIRD-PARTY 54 ../THIRD-PARTY-sidecar 55 ../LICENSE-MIT 56 ../LICENSE-APACHE 57 ]) ( 58 lib.fileset.fileFilter ( 59 file: 60 lib.elem file.name [ 61 "README.md" 62 "CLAUDE.md" 63 ".buckconfig.local" 64 ] 65 ) ../. 66 ); 67 };
69 thirdParty = builtins.readFile ../third-party/BUCK; 70 archives = map ( 71 block: 72 let 73 m = builtins.match ''[[:space:]]*name = "([^"]+)",[[:space:]]*sha256 = "([0-9a-f]+)",[[:space:]]*strip_prefix = "[^"]*",[[:space:]]*urls = [[]"([^"]+)"[]],[[:space:]]*visibility = [[][]],[[:space:]]*'' (lib.head (lib.splitString "\n)" block)); 74 in 75 if m == null then 76 throw "nix/package.nix: an http_archive in third-party/BUCK has an unexpected shape" 77 else 78 { 79 name = lib.elemAt m 0; 80 path = fetchurl { 81 name = "${lib.elemAt m 0}.tar.gz"; 82 url = lib.elemAt m 2; 83 sha256 = lib.elemAt m 1; 84 }; 85 } 86 ) (lib.drop 1 (lib.splitString "\nhttp_archive(" thirdParty)); 87 crates = linkFarm "postjevsql-crates" archives;
Builds one buck target to out, as the tests build it. The prelude
writes wrapper scripts (linker_wrapper.sh, ...) that start
#!/usr/bin/env bash, and the sandbox has no /usr. bwrap gives buck
a root that has it, with everything else bound as is. Passed on so
nix/sidecar-cli.nix builds its binary the same way.
94 buck = target: out: '' 95 export HOME=$TMPDIR 96 # buck2 loads the trust store at startup, though nothing is fetched. 97 export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt 98 bwrap \ 99 --bind /build /build --bind /tmp /tmp --ro-bind /nix /nix \ 100 --ro-bind /bin /bin --ro-bind /etc /etc --dev /dev --proc /proc \ 101 --symlink ${coreutils}/bin/env /usr/bin/env \ 102 --chdir "$PWD" \ 103 -- sh -c 'buck2 build --target-platforms //platforms:pg${major} ${target} --out ${out} && buck2 kill' 104 '';
106 version = lib.head ( 107 builtins.match ''[[:space:][:print:]]*VERSION = "([^"]+)"[[:space:][:print:]]*'' (builtins.readFile ../build/defs.bzl) 108 ); 109in 110assert lib.assertMsg (lib.elem major majors.all) 111 "postjevsql: PostgreSQL ${major} is not supported; the supported majors are ${lib.concatStringsSep ", " majors.all} (PG_MAJORS in build/defs.bzl)"; 112stdenv.mkDerivation { 113 pname = "postjevsql"; 114 inherit version src; 115 116 nativeBuildInputs = [ 117 buck2 118 rustc 119 # pgrx-pg-sys formats its generated bindings. 120 rustfmt 121 clang 122 lld 123 python3 124 gnutar 125 gzip 126 bubblewrap 127 # pgrx-pg-sys runs bindgen against the server headers. 128 rustPlatform.bindgenHook 129 ]; 130 buildInputs = [ postgresql ]; 131 132 PGRX_PG_CONFIG_PATH = "${postgresql.pg_config}/bin/pg_config"; 133 134 postPatch = '' 135 # The docs were the none cell's only files, and a fileset keeps no 136 # empty directory; buck needs the cell to exist. 137 mkdir -p none 138 cp -rL ${crates} third-party/crates 139 chmod -R u+w third-party/crates 140 cp nix/offline_archive.bzl third-party/offline_archive.bzl 141 sed -i '1a load("//third-party:offline_archive.bzl", "http_archive")' third-party/BUCK 142 # Release packaging builds without debug assertions (toolchains/BUCK). 143 substituteInPlace toolchains/BUCK \ 144 --replace-fail '"-Cdebug-assertions=on"' '"-Cdebug-assertions=off"' 145 cat > .buckconfig.local <<EOF 146 [nix] 147 cc = ${clang}/bin/clang 148 cxx = ${clang}/bin/clang++ 149 ar = ${clang}/bin/ar 150 python = ${python3}/bin/python3 151 [postjevsql] 152 postgres_bin_${major} = ${postgresql}/bin 153 pg_config_${major} = ${postgresql.pg_config}/bin/pg_config 154 EOF 155 ''; 156 157 buildPhase = '' 158 runHook preBuild 159 ${buck "//crates/postjevsql:ext" "ext"} 160 runHook postBuild 161 ''; 162 163 installPhase = '' 164 runHook preInstall 165 # nixpkgs' layout, which postgresql.withPackages joins. 166 mkdir -p $out/lib $out/share/postgresql 167 cp ext/lib/postjevsql.so $out/lib/ 168 cp -r ext/share/extension $out/share/postgresql/ 169 # The .so links crates.io code whose licences require their notices. 170 install -Dm644 -t $out/share/doc/postjevsql THIRD-PARTY LICENSE-MIT LICENSE-APACHE 171 runHook postInstall 172 ''; 173 174 passthru = { inherit buck; }; 175 176 meta = { 177 description = "Ask TypeSafe's Jev typed questions about rows, from SQL"; 178 platforms = postgresql.meta.platforms; 179 }; 180}