Hi
I’m looking for feedback on how I can improve this working nix expression for Deno.
There is an open issue on GitHub(#78461) for packaging Deno, and below is an expression that successfully builds it from source (warning: takes 49 minutes on my machine to compile!):
{ pkgs, ... } @ args: let
#
# @TODO: this hack shoves the llvm-* binaries alongside the clang/clang++
# binaries so we can reference them in the CLANG_BASE_PATH env
# var for the [rusty_v8 package][rv8].
#
# [rv8]: https://github.com/denoland/rusty_v8
#
llvm-with-clang = pkgs.stdenv.mkDerivation {
name = "llvm-with-clang";
srcs = [ pkgs.clang_8 pkgs.llvmPackages.bintools ];
unpackPhase = ''
runHook preUnpack
for _src in $srcs; do
cp -r "$_src" $(stripHash "$_src")
done
runHook postUnpack
'';
installPhase = ''
mkdir -p $out/bin
for _src in $srcs; do
cp -r $(stripHash "$_src")/bin/* $out/bin
done
'';
};
in pkgs.rustPlatform.buildRustPackage rec {
name = "deno";
verbose = true;
buildInputs = [
pkgs.pkgconfig
pkgs.python2Full
pkgs.glib
pkgs.gn
pkgs.ninja
pkgs.zlib
llvm-with-clang
];
#
# @TODO: skipping tests for now ~ the deno tests panic in some cases:
#
# ```
# test result: FAILED. 211 passed; 10 failed; 0 ignored; 0 measured; 0 filtered out
# ```
#
# e.g.
#
# ```
# ---- compilers::ts::tests::test_bundle stdout ----
# thread 'compilers::ts::tests::test_bundle' panicked at
# 'called `Result::unwrap()` on an `Err` value:
# ErrBox(Os { code: 13, kind: PermissionDenied, message: "Permission denied" })',
# src/libcore/result.rs:1188:5
# ```
#
checkPhase = ''
echo "skipping checkPhase"
'';
src = pkgs.fetchgit {
url = "https://github.com/denoland/deno.git";
# v0.42.0
# @TODO: update `postUnpack` if you update the version!
rev = "f92bb9cf4de6ed4b6a84a14775e0dbe4ed45291a";
sha256 = "156w1x0kphb2r9xxnwyk2cqxpyf43w1dy9jd544xpydl09p96pql";
fetchSubmodules = true;
};
cargoSha256 = "082wnld3vmyhla666cpf521yrl6bxa3q5mi6xkh62im7xh40mbhn";
#
# @TODO: This is a hack to recreate the necessary dotfiles to build
# the rusty_v8 dependency, namely, `.gn`
#
# When `cargo vendor` is called, it ignores dot-files that exist in
# the rusty_v8 package / source code.
#
# I have a hunch that it's executing this line in cargo:
#
# --> https://github.com/rust-lang/cargo/blob/bf1a26d355f2b12230eeef37b1e8617d90d2db99/src/cargo/sources/path.rs#L167
#
# which explicitally ignores dot-files and directories.
#
# More information here:
#
# --> https://github.com/rust-lang/cargo/issues/7183
#
postUnpack = ''
cargoDepsCopy=$(stripHash $(basename $cargoDeps))
cat > $cargoDepsCopy/rusty_v8/.clang-format <<EOL
BasedOnStyle: google
EOL
cat > $cargoDepsCopy/rusty_v8/.gn <<EOL
# This file is used by the GN meta build system to find the root of the source
# tree and to set startup options. For documentation on the values set in this
# file, run "gn help dotfile" at the command line.
# The location of the build configuration file.
buildconfig = "//build/config/BUILDCONFIG.gn"
# These are the targets to check headers for by default. The files in targets
# matching these patterns (see "gn help label_pattern" for format) will have
# their includes checked for proper dependencies when you run either
# "gn check" or "gn gen --check".
check_targets = []
# The secondary source root is a parallel directory tree where
# GN build files are placed when they can not be placed directly
# in the source tree, e.g. for third party source trees.
secondary_source = "//v8/"
default_args = {
linux_use_bundled_binutils = false
use_sysroot = false
use_dummy_lastchange = true
treat_warnings_as_errors = true
# TODO(ry) remove
v8_imminent_deprecation_warnings = false
# https://cs.chromium.org/chromium/src/docs/ccache_mac.md
clang_use_chrome_plugins = false
v8_enable_i18n_support = false
v8_monolithic = false
v8_use_external_startup_data = false
v8_use_snapshot = true
is_component_build = false
symbol_level = 1
}
EOL
unset cargoDepsCopy
'';
# ==================================================
# Environment Variables
#
V8_FROM_SOURCE = "1";
DENO_GN_PATH = "${pkgs.gn}/bin";
DENO_NINJA_PATH = "${pkgs.ninja}/bin";
NINJA = "${pkgs.ninja}/bin/ninja";
CLANG_BASE_PATH = "${llvm-with-clang}";
GN = "${pkgs.gn}/bin/gn";
GN_ARGS = "no_inline_line_tables=false";
#
# ==================================================
meta = with pkgs.stdenv.lib; {
description = "A secure runtime for JavaScript and TypeScript.";
longDescription = ''
Deno aims to provide a productive and secure scripting environment
for the modern programmer. It is built on top of V8, Rust, and
TypeScript.
'';
homepage = "https://deno.land";
changelog = "https://github.com/denoland/deno/blob/master/Releases.md";
license = licenses.mit;
maintainers = [ ];
platforms = platforms.linux;
};
}
There are multiple hacks going on here:
1. combining llvm-*
and clang
binaries
The cargo package rusty_v8
let’s users set a CLANG_BASE_PATH
environment variable to looks for both clang/clang++
and llvm-ar
binaries. The llvm-with-clang
derivation is a workaround for this lookup.
Also note that, the version of clang & llvm with this hack are different lol:
[/nix/store/*-llvm-with-clang]$ ./bin/clang --version
clang version 8.0.1 (tags/RELEASE_801/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /nix/store/bv17ssmbij00i2xdq4s1xkld1ix2g3b3-clang-8.0.1/bin
[/nix/store/*-llvm-with-clang]$ ./bin/llvm-ar --version
LLVM (http://llvm.org/):
LLVM version 7.1.0
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
but it works so
2. skipping test cases (checkPhase
)
Unfortunately, 10 of the tests fail to pass with cargo test
:
test result: FAILED. 211 passed; 10 failed; 0 ignored; 0 measured; 0 filtered out
What’s the common approach here when dealing with packages who’s test cases are, well, not friendly?
3. re-creating “dotfiles” that cargo vendor
drops
I don’t think this is an issue with Nix at all — see comments above postUnpack
.
This is more of a maintenance nightmare — whenever anyone updates rev
in deno’s fetchgit
, they have to make sure that these re-created files are in-sync with the current deno codebase.
Finishing Thoughts
I’d love to bring Deno to Nix, but I can’t realistically open a PR. This is my first Nix package for a 3rd party project, and, I don’t use GitHub.
The goal is that someone can help champion this into the nixpkgs
repository on my behalf (after the hacks are cleaned up a bit), and, I learn a heck-of-a-lot from interacting with folks on this forum ^_^
.
Help a Nix novice today!
TTFN~