diff options
Diffstat (limited to 'third_party/nix/default.nix')
-rw-r--r-- | third_party/nix/default.nix | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/third_party/nix/default.nix b/third_party/nix/default.nix new file mode 100644 index 000000000000..ad50ac6b7fea --- /dev/null +++ b/third_party/nix/default.nix @@ -0,0 +1,270 @@ +args@{ depot ? (import ../.. { }) +, pkgs ? depot.third_party.nixpkgs +, lib +, buildType ? "release" +, ... +}: + +let + # Override some external dependencies for C++17 & clang compat. + abseil-cpp = pkgs.abseil-cpp.override { + stdenv = pkgs.fullLlvm11Stdenv; + cxxStandard = "17"; + }; + + protobuf = pkgs.callPackage (pkgs.path + "/pkgs/development/libraries/protobuf/generic-v3.nix") { + version = "3.12.2"; + sha256 = "1lp368aa206vpic9fmax4k6llnmf28plfvkkm4vqhgphmjqykvl2"; + stdenv = pkgs.fullLlvm11Stdenv; + buildPackages = { + inherit (pkgs.buildPackages) which; + stdenv = pkgs.buildPackages.fullLlvm11Stdenv; + }; + }; + + re2 = pkgs.re2.override { + stdenv = pkgs.fullLlvm11Stdenv; + }; + + grpc = (pkgs.grpc.override { + inherit abseil-cpp protobuf re2; + stdenv = pkgs.fullLlvm11Stdenv; + }).overrideAttrs (orig: rec { + cmakeFlags = orig.cmakeFlags ++ [ + "-DCMAKE_CXX_STANDARD_REQUIRED=ON" + "-DCMAKE_CXX_STANDARD=17" + ]; + }); + + aws-s3-cpp = pkgs.aws-sdk-cpp.override { + apis = [ "s3" "transfer" ]; + customMemoryManagement = false; + }; + + src = + let + srcDir = ./.; + # create relative paths for all the sources we are filtering + asRelative = path: + let + srcS = toString srcDir; + pathS = toString path; + in + if ! lib.hasPrefix srcS pathS then + throw "Path is outside of the working directory." + else + lib.removePrefix srcS pathS; + + in + builtins.filterSource + (path: type: + # Strip out .nix files that are in the root of the repository. Changing + # the expression of tvix shouldn't cause a rebuild of tvix unless really + # required. + !(dirOf (asRelative path) == "/" && lib.hasSuffix ".nix" path) && + + # remove the proto files from the repo as those are compiled separately + !(lib.hasPrefix "src/proto" (asRelative path)) && + + # ignore result symlinks + !(type == "symlink" && lib.hasPrefix "result" (baseNameOf path)) + ) + srcDir; + + # Proto generation in CMake is theoretically possible, but that is + # very theoretical - this does it in Nix instead. + protoSrcs = pkgs.runCommand "nix-proto-srcs" { } '' + export PROTO_SRCS=${./src/proto} + mkdir -p $out/libproto + ${protobuf}/bin/protoc -I=$PROTO_SRCS \ + --cpp_out=$out/libproto \ + --plugin=protoc-gen-grpc=${grpc}/bin/grpc_cpp_plugin \ + --grpc_out=$out/libproto \ + $PROTO_SRCS/*.proto + ''; + + # Derivation for busybox that just has the `busybox` binary in bin/, not all + # the symlinks, so cmake can find it + busybox = pkgs.runCommand "busybox" { } '' + mkdir -p $out/bin + cp ${pkgs.busybox}/bin/busybox $out/bin + ''; + +in +lib.fix (self: pkgs.fullLlvm11Stdenv.mkDerivation { + pname = "tvix"; + version = "2.3.4"; + inherit src; + + nativeBuildInputs = with pkgs; [ + bison + clang-tools_11 + cmake + libxml2 + libxslt + pkgconfig + (import ./clangd.nix pkgs) + ]; + + # TODO(tazjin): Some of these might only be required for native inputs + buildInputs = (with pkgs; [ + aws-s3-cpp + brotli + bzip2 + c-ares + curl + editline + flex + glog + libseccomp + libsodium + openssl + sqlite + systemd.dev + xz + + # dependencies with custom overrides + abseil-cpp + grpc + protobuf + ]); + + doCheck = false; + doInstallCheck = true; + + # Preserve debug symbols, for core dumps + other live debugging + dontStrip = true; + + installCheckInputs = with depot.third_party; [ + gtest + pkgs.fd + rapidcheck + ]; + + propagatedBuildInputs = with pkgs; [ + boost + ]; + + configurePhase = '' + mkdir build + cd build + cmake .. \ + -DCMAKE_INSTALL_PREFIX=$out \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY=OFF \ + -DCMAKE_FIND_USE_PACKAGE_REGISTRY=OFF \ + -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY=ON + ''; + + installCheckPhase = '' + export NIX_DATA_DIR=$out/share + export NIX_TEST_VAR=foo # this is required by a language test + make test + ''; + + preBuild = '' + if [ -n "$NIX_BUILD_CORES" ]; then + makeFlags+="-j$NIX_BUILD_CORES " + makeFlags+="-l$NIX_BUILD_CORES " + fi + ''; + + # Forward the location of the generated Protobuf / gRPC files so + # that they can be included by CMake. + NIX_PROTO_SRCS = protoSrcs; + + # Work around broken system header include flags in the cxx toolchain. + LIBCXX_INCLUDE = "${pkgs.llvmPackages_11.libcxx}/include/c++/v1"; + + SANDBOX_SHELL = "${pkgs.busybox}/bin/busybox"; + + # Install the various symlinks to the Nix binary which users expect + # to exist. + postInstall = '' + ln -s $out/bin/nix $out/bin/nix-build + ln -s $out/bin/nix $out/bin/nix-channel + ln -s $out/bin/nix $out/bin/nix-collect-garbage + ln -s $out/bin/nix $out/bin/nix-copy-closure + ln -s $out/bin/nix $out/bin/nix-env + ln -s $out/bin/nix $out/bin/nix-hash + ln -s $out/bin/nix $out/bin/nix-instantiate + ln -s $out/bin/nix $out/bin/nix-prefetch-url + ln -s $out/bin/nix $out/bin/nix-shell + ln -s $out/bin/nix $out/bin/nix-store + + mkdir -p $out/libexec/nix + ln -s $out/bin/nix $out/libexec/nix/build-remote + + # configuration variables for templated files + export storedir=/nix/store + export localstatedir=/nix/var + export bindir=$out/bin + + mkdir -p $out/lib/systemd/system + substituteAll \ + ${src}/misc/systemd/nix-daemon.service.in \ + $out/lib/systemd/system/nix-daemon.service + substituteAll \ + ${src}/misc/systemd/nix-daemon.socket.in \ + $out/lib/systemd/system/nix-daemon.socket + + mkdir -p $out/etc/profile.d + substituteAll \ + ${src}/scripts/nix-profile.sh.in $out/etc/profile.d/nix.sh + substituteAll \ + ${src}/scripts/nix-profile-daemon.sh.in $out/etc/profile.d/nix-daemon.sh + ''; + + # TODO(tazjin): integration test setup? + # TODO(tazjin): docs generation? + + passthru = { + build-shell = self.overrideAttrs (up: rec { + run_clang_tidy = pkgs.writeShellScriptBin "run-clang-tidy" '' + test -f compile_commands.json || (echo "run from build output directory"; exit 1) || exit 1 + ${pkgs.jq}/bin/jq < compile_commands.json -r 'map(.file)|.[]' | grep -v '/generated/' | ${pkgs.parallel}/bin/parallel ${pkgs.clang-tools}/bin/clang-tidy -p compile_commands.json $@ + ''; + + installCheckInputs = up.installCheckInputs ++ [ run_clang_tidy ]; + + shellHook = '' + export NIX_DATA_DIR="${toString depot.path}/third_party" + export NIX_TEST_VAR=foo + ''; + }); + + # Ensure formatting is coherent, + # but do this in parallel to the main build because: + # - (in favor of building this after tvix) + # tests run so that developers get all the useful feedback + # - (in favor of building this before tvix) + # if the formatting is broken, and this build was submitted to CI + # it would be a good idea to get this feedback rather sooner than later + # - we don't want builds to differ between local and CI runs + checkfmt = pkgs.fullLlvm11Stdenv.mkDerivation { + name = "tvix-checkfmt"; + inherit src; + nativeBuildInputs = with pkgs; [ clang-tools_11 fd ]; + SANDBOX_SHELL = "${pkgs.busybox}/bin/busybox"; + + buildPhase = '' + set -e + runHook preBuild + fd . $src -e hh -e cc | xargs clang-format --dry-run --Werror + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + touch $out + runHook postInstall + ''; + }; + + test-vm = import ./test-vm.nix args; + }; + + meta.ci.targets = [ + "checkfmt" + ]; +}) |