From 0467b7f04ae2913301be52f78357b4ab2d67810a Mon Sep 17 00:00:00 2001 From: Rushmore Mushambi Date: Tue, 4 Oct 2022 18:32:44 +0200 Subject: [PATCH] Add NixOS build and simplify building from source (#100) --- .envrc | 1 + .github/workflows/nix.yml | 60 ++++++++ .gitignore | 4 + CONTRIBUTING.md | 2 +- default.nix | 6 + doc/BUILDING.md | 4 + flake.lock | 155 +++++++++++++++++++++ flake.nix | 120 ++++++++++++++++ pkg/nix/README.md | 151 ++++++++++++++++++++ pkg/nix/config.nix | 6 + pkg/nix/drv/binary.nix | 27 ++++ pkg/nix/drv/docker.nix | 12 ++ pkg/nix/spec/aarch64-unknown-linux-gnu.nix | 21 +++ pkg/nix/spec/x86_64-apple-darwin.nix | 21 +++ pkg/nix/spec/x86_64-pc-windows-gnu.nix | 17 +++ pkg/nix/spec/x86_64-unknown-linux-gnu.nix | 27 ++++ pkg/nix/spec/x86_64-unknown-linux-musl.nix | 17 +++ pkg/nix/util.nix | 96 +++++++++++++ shell.nix | 6 + 19 files changed, 752 insertions(+), 1 deletion(-) create mode 100644 .envrc create mode 100644 .github/workflows/nix.yml create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 pkg/nix/README.md create mode 100644 pkg/nix/config.nix create mode 100644 pkg/nix/drv/binary.nix create mode 100644 pkg/nix/drv/docker.nix create mode 100644 pkg/nix/spec/aarch64-unknown-linux-gnu.nix create mode 100644 pkg/nix/spec/x86_64-apple-darwin.nix create mode 100644 pkg/nix/spec/x86_64-pc-windows-gnu.nix create mode 100644 pkg/nix/spec/x86_64-unknown-linux-gnu.nix create mode 100644 pkg/nix/spec/x86_64-unknown-linux-musl.nix create mode 100644 pkg/nix/util.nix create mode 100644 shell.nix diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..3550a30f --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 00000000..37f73a11 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,60 @@ +name: Nix + +on: + - pull_request + - push + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: cachix/install-nix-action@v17 + - run: nix flake check --show-trace + + build-static: + name: Build static Linux binary + needs: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: cachix/install-nix-action@v17 + - uses: cachix/cachix-action@v10 + with: + name: surrealdb + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + extraPullNames: nix-community + - run: nix build .#static-binary + - run: ./result/bin/surreal help + + build-docker: + name: Build Docker image + needs: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: cachix/install-nix-action@v17 + - uses: cachix/cachix-action@v10 + with: + name: surrealdb + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + extraPullNames: nix-community + - run: nix build .#docker-image + - run: docker load --input ./result + + build-native-linux: + name: Build native Linux binary + needs: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: cachix/install-nix-action@v17 + - uses: cachix/cachix-action@v10 + with: + name: surrealdb + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + extraPullNames: nix-community + - run: nix build .#x86_64-unknown-linux-gnu + - run: ./result/bin/surreal help diff --git a/.gitignore b/.gitignore index d6b35ae0..0eceb14a 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,10 @@ Temporary Items /target/ /lib/target/ .idea/ +/result +/bin/ +/docker/ +/.direnv/ # ----------------------------------- # Specific diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 822afb5a..7568fe0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ rustup component add rustfmt ## Getting started from source -To set up a working **development environment**, ensure that you have `rustup` installed, and fork the project git repository. +To set up a working **development environment**, you can either [use the Nix package manager](pkg/nix#readme) or you can [install dependencies manually](doc/BUILDING.md#building-surrealdb) and ensure that you have `rustup` installed, and fork the project git repository. > Please note that these instructions are for setting up a functional dev environment. If you just want to install SurrealDB for day-to-day usage and not as a code maintainer use this [installation guide](https://surrealdb.com/docs/install). If you want to get started integrating SurrealDB into your app, view the [integration tutorials](https://surrealdb.com/docs/integration). diff --git a/default.nix b/default.nix new file mode 100644 index 00000000..80aeb433 --- /dev/null +++ b/default.nix @@ -0,0 +1,6 @@ +(import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock); +in fetchTarball { + url = + "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; +}) { src = ./.; }).defaultNix diff --git a/doc/BUILDING.md b/doc/BUILDING.md index d3393ece..fc6c3599 100644 --- a/doc/BUILDING.md +++ b/doc/BUILDING.md @@ -359,3 +359,7 @@ docker run --pull --rm -v $PWD:/volume -t clux/muslrust:stable cargo build --rel Running `cargo build` in an **elevated shell** will now build the `SurrealDB` in Windows OS. + +## Building using the Nix package manager + +SurrealDB can be built [using the Nix package manager](../pkg/nix#nix-package-manager). diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..67da1e5a --- /dev/null +++ b/flake.lock @@ -0,0 +1,155 @@ +{ + "nodes": { + "crane": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1664412889, + "narHash": "sha256-gyVtTQf3CiXLe1cwNRFxqUqYl9BCmIDvK7hIpzR/oQU=", + "owner": "ipetkov", + "repo": "crane", + "rev": "755acd231a7de182fdc772bee1b2a1f21d4ec9ed", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "ref": "v0.7.0", + "repo": "crane", + "type": "github" + } + }, + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1664865507, + "narHash": "sha256-KUonhQPn7SigY+4mfI/UydMQv4nIhBKIqgeU3JAaowI=", + "owner": "nix-community", + "repo": "fenix", + "rev": "93c65e24793653fdc45339022218a9ceca6219dd", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1650374568, + "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "b4a34015c698c7793d592d66adbab377907a2be8", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1650374568, + "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "b4a34015c698c7793d592d66adbab377907a2be8", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1652776076, + "narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8", + "type": "github" + }, + "original": { + "owner": "numtide", + "ref": "v1.0.0", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1664790708, + "narHash": "sha256-fzxmpOPjzOVIt9KeDN4EDPI13xJn+u0uMxheKCWken8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "81a3237b64e67b66901c735654017e75f0c50943", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "fenix": "fenix", + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs" + } + }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1664652573, + "narHash": "sha256-mVf9fjQbtYbrVvQSaJOCwArWIvXHrXqVVUhP0x9ZcVY=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "5c28ad193238635189f849c94ffc178f00008b12", + "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 00000000..6c420294 --- /dev/null +++ b/flake.nix @@ -0,0 +1,120 @@ +{ + description = + "A scalable, distributed, collaborative, document-graph database, for the realtime web"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.05-small"; + flake-utils.url = "github:numtide/flake-utils/v1.0.0"; + crane = { + url = "github:ipetkov/crane/v0.7.0"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; + }; + + outputs = inputs: + with inputs; + + # Make systems available as variables to prevent typos + with flake-utils.lib.system; + + # let-in expressions, very similar to Rust's let bindings. These names + # are used to express the output but not themselves paths in the output. + let + + nativeSystems = [ aarch64-linux x86_64-darwin x86_64-linux ]; + + # Build the output set for each default system and map system sets into + # attributes, resulting in paths such as: + # nix build .#packages.x86_64-linux. + in flake-utils.lib.eachSystem nativeSystems (system: + + let + + pkgs = import nixpkgs { inherit system; }; + + util = import ./pkg/nix/util.nix { + inherit system; + inherit (pkgs) lib; + systems = flake-utils.lib.system; + flake = self; + }; + + mkRustToolchain = target: + with fenix.packages.${system}; + combine [ + stable.rustc + stable.cargo + targets.${target}.stable.rust-std + ]; + + buildPlatform = pkgs.stdenv.buildPlatform.config; + + # Make platforms available as variables to prevent typos + in with util.platforms; + + rec { + packages = { + # nix build + default = + packages.${buildPlatform} or packages.x86_64-unknown-linux-gnu; + + # nix build .#docker-image + docker-image = import ./pkg/nix/drv/docker.nix { + inherit util; + inherit (pkgs) cacert dockerTools; + package = packages.x86_64-unknown-linux-gnu; + }; + + # nix build .#static-binary + static-binary = packages.x86_64-unknown-linux-musl; + + # nix build .#windows-binary + windows-binary = packages.x86_64-pc-windows-gnu; + } // (pkgs.lib.attrsets.mapAttrs (target: _: + let + spec = + import ./pkg/nix/spec/${target}.nix { inherit pkgs target util; }; + in import ./pkg/nix/drv/binary.nix { + inherit pkgs util spec crane; + rustToolchain = mkRustToolchain target; + }) util.platforms); + + devShells = { + # nix develop + default = + devShells.${buildPlatform} or devShells.x86_64-unknown-linux-gnu; + + # nix develop .#static-binary + static-binary = devShells.x86_64-unknown-linux-musl; + + # nix develop .#windows-binary + windows-binary = devShells.x86_64-pc-windows-gnu; + } // (pkgs.lib.attrsets.mapAttrs (target: _: + let + spec = (import ./pkg/nix/spec/${target}.nix) { + inherit pkgs target util; + }; + rustToolchain = mkRustToolchain target; + buildSpec = spec.buildSpec; + in pkgs.mkShell (buildSpec // { + hardeningDisable = [ "fortify" ]; + + depsBuildBuild = buildSpec.depsBuildBuild or [ ] + ++ [ rustToolchain ] ++ (with pkgs; [ nixfmt cargo-watch ]); + + inherit (util) SURREAL_BUILD_METADATA; + })) util.platforms); + + # nix run + apps.default = flake-utils.lib.mkApp { drv = packages.default; }; + + }); +} diff --git a/pkg/nix/README.md b/pkg/nix/README.md new file mode 100644 index 00000000..2c3089e2 --- /dev/null +++ b/pkg/nix/README.md @@ -0,0 +1,151 @@ +# Nix package manager + +According to [Wikipedia] + +> Nix is a cross-platform package manager that utilizes a purely functional deployment model where software is installed into unique directories generated through cryptographic hashes. It is also the name of the tool's programming language. A package's hash takes into account the dependencies, which is claimed to eliminate dependency hell. This package management model advertises more reliable, reproducible, and portable packages. + +SurrealDB has support for the Nix package manager. It makes it easier to build the project from source and setting up development environments. + +## Table of Contents + +- [Running Nix from Docker](#running-nix-from-docker) + * [Building a Docker image (recommended)](#building-a-docker-image--recommended-) + * [Building a static binary](#building-a-static-binary) +- [Installing Nix](#installing-nix) + * [Activating support for Nix Flakes (recommended)](#activating-support-for-nix-flakes--recommended-) + * [Setting up a binary cache (optional)](#setting-up-a-binary-cache--optional-) +- [Installing SurrealDB](#installing-surrealdb) +- [Setting up a development environment](#setting-up-a-development-environment) + * [Setting dependencies up automatically](#setting-dependencies-up-automatically) + * [Manually installing dependencies](#manually-installing-dependencies) +- [Collecting garbage](#collecting-garbage) + +## Running Nix from Docker + +If all you want is to build a Docker image or a static linux binary and you already have Docker installed, then you can do so without installing anything on your machine. + +First, you need to clone this repo and `cd` into it + +``` +git clone https://github.com/surrealdb/surrealdb.git +cd surrealdb +``` + +### Building a Docker image (recommended) + +A Docker image is recommended because it supports all the features and storage backends that SurrealDB supports. To build a Docker image, run the following command. + +``` +docker run -it --rm -v $(pwd):/surrealdb -w /surrealdb nixos/nix sh -c "nix-build -A packages.x86_64-linux.docker-image && mkdir docker && cp -vL ./result docker/surreal.tar.gz && rm result" +``` + +The image will be saved as `docker/surreal.tar.gz`. You can load it using + +``` +docker load -i docker/surreal.tar.gz +``` + +### Building a static binary + +Please note that currently a static binary is very limited. It doesn't come with any optional features and it only supports the in-memory store, so you can't persist data with it. + +To build the static binary, run + +``` +docker run -it --rm -v $(pwd):/surrealdb -w /surrealdb nixos/nix sh -c "nix-build -A packages.x86_64-linux.static-binary && mkdir bin && cp -v ./result/bin/surreal bin/ && rm result" +``` + +The binary will be saved as `bin/surreal`. + +## Installing Nix + +If you want to develop using Nix or you want to build binaries native to your platform then you may need to install Nix. To do so, please follow the official [installation instructions]. + +### Activating support for Nix Flakes (recommended) + +Nix Flakes are an upcoming feature of the Nix package manager. Officially, they are still considered experimental and, as such, are not enabled by default. However, they are already widely adopted by the Nix community. SurrealDB supports Nix both with and without support for Flakes. + +To enable support for Flakes, edit either `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` and add: + +``` +experimental-features = nix-command flakes +``` + +If the Nix installation is in multi-user mode, you will need to restart the `nix-daemon` after this. If your system uses `systemd`, you can do this by simply running `sudo systemctl restart nix-daemon`. + +Because of Flakes' superior user experience, we highly recommend them. For brevity, the rest of this guide will assume that flake support is enabled. + +### Setting up a binary cache (optional) + +Building SurrealDB and all its dependencies can take a while. To speed up the process, you can take advantage of our binary cache. To do so, you simply need to run the following command: + +``` +nix run nixpkgs#cachix use surrealdb +``` + +This will download and run the Cachix command to configure your system to use our binary cache. + +## Installing SurrealDB + +If all you need to do is run SurrealDB without installing it to your `PATH` then you simply need to run + +``` +nix run github:surrealdb/surrealdb +``` + +To install it, use + +``` +nix profile install github:surrealdb/surrealdb +``` + +You can target a specific branch, tag or commit by appending it to above commands separated by `/`. For example + +``` +nix run github:surrealdb/surrealdb/v1.0.0-beta.9 +``` + +If you just want to build the binary, without running it, you can use `nix build` instead of `nix run`. You will then find the binary in `result/bin`. + +**NB**: While Nix is cross-platform, currently only building Linux binaries on Linux is supported. The above commands build the default binary, a dynamically linked binary with support for all SurrealDB features. To build a statically linked binary use `nix build github:surrealdb/surrealdb#static-binary`. To build a Docker image use `nix build github:surrealdb/surrealdb#docker-image`. We plan to add support for more platforms in future, in the meantime you can [run Nix from Docker](#running-nix-from-docker) if you would like to build from a different platform. + +## Setting up a development environment + +Nix can be used to set up C/C++ dependencies for this project in order for Cargo commands to work properly. + +If you haven't already done so, you will need to clone this repo and `cd` into it + +``` +git clone https://github.com/surrealdb/surrealdb.git +cd surrealdb +``` + +### Setting dependencies up automatically + +To make Nix setup dependencies automatically when you switch into this project, you need to install and configure `direnv`. To do so, run the following commands:- + +``` +nix profile install nixpkgs#direnv +nix profile install nixpkgs#nix-direnv +``` + +and add `eval "$(direnv hook bash)"` to your `~/.bashrc` or similar file. + +Finally, from this project's root directory, run + +``` +direnv allow +``` + +### Manually installing dependencies + +If you choose not to use `direnv` to automatically setup your dependencies as described above, you can use `nix develop` to manually install the dependencies and configure your environment so that `cargo` commands work normally. + +Once your environment is set up, you can use normal `cargo` commands. + +## Collecting garbage + +Because of the way it works, Nix can use a lot of space on your machine. To reclaim some of that space, you can use `nix-collect-garbage -d`. + +[Wikipedia]: https://en.wikipedia.org/wiki/Nix_(package_manager) +[installation instructions]: https://nixos.org/download.html#nix-install-linux diff --git a/pkg/nix/config.nix b/pkg/nix/config.nix new file mode 100644 index 00000000..a790ba22 --- /dev/null +++ b/pkg/nix/config.nix @@ -0,0 +1,6 @@ +{ + # Set the desired FoundationDB version here + # Specify only the major and minor parts using `major.minor` format + # Must be supported by both the foundationdb crate and NixPkgs + fdbVersion = "6.1"; +} diff --git a/pkg/nix/drv/binary.nix b/pkg/nix/drv/binary.nix new file mode 100644 index 00000000..2ab24494 --- /dev/null +++ b/pkg/nix/drv/binary.nix @@ -0,0 +1,27 @@ +{ pkgs, spec, util, rustToolchain, crane }: + +let + + featureFlags = let + featureLists = spec.features or [ ]; + features = with pkgs.lib; lists.unique (lists.flatten featureLists); + in map (feature: "--features=${feature}") features; + + craneLib = (crane.mkLib pkgs).overrideScope' (final: prev: { + cargo = rustToolchain; + rustc = rustToolchain; + }); + + buildSpec = spec.buildSpec // { + src = craneLib.cleanCargoSource ../../../.; + doCheck = false; + cargoExtraArgs = let flags = [ "--no-default-features" ] ++ featureFlags; + in builtins.concatStringsSep " " flags; + }; + + cargoArtifacts = craneLib.buildDepsOnly buildSpec; + +in craneLib.buildPackage (buildSpec // { + inherit cargoArtifacts; + inherit (util) version SURREAL_BUILD_METADATA; +}) diff --git a/pkg/nix/drv/docker.nix b/pkg/nix/drv/docker.nix new file mode 100644 index 00000000..01d46a9d --- /dev/null +++ b/pkg/nix/drv/docker.nix @@ -0,0 +1,12 @@ +{ cacert, dockerTools, package, util }: + +dockerTools.buildLayeredImage { + name = "surrealdb/surrealdb"; + # Unfortunately Docker doesn't support semver's `+` so we are using `_` instead + tag = "v${builtins.replaceStrings [ "+" ] [ "_" ] util.version}"; + config = { + Env = [ "SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt" ]; + WorkingDir = "/"; + Entrypoint = "${package}/bin/${util.packageName}"; + }; +} diff --git a/pkg/nix/spec/aarch64-unknown-linux-gnu.nix b/pkg/nix/spec/aarch64-unknown-linux-gnu.nix new file mode 100644 index 00000000..f881c589 --- /dev/null +++ b/pkg/nix/spec/aarch64-unknown-linux-gnu.nix @@ -0,0 +1,21 @@ +{ pkgs, target, util }: + +{ + inherit target; + + features = with util.features; [ http ]; + + buildSpec = with pkgs; { + depsBuildBuild = [ clang protobuf perl ]; + + nativeBuildInputs = [ pkg-config ]; + + buildInputs = [ openssl binutils ]; + + CARGO_BUILD_TARGET = target; + + LIBCLANG_PATH = "${llvmPackages.libclang.lib}/lib"; + + OPENSSL_NO_VENDOR = "true"; + }; +} diff --git a/pkg/nix/spec/x86_64-apple-darwin.nix b/pkg/nix/spec/x86_64-apple-darwin.nix new file mode 100644 index 00000000..881a8048 --- /dev/null +++ b/pkg/nix/spec/x86_64-apple-darwin.nix @@ -0,0 +1,21 @@ +{ pkgs, target, util }: + +{ + inherit target; + + features = with util.features; [ http ]; + + buildSpec = with pkgs; { + depsBuildBuild = [ clang protobuf perl ]; + + nativeBuildInputs = [ pkg-config ]; + + buildInputs = [ openssl ]; + + CARGO_BUILD_TARGET = target; + + LIBCLANG_PATH = "${llvmPackages.libclang.lib}/lib"; + + OPENSSL_NO_VENDOR = "true"; + }; +} diff --git a/pkg/nix/spec/x86_64-pc-windows-gnu.nix b/pkg/nix/spec/x86_64-pc-windows-gnu.nix new file mode 100644 index 00000000..f057df28 --- /dev/null +++ b/pkg/nix/spec/x86_64-pc-windows-gnu.nix @@ -0,0 +1,17 @@ +{ pkgs, target, util }: + +{ + inherit target; + + features = with util.features; [ default ]; + + buildSpec = with pkgs; { + strictDeps = true; + + depsBuildBuild = [ pkgsCross.mingwW64.stdenv.cc ]; + + buildInputs = [ pkgsCross.mingwW64.windows.pthreads ]; + + CARGO_BUILD_TARGET = target; + }; +} diff --git a/pkg/nix/spec/x86_64-unknown-linux-gnu.nix b/pkg/nix/spec/x86_64-unknown-linux-gnu.nix new file mode 100644 index 00000000..46118e64 --- /dev/null +++ b/pkg/nix/spec/x86_64-unknown-linux-gnu.nix @@ -0,0 +1,27 @@ +{ pkgs, target, util }: + +{ + inherit target; + + features = with util.features; + [ default storage-tikv ] + ++ pkgs.lib.lists.optional (util.fdbSupported pkgs.fdbPackages) + [ storage-fdb ]; + + buildSpec = with pkgs; + let crossCompiling = !util.isNative target; + in { + depsBuildBuild = [ clang cmake gcc10 perl protobuf grpc llvm ] + ++ lib.lists.optional crossCompiling qemu; + + nativeBuildInputs = [ pkg-config ]; + + buildInputs = [ openssl ] + ++ lib.lists.optional (util.fdbSupported fdbPackages) + (util.fdbPackage fdbPackages); + + LIBCLANG_PATH = "${llvmPackages.libclang.lib}/lib"; + + CARGO_BUILD_TARGET = target; + }; +} diff --git a/pkg/nix/spec/x86_64-unknown-linux-musl.nix b/pkg/nix/spec/x86_64-unknown-linux-musl.nix new file mode 100644 index 00000000..51ef2af9 --- /dev/null +++ b/pkg/nix/spec/x86_64-unknown-linux-musl.nix @@ -0,0 +1,17 @@ +{ pkgs, target, util }: + +{ + inherit target; + + buildSpec = with pkgs; { + nativeBuildInputs = with pkgsStatic; [ stdenv.cc openssl ]; + + CARGO_BUILD_RUSTFLAGS = "-C target-feature=+crt-static"; + CARGO_BUILD_TARGET = target; + + OPENSSL_NO_VENDOR = "true"; + OPENSSL_STATIC = "true"; + OPENSSL_LIB_DIR = "${pkgsStatic.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgsStatic.openssl.dev}/include"; + }; +} diff --git a/pkg/nix/util.nix b/pkg/nix/util.nix new file mode 100644 index 00000000..072c7530 --- /dev/null +++ b/pkg/nix/util.nix @@ -0,0 +1,96 @@ +{ lib, flake, systems, system }: + +rec { + inherit systems system; + + config = import ./config.nix; + + supportedPlatforms = let + specDir = builtins.readDir ./spec; + nixExt = ".nix"; + nixFilesFun = key: val: + val == "regular" && lib.strings.hasSuffix nixExt key; + trimNixExtFun = key: val: lib.strings.removeSuffix nixExt key; + nixFiles = lib.attrsets.filterAttrs nixFilesFun specDir; + in lib.attrsets.mapAttrsToList trimNixExtFun nixFiles; + + systemPlatforms = let + matchingPlatforms = target: + let targetSystem = targetToSystem target; + in targetSystem == system; + in builtins.filter matchingPlatforms supportedPlatforms; + + platforms = let + kvFun = platform: { + name = platform; + value = platform; + }; + in builtins.listToAttrs (map kvFun supportedPlatforms); + + targetToEnv = target: + let withoutDashes = builtins.replaceStrings [ "-" ] [ "_" ] target; + in lib.strings.toUpper withoutDashes; + + targetToUpperEnv = target: lib.strings.toUpper (targetToEnv target); + + targetToSystem = with builtins; + target: + let + parts = split "-" target; + arch = elemAt parts 0; + prefix = lib.strings.optionalString (arch == "armv7") "l"; + os = elemAt parts 4; + in "${arch}${prefix}-${os}"; + + isNative = target: + let targetSystem = targetToSystem target; + in targetSystem == system; + + cpu = with builtins; + target: + let + parts = split "-" target; + arch = elemAt parts 0; + in if arch == "armv7" then replaceStrings [ "v7" ] [ "" ] arch else arch; + + cargoToml = with builtins; + let toml = readFile ../../Cargo.toml; + in fromTOML toml; + + packageName = cargoToml.package.name; + + fdbPackage = fdbPackages: + let + fdbPkgVersion = builtins.replaceStrings [ "." ] [ "" ] config.fdbVersion; + in fdbPackages."foundationdb${fdbPkgVersion}"; + + fdbSupported = fdbPackages: + let + package = fdbPackage fdbPackages; + fdbSystems = package.meta.platforms or [ ]; + in builtins.elem system fdbSystems; + + features = cargoToml.features // { + storage-fdb = let + fdbFeatureVersion = + builtins.replaceStrings [ "." ] [ "_" ] config.fdbVersion; + in [ "surrealdb/kv-fdb-${fdbFeatureVersion}" ]; + }; + + buildMetadata = with lib.strings; + let + lastModifiedDate = flake.lastModifiedDate or flake.lastModified or ""; + date = builtins.substring 0 8 lastModifiedDate; + shortRev = flake.shortRev or "dirty"; + hasDateRev = lastModifiedDate != "" && shortRev != ""; + dot = optionalString hasDateRev "."; + in "${date}${dot}${shortRev}"; + + version = with lib.strings; + let + hasBuildMetadata = buildMetadata != ""; + plus = optionalString hasBuildMetadata "+"; + in "${cargoToml.package.version}${plus}${buildMetadata}"; + + SURREAL_BUILD_METADATA = buildMetadata; +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 00000000..fa2a56c7 --- /dev/null +++ b/shell.nix @@ -0,0 +1,6 @@ +(import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock); +in fetchTarball { + url = + "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; +}) { src = ./.; }).shellNix