diff --git a/.github/workflows/build-and-push-container.yml b/.github/workflows/build-and-push-container.yml new file mode 100644 index 0000000..9920535 --- /dev/null +++ b/.github/workflows/build-and-push-container.yml @@ -0,0 +1,29 @@ +name: test suite +on: [ push, pull_request ] + +jobs: + build: + name: build-container + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: install nix + uses: cachix/install-nix-action@v27 + - name: setup nix cache + id: nix-package-cache + uses: actions/cache@v4 + with: + path: ~/work/nix-store + key: nix-package-chache-${{ runner.os }}-${{ hashFiles('./nix/versions.nix') }} + - name: install just + uses: extractions/setup-just@v2 + - name: login to ghcr.io + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: build debug container + run: just build-container debug + - name: push debug container + run: just push-container debug diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a7328b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/.idea +/sysroot diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..5353300 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,382 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "doxygen-rs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9" +dependencies = [ + "phf", +] + +[[package]] +name = "dpdk-sys" +version = "0.0.1" +dependencies = [ + "bindgen", + "doxygen-rs", + "dpdk-sysroot-helper", +] + +[[package]] +name = "dpdk-sysroot-helper" +version = "0.0.1" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "prettyplease" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "regex" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..76e6809 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,45 @@ +[workspace] + +members = [ + "dpdk-sys", + "dpdk-sysroot-helper", +] +resolver = "2" + +[workspace.dependencies] + +bindgen = { version = "0.70.1" } +cc = { version = "1.1.21" } +doxygen-rs = { version = "0.4.0" } +rustc_version = { version = "0.4.1" } + +[profile.release] +opt-level = 3 +lto = "thin" +codegen-units = 1 +overflow-checks = false +strip = "none" +# NOTE: I expect that we will use objcopy / strip to keep the debug symbols in a separate file +# We _could_ just compile without them, but if you need debug symbols for a release build, you +# are already having a rough day, and if you need them and don't have them, then you are having a +# worse day :) +# +# That said, debug-assertions should still be false so that compiler optimizations are not +# inhibited. +debug = true +debug-assertions = false + +[profile.dev] +opt-level = 0 +lto = false +incremental = true +debug = true + +[profile.analysis] +inherits = "dev" +codegen-units = 1 +lto = "thin" +incremental = false + +[profile.fuzz] +inherits = "release" diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..b70bad0 --- /dev/null +++ b/default.nix @@ -0,0 +1,257 @@ +{ + llvm-version ? "18", + profile ? "debug", + crossEnv ? "gnu64", + build-flags-file ? ./nix/flags.nix, + versions ? import ./nix/versions.nix, +}: rec { + toolchainPkgs = import (fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/${versions.nix.commit}.tar.gz"; + sha256 = versions.nix.hash.nar.sha256; + }) {}; + project-name = "dpdk-sys"; + build-flags = (import build-flags-file).${profile}; + crossOverlay = crossEnv: self: super: rec { + inherit build-flags; + buildWithFlags = flags: pkg: (pkg.overrideAttrs (orig: { + CFLAGS = "${orig.CFLAGS or ""} ${flags.CFLAGS}"; + CXXFLAGS = "${orig.CXXFLAGS or ""} ${flags.CXXFLAGS}"; + LDFLAGS = "${orig.LDFLAGS or ""} ${flags.LDFLAGS}"; + })); + llvmPackagesVersion = "llvmPackages_${llvm-version}"; + llvmPackages = super.${llvmPackagesVersion}; + customStdenv = self.stdenvAdapters.makeStaticLibraries ( + self.stdenvAdapters.useMoldLinker ( + if crossEnv == "musl64" then + self.pkgsMusl.${llvmPackagesVersion}.libcxxStdenv + else if crossEnv == "gnu64" then + llvmPackages.stdenv + else + llvmPackages.stdenv + ) + ); + # NOTE: libmd and libbsd customizations will cause an infinite recursion if done with normal overlay methods + customLibmd = ((buildWithMyFlags (super.libmd)).override { stdenv = customStdenv; }).overrideAttrs (orig: { + configureFlags = orig.configureFlags ++ ["--enable-static" "--disable-shared"]; + postFixup = (orig.postFixup or "") + '' + rm $out/lib/*.la + ''; + }); + customLibbsd = ((buildWithMyFlags super.libbsd).override { + stdenv = customStdenv; libmd = customLibmd; + }).overrideAttrs (orig: { + doCheck = false; + configureFlags = orig.configureFlags ++ ["--enable-static" "--enable-shared"]; + postFixup = (orig.postFixup or "") + '' + rm $out/lib/*.la + ''; + }); + buildWithMyFlags = pkg: (buildWithFlags build-flags pkg); + optimizedBuild = pkg: (buildWithMyFlags (pkg.override { + stdenv = customStdenv; + })); + fatLto = pkg: pkg.overrideAttrs (orig: { + CFLAGS = "${orig.CFLAGS or ""} -ffat-lto-objects"; + }); + rdma-core = (fatLto (optimizedBuild super.rdma-core)).overrideAttrs (orig: { + cmakeFlags = orig.cmakeFlags ++ [ + "-DENABLE_STATIC=1" + ]; + }); + iptables = null; + ethtool = null; + iproute2 = null; + libnl = (optimizedBuild super.libnl).overrideAttrs (orig: { + configureFlags = orig.configureFlags ++ [ + "--enable-static" + "--disable-shared" + ]; + postFixup = (orig.postFixup or "") + '' + rm $out/lib/*.la + ''; + }); + jansson = (optimizedBuild super.jansson).overrideAttrs (orig: { + cmakeFlags = [ + "-DJANSSON_BUILD_SHARED_LIBS=OFF" + ]; + }); + libmnl = optimizedBuild super.libmnl; + libnetfilter_conntrack = optimizedBuild super.libnetfilter_conntrack; + libnftnl = optimizedBuild super.libnftnl; + libpcap = optimizedBuild super.libpcap; + numactl = (optimizedBuild super.numactl).overrideAttrs (orig: { + outputs = super.lib.lists.remove "man" orig.outputs; + configurePhase = '' + set -euxo pipefail; + ./configure \ + --prefix=$out \ + --libdir=$out/lib \ + --includedir=$out/include \ + --enable-static \ + --enable-shared; + ''; + buildPhase = '' + set -euxo pipefail; + make; + rm ./.libs/*.la; + ''; + }); + dpdk = (optimizedBuild (self.callPackage ./nix/dpdk { + libbsd = customLibbsd; libmd = customLibmd; + })); + dpdk-wrapper = (optimizedBuild (self.callPackage ./nix/dpdk-wrapper { + libbsd = customLibbsd; inherit dpdk; + })); + }; + + pkgsCross = (import toolchainPkgs.path { + overlays = [ + (self: prev: { + pkgsCross.gnu64 = import prev.path { + overlays = [(crossOverlay "gnu64")]; + }; + pkgsCross.musl64 = import prev.path { + overlays = [(crossOverlay "musl64")]; + }; + }) + ]; + }).pkgsCross; + + sysrootPackageListFn = pkgs: with pkgs; ( + [ + dpdk + dpdk-wrapper + customLibbsd.dev + customLibmd + libmnl + libnftnl + libnl.out + libpcap + numactl + rdma-core + ] ++ + (if customStdenv.targetPlatform.isGnu then [ glibc.out libgcc.libgcc ] else []) + ++ + (if customStdenv.targetPlatform.isMusl then [ musl.out ] else []) + ); + + sysrootPackageList = { + gnu64 = sysrootPackageListFn pkgsCross.gnu64; + musl64 = sysrootPackageListFn pkgsCross.musl64; + }; + + + toolchainPackageList = (with toolchainPkgs; let + # mdbook-citeproc = import ./nix/mdbook-citeproc.nix ({ + # stdenv = pkgs.stdenv; + # inherit lib fetchFromGitHub rustPlatform CoreServices; + # }); + # mdbook-alerts = import ./nix/mdbook-alerts.nix ({ + # stdenv = pkgs.stdenv; + # inherit lib fetchFromGitHub rustPlatform CoreServices; + # }); + in [ + # mdbook-alerts + # mdbook-citeproc + bash + bash-completion + cacert + coreutils + docker + git + just + llvmPackages.clang + llvmPackages.compiler-rt + llvmPackages.libclang.lib + llvmPackages.libcxx + llvmPackages.lld + llvmPackages.llvm + mdbook + mdbook-admonish + mdbook-katex + mdbook-mermaid + mdbook-plantuml + mold + nix + pandoc # needed for mdbook-citeproc to work (runtime exe dep) + plantuml # needed for mdbook-plantuml to work (runtime exe dep) + rustup + ] + ); + + + env = { + + sysroot.gnu64 = toolchainPkgs.buildEnv { + name = "${project-name}-sysroot-gnu64"; + paths = sysrootPackageList.gnu64; + pathsToLink = [ "/include" "/lib" ]; + }; + + sysroot.musl64 = toolchainPkgs.buildEnv { + name = "${project-name}-sysroot-musl64"; + paths = sysrootPackageList.musl64; + pathsToLink = [ "/include" "/lib" ]; + }; + + + toolchain = toolchainPkgs.buildEnv { + name = "${project-name}-toolchain"; + paths = toolchainPackageList; + pathsToLink = [ "/" ]; + }; + }; + + sysroot = toolchainPkgs.stdenv.mkDerivation { + name = "${project-name}-sysroot"; + src = ./.; + buildPhase = '' + mkdir -p $out; + ln -s ${env.sysroot.musl64} $out/x86_64-unknown-linux-musl; + ln -s ${env.sysroot.gnu64} $out/x86_64-unknown-linux-gnu; + ''; + }; + + build = toolchainPkgs.stdenv.mkDerivation { + name = "${project-name}-dir"; + src = env.toolchain; + buildPhase = '' + mkdir -p $out + cp -r ${env.toolchain}/* $out/ + mkdir -p $out/sysroot + ln -s ${env.sysroot.musl64} $out/sysroot/x86_64-unknown-linux-musl; + ln -s ${env.sysroot.gnu64} $out/sysroot/x86_64-unknown-linux-gnu; + mkdir $out/tmp + ''; + }; + + dockerEnvs = [ + "LD_LIBRARY_PATH=/lib" + ]; + + container = { + toolchain = toolchainPkgs.dockerTools.buildLayeredImage { + name = "ghcr.io/githedgehog/dpdk-sys/toolchain"; + tag = "latest"; + contents = [ env.toolchain ]; + maxLayers = 120; + config = { + Cmd = [ "/bin/bash" ]; + WorkingDir = "/"; + Env = dockerEnvs; + }; + + }; + dev-env = toolchainPkgs.dockerTools.buildLayeredImage { + name = "ghcr.io/githedgehog/dpdk-sys/dev-env"; + tag = profile; + contents = [ build ]; + config = { + Cmd = [ "/bin/bash" ]; + WorkingDir = "/"; + Env = dockerEnvs; + }; + maxLayers = 120; + }; + }; +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..e80d9f1 --- /dev/null +++ b/justfile @@ -0,0 +1,17 @@ +default_target := "x86_64-unknown-linux-musl" +default_toolchain := "stable" +default_profile := "debug" +container_name := "ghcr.io/githedgehog/dpdk-sys/dev-env" + +default: build-container + +install-nix: + sh <(curl -L https://nixos.org/nix/install) --no-daemon + +build-container profile=default_profile *args="": + nix build --keep-failed --print-build-logs --show-trace -f default.nix container.dev-env --out-link container.dev-env {{args}} + docker load --input ./container.dev-env + docker tag "{{container_name}}:{{profile}}" "{{container_name}}:{{profile}}-$(git rev-parse HEAD)" + +push-container profile=default_profile: + docker push "{{container_name}}:{{profile}}-$(git rev-parse HEAD)" diff --git a/nix/dpdk-wrapper/default.nix b/nix/dpdk-wrapper/default.nix new file mode 100644 index 0000000..1b22d10 --- /dev/null +++ b/nix/dpdk-wrapper/default.nix @@ -0,0 +1,49 @@ +{ + stdenv, + clang, + dpdk, + llvm, + libbsd, + libnl, +}: stdenv.mkDerivation { + pname = "dpdk-wrapper"; + version = "24.07"; + + src = ./src; + + nativeBuildInptus = [ + clang + dpdk + libbsd.dev + libnl + llvm + ]; + + buildPhase = '' + set euxo pipefail + mkdir -p $out/{lib,include} + ${stdenv.cc}/bin/clang \ + -Wno-deprecated-declarations \ + -Ic \ + -O3 \ + -flto=thin \ + -fretain-comments-from-system-headers \ + -fparse-all-comments \ + -march=native \ + -ggdb3 \ + -march=x86-64-v4 \ + -mtune=znver4 \ + -Werror=odr \ + -Werror=strict-aliasing \ + -fstack-protector-strong \ + -I${dpdk}/include \ + -I${libbsd.dev}/include \ + -c \ + $src/dpdk_wrapper.c \ + -o \ + wrapper.o; + ${llvm}/bin/llvm-ar rcs $out/lib/libdpdk_wrapper.a wrapper.o; + cp $src/*.h $out/include + ''; + +} diff --git a/nix/dpdk-wrapper/src/dpdk_wrapper.c b/nix/dpdk-wrapper/src/dpdk_wrapper.c new file mode 100644 index 0000000..1e3f643 --- /dev/null +++ b/nix/dpdk-wrapper/src/dpdk_wrapper.c @@ -0,0 +1,13 @@ +#include "dpdk_wrapper.h" + +int wrte_errno() { + return rte_errno; +} + +uint16_t wrte_eth_rx_burst(uint16_t const port_id, uint16_t const queue_id, struct rte_mbuf **rx_pkts, uint16_t const nb_pkts) { + return rte_eth_rx_burst(port_id, queue_id, rx_pkts, nb_pkts); +} + +uint16_t wrte_eth_tx_burst(uint16_t const port_id, uint16_t const queue_id, struct rte_mbuf **tx_pkts, uint16_t const nb_pkts) { + return rte_eth_tx_burst(port_id, queue_id, tx_pkts, nb_pkts); +} diff --git a/nix/dpdk-wrapper/src/dpdk_wrapper.h b/nix/dpdk-wrapper/src/dpdk_wrapper.h new file mode 100644 index 0000000..6315489 --- /dev/null +++ b/nix/dpdk-wrapper/src/dpdk_wrapper.h @@ -0,0 +1,305 @@ +// Trace point and and trace point register need to be included before other headers +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//int const rte_get_errno(); + +//enum rte_eth_tx_offload: uint64_t { +// VLAN_INSERT = RTE_ETH_TX_OFFLOAD_VLAN_INSERT, +// IPV4_CKSUM = RTE_ETH_TX_OFFLOAD_IPV4_CKSUM, +// UDP_CKSUM = RTE_ETH_TX_OFFLOAD_UDP_CKSUM, +// TCP_CKSUM = RTE_ETH_TX_OFFLOAD_TCP_CKSUM, +// SCTP_CKSUM = RTE_ETH_TX_OFFLOAD_SCTP_CKSUM, +// TCP_TSO = RTE_ETH_TX_OFFLOAD_TCP_TSO, +// UDP_TSO = RTE_ETH_TX_OFFLOAD_UDP_TSO, +// OUTER_IPV4_CKSUM = RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM, +// QINQ_INSERT = RTE_ETH_TX_OFFLOAD_QINQ_INSERT, +// VXLAN_TNL_TSO = RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO, +// GRE_TNL_TSO = RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO, +// IPIP_TNL_TSO = RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO, +// GENEVE_TNL_TSO = RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO, +// MACSEC_INSERT = RTE_ETH_TX_OFFLOAD_MACSEC_INSERT, +//}; + +//enum rte_flow_port_flag: uint32_t { +// /** +// * Indicate all operations for a given flow rule will _strictly_ +// * happen on the same queue (create/destroy/query/update). +// */ +// STRICT_QUEUE = RTE_FLOW_PORT_FLAG_STRICT_QUEUE, +// +// /** +// * Indicate all steering objects should be created on contexts +// * of the host port, providing indirect object sharing between +// * ports. +// */ +// SHARE_INDIRECT = RTE_FLOW_PORT_FLAG_SHARE_INDIRECT +//}; + + + + +// Things which are either duplicated, totally inapplicable or not needed +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include // this is an internal header +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + +/** + * Thin wrapper to expose `rte_errno`. + * + * @return + * The last rte_errno value (thread local value). + */ +__rte_hot +__rte_warn_unused_result +int wrte_errno(); + +///** +// * DPDK specific error codes. +// * +// * I wrapped these because the original enum is anonymous (this irritates me). +// */ +//enum wrte_errno : uint32_t { +// RTE_MIN_ERRNO = __ELASTERROR, /**< Start numbering above std errno vals */ +// +// E_RTE_SECONDARY, /**< Operation not allowed in secondary processes */ +// E_RTE_NO_CONFIG, /**< Missing rte_config */ +// +// RTE_MAX_ERRNO /**< Max RTE error number */ +//}; + +/** + * TX offloads to be set in [`rte_eth_tx_mode.offloads`]. + * + * This is a bitfield. Union these to enable multiple offloads. + * + * I wrapped these because the enum must be explicitly typed as 64 bit, but + * DPDK is not yet using the C23 standard (which would allow the inheritance + * notation with `uint64_t` seen here.). + */ +enum wrte_eth_tx_offload: uint64_t { + VLAN_INSERT = RTE_ETH_TX_OFFLOAD_VLAN_INSERT, + IPV4_CKSUM = RTE_ETH_TX_OFFLOAD_IPV4_CKSUM, + UDP_CKSUM = RTE_ETH_TX_OFFLOAD_UDP_CKSUM, + TCP_CKSUM = RTE_ETH_TX_OFFLOAD_TCP_CKSUM, + SCTP_CKSUM = RTE_ETH_TX_OFFLOAD_SCTP_CKSUM, + TCP_TSO = RTE_ETH_TX_OFFLOAD_TCP_TSO, + UDP_TSO = RTE_ETH_TX_OFFLOAD_UDP_TSO, + OUTER_IPV4_CKSUM = RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM, + QINQ_INSERT = RTE_ETH_TX_OFFLOAD_QINQ_INSERT, + VXLAN_TNL_TSO = RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO, + GRE_TNL_TSO = RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO, + IPIP_TNL_TSO = RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO, + GENEVE_TNL_TSO = RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO, + MACSEC_INSERT = RTE_ETH_TX_OFFLOAD_MACSEC_INSERT, +}; + + +/** + * Thin wrapper around `rte_eth_rx_burst`. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param queue_id + * The index of the receive queue on the Ethernet device. + * @param rx_pkts + * The address of an array of pointers to [`rte_mbuf`] structures that must be + * large enough to store `nb_pkts` pointers in it. + * @param nb_pkts + * The maximum number of packets to receive. + * @return + * The number of packets received, which is the number of [`rte_mbuf`] structures + */ +__rte_hot +__rte_warn_unused_result +uint16_t wrte_eth_rx_burst(uint16_t const port_id, uint16_t const queue_id, struct rte_mbuf **rx_pkts, uint16_t const nb_pkts); + +/** + * Thin wrapper around [`rte_eth_tx_burst`]. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param queue_id + * The index of the transmit queue on the Ethernet device. + * @param tx_pkts + * The address of an array of pointers to [`rte_mbuf`] structures that contain + * @param nb_pkts + * The number of packets to transmit. + * @return + * The number of packets actually sent. + */ +__rte_hot +__rte_warn_unused_result +uint16_t wrte_eth_tx_burst(uint16_t const port_id, uint16_t const queue_id, struct rte_mbuf **tx_pkts, uint16_t const nb_pkts); diff --git a/nix/dpdk/default.nix b/nix/dpdk/default.nix new file mode 100644 index 0000000..1791412 --- /dev/null +++ b/nix/dpdk/default.nix @@ -0,0 +1,286 @@ +# This is copied from nixpkgs and modified significantly +{ stdenv, lib +, fetchurl +, pkg-config, meson, ninja, makeWrapper +, libbsd, numactl, libbpf, zlib, elfutils, jansson, openssl, libpcap, rdma-core, libnl, libmd +, doxygen, python3, pciutils +, withExamples ? [] +}: + +stdenv.mkDerivation rec { + pname = "dpdk"; + version = "24.07"; + + src = fetchurl { + url = "https://fast.dpdk.org/rel/dpdk-${version}.tar.xz"; + sha256 = "sha256-mUT35fJo56ybQZPizVTvbZj24dfd3JZ8d65PZhbW+70="; + }; + + nativeBuildInputs = [ + makeWrapper + doxygen + meson + ninja + pkg-config + python3 + python3.pkgs.sphinx + python3.pkgs.pyelftools + libnl + rdma-core + ]; + + buildInputs = [ + jansson + libbpf + elfutils + libpcap + numactl + openssl.dev + zlib + python3 + ]; + + propagatedBuildInputs = [ + # Propagated to support current DPDK users in nixpkgs which statically link + # with the framework (e.g. odp-dpdk). + rdma-core + # Requested by pkg-config. + (libbsd.override { inherit libmd; }) + ]; + + postPatch = '' + patchShebangs config/arm buildtools + ''; + + LDFLAGS = ''-Wl,--push-state -Wl,--as-needed -l:libibverbs.a -l:libmlx5.a -l:libjansson.a -l:libnl-route-3.a -l:libnl-3.a -l:libbsd.a -l:libmd.a -Wl,--pop-state''; + + disabledLibs = [ + "acl" + "argparse" + "bbdev" + "bitratestats" + "bpf" + "cfgfile" + "compressdev" + "cryptodev" + "dispatcher" + "distributor" + "dmadev" + "efd" + "eventdev" + "fib" + "gpudev" + "graph" + "gro" + "gso" + "ip_frag" + "ipsec" + "jobstats" + "latencystats" + "lpm" + "member" + "metrics" + "mldev" + "node" + "pcapng" + "pdcp" + "pdump" + "pipeline" + "port" + "power" + "ptr_compress" + "rawdev" + "regexdev" + "reorder" + "rib" + "sched" + "security" + "table" + "timer" + "vhost" + ]; + + disabledDrivers = [ + "baseband/*" + "bus/ifpga" + "bus/vdev" + "bus/vmbus" + "common/cnxk" + "common/cpt" + "common/dpaax" + "common/iavf" + "common/octeontx" + "common/octeontx2" + "common/qat" + "common/sfc_efx" + "compress/mlx5" + "compress/zlib" + "crypto/aesni_gcm" + "crypto/aesni_mb" + "crypto/bcmfs" + "crypto/ccp" + "crypto/kasumi" + "crypto/mlx5" + "crypto/nitrox" + "crypto/null" + "crypto/openssl" + "crypto/scheduler" + "crypto/snow3g" + "crypto/virtio" + "crypto/zuc" + "event/dlb" + "event/dsw" + "event/opdl" + "event/skeleton" + "event/sw" + "net/acc100" + "net/af_packet" + "net/af_xdp" + "net/ark" + "net/atlantic" + "net/avp" + "net/axgbe" + "net/bcmfs" + "net/bnx2x" + "net/bnxt" + "net/bond" + "net/caam_jr" + "net/ccp" + "net/cnxk" + "net/cnxk_bphy" + "net/cpt" + "net/cxgbe" + "net/dlb2" + "net/dpaa" + "net/dpaa2" + "net/dpaa2_cmdif" + "net/dpaa2_qdma" + "net/dpaa2_sec" + "net/dpaa_sec" + "net/dpaax" + "net/dsw" + "net/e1000" + "net/ena" + "net/enetc" + "net/enic" + "net/failsafe" + "net/fm10k" + "net/fpga_5gnr_fec" + "net/fpga_lte_fec" + "net/fslmc" + "net/hinic" + "net/hns3" + "net/i40e" + "net/iavf" + "net/ifc" + "net/ifpga" + "net/igc" + "net/ioat" + "net/ionic" + "net/ipn3ke" + "net/ixgbe" + "net/kasumi" + "net/kni" + "net/liquidio" + "net/memif" + "net/mlx4" + "net/netvsc" + "net/nfp" + "net/ngbe" + "net/nitrox" + "net/ntb" + "net/null" + "net/octeontx" + "net/octeontx2" + "net/octeontx2_dma" + "net/octeontx2_ep" + "net/octeontx_ep" + "net/opdl" + "net/pcap" + "net/pfe" + "net/qede" + "net/sfc" + "net/sfc_efx" + "net/skeleton" + "net/snow3g" + "net/softnic" + "net/tap" + "net/thunderx" + "net/turbo_sw" + "net/txgbe" + "net/vdev" + "net/vdev_netvsc" + "net/vhost" + "net/virtio" + "net/vmbus" + "net/vmxnet3" + "net/zuc" + "raw/ioat" + "raw/ntb" + "raw/skeleton" + "regex/mlx5" + "vdpa/ifc" + "vdpa/mlx5" + ]; + + enabledDrivers = [ + "bus/auxiliary" + "bus/pci" + "common/mlx5" + "mempool/bucket" + "mempool/ring" + "mempool/stack" + "net/auxiliary" + "net/mlx5" + "net/ring" + ]; + + mesonFlags = [ + "-Dauto_features=disabled" + "-Db_colorout=never" + "-Db_coverage=false" + "-Db_lto=true" + "-Db_lundef=true" + "-Db_pch=true" + "-Db_pgo=off" + "-Db_pie=true" + "-Db_sanitize=none" + "-Dbackend=ninja" + "-Ddefault_library=static" + "-Denable_docs=false" + "-Denable_driver_sdk=false" + "-Dibverbs_link=static" + "-Dmax_numa_nodes=4" + "-Dstrip=false" # We should strip binaries in a separate step to preserve detached debug info + "-Dtests=false" # Running DPDK tests in CI is usually silly + "-Duse_hpet=false" # TODO: compile kernel with CONFIG_HPET_MMAP=Y + "-Db_lto_mode=thin" + "-Doptimization=3" + "-Ddebug=true" + ''-Ddisable_drivers=${lib.concatStringsSep "," disabledDrivers}'' + ''-Denable_drivers=${lib.concatStringsSep "," enabledDrivers}'' + ''-Ddisable_libs=${lib.concatStringsSep "," disabledLibs}'' + ]; + + postInstall = '' + # Remove Sphinx cache files. Not only are they not useful, but they also + # contain store paths causing spurious dependencies. + rm -rf $out/share/doc/dpdk/html/.doctrees + + wrapProgram $out/bin/dpdk-devbind.py \ + --prefix PATH : "${lib.makeBinPath [ pciutils ]}" + '' + lib.optionalString (withExamples != []) '' + mkdir -p $examples/bin + find examples -type f -executable -exec install {} $examples/bin \; + ''; + + outputs = [ "out" ] ++ lib.optional (withExamples != []) "examples"; + + meta = with lib; { + description = "Set of libraries and drivers for fast packet processing"; + homepage = "http://dpdk.org/"; + license = with licenses; [ lgpl21 gpl2 bsd2 ]; + platforms = platforms.linux; + maintainers = with maintainers; [ magenbluten orivej mic92 zhaofengli ]; + }; +} diff --git a/nix/flags.nix b/nix/flags.nix new file mode 100644 index 0000000..c2c708c --- /dev/null +++ b/nix/flags.nix @@ -0,0 +1,13 @@ +{ + release = rec { + CFLAGS="-O3 -ggdb3 -march=x86-64-v4 -mtune=znver4 -flto=thin -Werror=odr -Werror=strict-aliasing -fstack-protector-strong -Qunused-arguments"; + CXXFLAGS=CFLAGS; + LDFLAGS="-Wl,-O3 -Wl,--gc-sections -Wl,-z,relro,-z,now -Qunused-arguments"; + }; + + debug = rec { + CFLAGS="-Og -ggdb3 -fno-inline -Qunused-arguments"; + CXXFLAGS=CFLAGS; + LDFLAGS=""; + }; +} diff --git a/nix/versions.nix b/nix/versions.nix new file mode 100644 index 0000000..56b7ac5 --- /dev/null +++ b/nix/versions.nix @@ -0,0 +1,23 @@ +{ + nix = { + branch = "nixpkgs-unstable"; + date = "2024-10-01T22:40:38+00:00"; + commit = "9682b2197dabc185fcca802ac1ac21136e48fcc2"; + source_url = "https://github.com/NixOS/nixpkgs/archive/9682b2197dabc185fcca802ac1ac21136e48fcc2.tar.gz"; + hash = { + nar = { + comment = "nix-prefetch-url generated hash of the tar.gz file obtained from github archive"; + sha256 = "1ywcly5wphkk20sbqa5r79341wdx551b0nhdmri1qgp48b3niw6q"; + }; + tar = { + comment = "openssl generated hashes of the actual tar.gz file obtained from github archive"; + sha256 = "5eb48eb40b788dfa1fb538e1d74e225c2a6e00bb173557471ea23379115d35fa"; + sha384 = "cecef9cd2575fac1e9e3323222ad4f1809878d67e9d9117a5b490f11782201e2851cad70b5777db9672937bb1d34f695"; + sha512 = "6683a7613d6cb7559c297cd9e2dd66ad1d029f2001e71d4309c229c080a5176b370eb25bf03d0da30dc85925e5de15f4fdb3d4f92e95f54c10abd7f3a8a8b218"; + sha3_256 = "e4105493a4fb7829f9c41a2d4683332a7bd6d45e736329a23f97e2a19eced97e"; + sha3_384 = "1488d6fe422280ae11f3ab56c4b02d52c116aab12751f1b362407c5253ad1ba0ac847332e0de716b5622845ac25eb6df"; + sha3_512 = "4a9e40740f008d9ede2b9d644f8f91e11b51de330f2acb8ce8f111d8730bb5ad343ddf09f330c50988b018c0fafbd589d64fe471a167441bb00e186cfb1e2254"; + }; + }; + }; +} diff --git a/nix/versions.nix.template b/nix/versions.nix.template new file mode 100644 index 0000000..5c7f662 --- /dev/null +++ b/nix/versions.nix.template @@ -0,0 +1,23 @@ +{ + nix = { + branch = "$NIXPKGS_BRANCH"; + date = "$NIXPKGS_DATE"; + commit = "$NIXPKGS_COMMIT"; + source_url = "$NIXPKGS_SOURCE_URL"; + hash = { + nar = { + comment = "nix-prefetch-url generated hash of the tar.gz file obtained from github archive"; + sha256 = "$NIXPKGS_NIX_HASH"; + }; + tar = { + comment = "openssl generated hashes of the actual tar.gz file obtained from github archive"; + sha256 = "$NIXPKGS_TAR_SHA256"; + sha384 = "$NIXPKGS_TAR_SHA384"; + sha512 = "$NIXPKGS_TAR_SHA512"; + sha3_256 = "$NIXPKGS_TAR_SHA3_256"; + sha3_384 = "$NIXPKGS_TAR_SHA3_384"; + sha3_512 = "$NIXPKGS_TAR_SHA3_512"; + }; + }; + }; +} diff --git a/update-version-pinning.sh b/update-version-pinning.sh new file mode 100755 index 0000000..4616dd4 --- /dev/null +++ b/update-version-pinning.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +declare -rx NIXPKGS_BRANCH="nixpkgs-unstable" + +declare script_dir +script_dir="$(readlink -e "$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")")" +declare -r script_dir + +declare -a cleanup_actions=() + +_cleanup() { + declare action + for action in "${cleanup_actions[@]}"; do + ${action} + done +} +trap _cleanup EXIT + +declare nixpkgs_repo +nixpkgs_repo="$(mktemp --directory --suffix=.nixpkgs)" +declare -r nixpkgs_repo + +declare NIXPKGS_DATE +NIXPKGS_DATE="$(date --utc --iso-8601=seconds)" +declare -rx NIXPKGS_DATE + +git clone --depth=1 --branch "${NIXPKGS_BRANCH}" "https://github.com/NixOS/nixpkgs" "${nixpkgs_repo}" +cleanup_actions+=("rm -rf ${nixpkgs_repo}") +pushd "${nixpkgs_repo}" + +declare NIXPKGS_COMMIT +NIXPKGS_COMMIT="$(git rev-parse HEAD)" +declare -rx NIXPKGS_COMMIT + + +declare NIXPKGS_SOURCE_URL +NIXPKGS_SOURCE_URL="https://github.com/NixOS/nixpkgs/archive/${NIXPKGS_COMMIT}.tar.gz" +declare -rx NIXPKGS_SOURCE_URL + +wget --quiet --output-document="${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" "${NIXPKGS_SOURCE_URL}" + +declare NIXPKGS_TAR_SHA256 +declare NIXPKGS_TAR_SHA384 +declare NIXPKGS_TAR_SHA512 +declare NIXPKGS_TAR_SHA3_256 +declare NIXPKGS_TAR_SHA3_384 +declare NIXPKGS_TAR_SHA3_512 + +NIXPKGS_TAR_SHA256="$(openssl dgst -sha2-256 < "${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" | cut -d' ' -f2)" +NIXPKGS_TAR_SHA384="$(openssl dgst -sha2-384 < "${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" | cut -d' ' -f2)" +NIXPKGS_TAR_SHA512="$(openssl dgst -sha2-512 < "${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" | cut -d' ' -f2)" +NIXPKGS_TAR_SHA3_256="$(openssl dgst -sha3-256 < "${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" | cut -d' ' -f2)" +NIXPKGS_TAR_SHA3_384="$(openssl dgst -sha3-384 < "${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" | cut -d' ' -f2)" +NIXPKGS_TAR_SHA3_512="$(openssl dgst -sha3-512 < "${nixpkgs_repo}/${NIXPKGS_BRANCH}.tar.gz" | cut -d' ' -f2)" + +declare -rx NIXPKGS_TAR_SHA256 +declare -rx NIXPKGS_TAR_SHA384 +declare -rx NIXPKGS_TAR_SHA512 +declare -rx NIXPKGS_TAR_SHA3_256 +declare -rx NIXPKGS_TAR_SHA3_384 +declare -rx NIXPKGS_TAR_SHA3_512 + +declare -rx NIXPKGS_NIX_HASH_TYPE=sha256 +declare NIXPKGS_NIX_HASH +NIXPKGS_NIX_HASH="$(nix-prefetch-url --name "${NIXPKGS_BRANCH}" --type "${NIXPKGS_NIX_HASH_TYPE}" --unpack "${NIXPKGS_SOURCE_URL}")" +declare -rx NIXPKGS_NIX_HASH + +pushd "${script_dir}" +envsubst < "${script_dir}/nix/versions.nix.template" > "${script_dir}/nix/versions.nix"