diff --git a/.gitignore b/.gitignore index 2e461bd71..d8c8d98a6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ cmake*/ .direnv pgrx-examples/*/target /bin +result diff --git a/ci/nix-update-rust-toolchain.sh b/ci/nix-update-rust-toolchain.sh new file mode 100755 index 000000000..e3d846971 --- /dev/null +++ b/ci/nix-update-rust-toolchain.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +echo "---- update nix rust dependency ----" +nix flake update fenix --commit-lock-file diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..ab1f6ac10 --- /dev/null +++ b/flake.lock @@ -0,0 +1,144 @@ +{ + "nodes": { + "crane": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1713979152, + "narHash": "sha256-apdecPuh8SOQnkEET/kW/UcfjCRb8JbV5BKjoH+DcP4=", + "owner": "ipetkov", + "repo": "crane", + "rev": "a5eca68a2cf11adb32787fc141cddd29ac8eb79c", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1714199028, + "narHash": "sha256-QO3Yv3UfJRfhZE1wsHOartg+k8/Kf1BiDyfl8eEpqcE=", + "owner": "nix-community", + "repo": "fenix", + "rev": "055f6db376eaf544d84aa55bd5a7c70634af41ba", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1714076141, + "narHash": "sha256-Drmja/f5MRHZCskS6mvzFqxEaZMeciScCTFxWVLqWEY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7bb2ccd8cdc44c91edba16c48d2c8f331fb3d856", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1711703276, + "narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d8fe5e6c92d0d190646fb9f1056741a229980089", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "fenix": "fenix", + "flake-parts": "flake-parts", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1714150666, + "narHash": "sha256-S8AsTyJvT6Q3pRFeo8QepWF/husnJh61cOhRt18Xmyc=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "1ed7e2de05ee76f6ae83cc9c72eb0b33ad6903f2", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..fb7116d21 --- /dev/null +++ b/flake.nix @@ -0,0 +1,147 @@ +{ + inputs = { + crane = { + url = "github:ipetkov/crane"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixpkgs.url = "nixpkgs/nixos-unstable"; + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + flake-parts.url = "github:hercules-ci/flake-parts"; + gitignore = { + url = "github:hercules-ci/gitignore"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs: + inputs.flake-parts.lib.mkFlake {inherit inputs;} { + systems = ["x86_64-linux" "aarch64-linux" "aarch64-darwin"]; + perSystem = { + lib, + pkgs, + inputs', + system, + self', + ... + }: let + rustToolchain = inputs'.fenix.packages.stable.toolchain; + craneLib = inputs.crane.lib.${system}.overrideToolchain rustToolchain; + in { + packages = { + cargo-pgrx = craneLib.buildPackage { + src = inputs.gitignore.lib.gitignoreSource ./.; + inherit (craneLib.crateNameFromCargoToml {cargoToml = ./cargo-pgrx/Cargo.toml;}) pname version; + cargoExtraArgs = "--package cargo-pgrx"; + nativeBuildInputs = [pkgs.pkg-config]; + buildInputs = [pkgs.openssl] ++ lib.optionals pkgs.stdenv.isDarwin [pkgs.darwin.apple_sdk.frameworks.Security pkgs.libiconv]; + # fixes to enable running pgrx tests + preCheck = '' + export PGRX_HOME=$(mktemp -d) + ''; + # skip tests that require pgrx to be initialized using `cargo pgrx init` + cargoTestExtraArgs = "-- --skip=command::schema::tests::test_parse_managed_postmasters"; + }; + }; + devShells.default = with pkgs; mkShell { + inputsFrom = [ + self'.packages.cargo-pgrx + ]; + nativeBuildInputs = with pkgs; [ + rustToolchain + pkg-config + ]; + buildInputs = with pkgs; [ + openssl + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.Security + libiconv + ]; + + shellHook = '' + export PGRX_HOME=$(mktemp -d) + ''; + }; + }; + flake.lib.buildPgrxExtension = { + rustToolchain, + system, + src, + postgresql, + additionalFeatures ? [], + }: let + cargo-pgrx = inputs.self.packages.${system}.cargo-pgrx; + pkgs = inputs.nixpkgs.legacyPackages.${system}; + craneLib = inputs.crane.lib.${system}.overrideToolchain rustToolchain; + + postgresMajor = inputs.nixpkgs.lib.versions.major postgresql.version; + cargoToml = builtins.fromTOML (builtins.readFile "${src}/Cargo.toml"); + name = cargoToml.package.name; + pgrxFeatures = builtins.toString additionalFeatures; + + preBuildAndTest = '' + export PGRX_HOME=$(mktemp -d) + mkdir -p $PGRX_HOME/${postgresMajor} + + cp -r -L ${postgresql}/. $PGRX_HOME/${postgresMajor}/ + chmod -R ugo+w $PGRX_HOME/${postgresMajor} + cp -r -L ${postgresql.lib}/lib/. $PGRX_HOME/${postgresMajor}/lib/ + + ${cargo-pgrx}/bin/cargo-pgrx pgrx init \ + --pg${postgresMajor} $PGRX_HOME/${postgresMajor}/bin/pg_config \ + ''; + + craneCommonBuildArgs = { + inherit src; + pname = "${name}-pg${postgresMajor}"; + nativeBuildInputs = [ + pkgs.pkg-config + pkgs.rustPlatform.bindgenHook + postgresql.lib + postgresql + ]; + cargoExtraArgs = "--no-default-features --features \"pg${postgresMajor} ${pgrxFeatures}\""; + postPatch = "patchShebangs ."; + preBuild = preBuildAndTest; + preCheck = preBuildAndTest; + postBuild = '' + if [ -f "${name}.control" ]; then + export NIX_PGLIBDIR=${postgresql.out}/share/postgresql/extension/ + ${cargo-pgrx}/bin/cargo-pgrx pgrx package --pg-config ${postgresql}/bin/pg_config --features "${pgrxFeatures}" --out-dir $out + export NIX_PGLIBDIR=$PGRX_HOME/${postgresMajor}/lib + fi + ''; + + PGRX_PG_SYS_SKIP_BINDING_REWRITE = "1"; + CARGO = "${rustToolchain}/bin/cargo"; + CARGO_BUILD_INCREMENTAL = "false"; + RUST_BACKTRACE = "full"; + }; + + cargoArtifacts = craneLib.buildDepsOnly craneCommonBuildArgs; + in + craneLib.mkCargoDerivation ({ + inherit cargoArtifacts; + buildPhaseCargoCommand = '' + ${cargo-pgrx}/bin/cargo-pgrx pgrx package --pg-config ${postgresql}/bin/pg_config --features "${pgrxFeatures}" --out-dir $out + ''; + doCheck = false; + preFixup = '' + if [ -f "${name}.control" ]; then + ${cargo-pgrx}/bin/cargo-pgrx pgrx stop all + rm -rfv $out/target* + fi + ''; + + postInstall = '' + mkdir -p $out/lib + cp target/release/lib${name}.so $out/lib/${name}.so + mv -v $out/${postgresql.out}/* $out + rm -rfv $out/nix + ''; + } + // craneCommonBuildArgs); + }; +}