3
0
Fork 0
forked from mirrors/nixpkgs

Merge pull request #7501 from wizeman/u/upd-rust

Add support for Rust / Cargo packaging
This commit is contained in:
Ricardo M. Correia 2015-05-12 17:30:11 +02:00
commit 755df64ee3
17 changed files with 513 additions and 38 deletions

View file

@ -9,6 +9,7 @@ header "exporting $url (rev $rev) into $out"
$fetcher --builder --url "$url" --out "$out" --rev "$rev" \
${leaveDotGit:+--leave-dotGit} \
${deepClone:+--deepClone} \
${fetchSubmodules:+--fetch-submodules}
${fetchSubmodules:+--fetch-submodules} \
${branchName:+--branch-name "$branchName"}
stopNest

View file

@ -13,6 +13,7 @@
in
{ url, rev ? "HEAD", md5 ? "", sha256 ? "", leaveDotGit ? deepClone
, fetchSubmodules ? true, deepClone ? false
, branchName ? null
, name ? urlToName url rev
}:
@ -51,7 +52,7 @@ stdenv.mkDerivation {
outputHashMode = "recursive";
outputHash = if sha256 == "" then md5 else sha256;
inherit url rev leaveDotGit fetchSubmodules deepClone;
inherit url rev leaveDotGit fetchSubmodules deepClone branchName;
GIT_SSL_CAINFO = "${cacert}/etc/ca-bundle.crt";

View file

@ -8,6 +8,7 @@ deepClone=$NIX_PREFETCH_GIT_DEEP_CLONE
leaveDotGit=$NIX_PREFETCH_GIT_LEAVE_DOT_GIT
fetchSubmodules=
builder=
branchName=$NIX_PREFETCH_GIT_BRANCH_NAME
if test -n "$deepClone"; then
deepClone=true
@ -31,6 +32,7 @@ for arg; do
--url) argfun=set_url;;
--rev) argfun=set_rev;;
--hash) argfun=set_hashType;;
--branch-name) argfun=set_branchName;;
--deepClone) deepClone=true;;
--no-deepClone) deepClone=false;;
--leave-dotGit) leaveDotGit=true;;
@ -108,7 +110,7 @@ checkout_hash(){
fi
git fetch ${builder:+--progress} origin || return 1
git checkout -b fetchgit $hash || return 1
git checkout -b $branchName $hash || return 1
}
# Fetch only a branch/tag and checkout it.
@ -131,7 +133,7 @@ checkout_ref(){
if test -n "$ref"; then
# --depth option is ignored on http repository.
git fetch ${builder:+--progress} --depth 1 origin +"$ref" || return 1
git checkout -b fetchgit FETCH_HEAD || return 1
git checkout -b $branchName FETCH_HEAD || return 1
else
return 1
fi
@ -222,7 +224,7 @@ make_deterministic_repo(){
fi
done
# Do a full repack. Must run single-threaded, or else we loose determinism.
# Do a full repack. Must run single-threaded, or else we lose determinism.
git config pack.threads 1
git repack -A -d -f
rm -f .git/config
@ -251,7 +253,7 @@ clone_user_rev() {
fi;;
esac
local full_revision=$(cd $dir && (git rev-parse $rev 2> /dev/null || git rev-parse refs/heads/fetchgit) | tail -n1)
local full_revision=$(cd $dir && (git rev-parse $rev 2> /dev/null || git rev-parse refs/heads/$branchName) | tail -n1)
echo "git revision is $full_revision"
echo "git human-readable version is $(cd $dir && (git describe $full_revision 2> /dev/null || git describe --tags $full_revision 2> /dev/null || echo -- none --))" >&2
echo "Commit date is $(cd $dir && git show --no-patch --pretty=%ci $full_revision)"
@ -268,6 +270,10 @@ clone_user_rev() {
fi
}
if test -z "$branchName"; then
branchName=fetchgit
fi
if test -n "$builder"; then
test -n "$out" -a -n "$url" -a -n "$rev" || usage
mkdir $out

View file

@ -0,0 +1,93 @@
{ stdenv, cacert, git, rustc, cargo, rustRegistry }:
{ name, src, depsSha256, buildInputs ? [], cargoUpdateHook ? "", ... } @ args:
let
fetchDeps = import ./fetchcargo.nix {
inherit stdenv cacert git rustc cargo rustRegistry;
};
cargoDeps = fetchDeps {
inherit name src cargoUpdateHook;
sha256 = depsSha256;
};
# The following is the directory name cargo creates when the registry index
# URL is file:///dev/null
#
# It's OK to use /dev/null as the URL because by the time we do this, cargo
# won't attempt to update the registry anymore, so the URL is more or less
# irrelevant
registryIndexDirName = "-ba82b75dd6681d6f";
in stdenv.mkDerivation (args // {
inherit cargoDeps rustRegistry;
patchRegistryDeps = ./patch-registry-deps;
buildInputs = [ git cargo rustc ] ++ buildInputs;
configurePhase = args.configurePhase or "true";
postUnpack = ''
echo "Using cargo deps from $cargoDeps"
cp -r "$cargoDeps" deps
chmod +w deps -R
cat <<EOF > deps/config
[registry]
index = "file:///dev/null"
EOF
echo "Using rust registry from $rustRegistry"
ln -s "$rustRegistry" "deps/registry/index/${registryIndexDirName}"
export CARGO_HOME="$(realpath deps)"
# Retrieved the Cargo.lock file which we saved during the fetch
mv deps/Cargo.lock $sourceRoot/
(
cd $sourceRoot
cargo fetch
cargo clean
)
'' + (args.postUnpack or "");
prePatch = ''
# Patch registry dependencies, using the scripts in $patchRegistryDeps
(
set -euo pipefail
cd ../deps/registry/src/*
for script in $patchRegistryDeps/*; do
# Run in a subshell so that directory changes and shell options don't
# affect any following commands
( . $script)
done
)
'' + (args.prePatch or "");
buildPhase = args.buildPhase or ''
echo "Running cargo build --release"
cargo build --release
'';
checkPhase = args.checkPhase or ''
echo "Running cargo test"
cargo test
'';
doCheck = args.doCheck or true;
installPhase = args.installPhase or ''
mkdir -p $out/bin
for f in $(find target/release -maxdepth 1 -type f); do
cp $f $out/bin
done;
'';
})

View file

@ -0,0 +1,17 @@
source $stdenv/setup
# cargo-fetch needs to write to Cargo.lock, even to do nothing. We
# create a fake checkout with symlinks and and editable Cargo.lock.
mkdir copy
cd copy
for f in $(ls $src); do
ln -s $src/"$f" .
done
rm Cargo.lock
cp $src/Cargo.lock .
chmod +w Cargo.lock
$fetcher . $out
cd ..
rm -rf copy

View file

@ -0,0 +1,177 @@
#! /bin/sh
source $stdenv/setup
set -euo pipefail
src=$(realpath $1)
out=$(realpath $2)
echo "Fetching $src to $out"
mkdir $out
# Configure cargo to fetch from a local copy of the crates.io registry
echo "Using rust registry from $rustRegistry"
cat <<EOF > $out/config
[registry]
index = "file://$rustRegistry"
EOF
export CARGO_HOME=$out
cd $src
if [[ ! -f Cargo.lock ]]; then
echo "ERROR: The Cargo.lock file doesn't exist"
echo
echo "Cargo.lock is needed to make sure that depsSha256 doesn't change"
echo "when the registry is updated."
exit 1
fi
# We need to do the following string replacement so that 'cargo fetch'
# doesn't ignore the versions specified in Cargo.lock
set +u
substituteInPlace Cargo.lock \
--replace "registry+https://github.com/rust-lang/crates.io-index" \
"registry+file://$rustRegistry"
set -u
# Do any possible 'cargo update -p <pkgName> --precise <version>' ad-hoc updates
eval "$cargoUpdateHook"
# Do the fetch
cargo fetch --verbose
# Now that we have fetched everything, let's make the output deterministic
# Cargo uses the following directory structure for fetched data, where
# $indexHash is a hash of the registry index URL:
#
#
# /config:
#
# Cargo config file. We'll delete this because it's not deterministic,
# and instead recreate it just before running 'cargo build'.
#
# /registry/cache/$indexHash/:
#
# This is where tarballs of registry package dependencies are kept
# We'll need to keep this, but make sure $indexHash is a fixed name.
#
# /registry/index/$indexHash/:
#
# A copy of the registry index is kept here. We can delete this, and
# instead, just before running 'cargo build', we'll symlink this
# directory to our static copy of the registry in the Nix store.
#
# /registry/src/$indexHash/{pkgName-pkgVersion}/:
#
# Here cargo keeps extracted sources of the cached tarballs.
# We'll just delete this because cargo will re-populate them from the
# tarballs.
#
# /git/db/{domain-hash}/:
#
# Here cargo keeps the `.git` directories of git dependencies.
# We'll need to keep these, but make them deterministic.
#
# /git/checkouts/{domain-hash}/{branchName}/:
#
# Here cargo keeps checked-out sources of the git dependencies.
# We can delete this, because cargo will re-populate them from the above
# `.git` directories.
#
# Let's start
# Remove cargo config file, which points to the ever-changing registry
rm $out/config
# Save the Cargo.lock file into the output, so that we don't have to do another
# 'cargo update' during the build (which would try to access the network) for
# any ad-hoc package updates (through $cargoUpdateHook).
#
# We need to replace the rustRegistry URL with something deterministic.
# Since the URL won't actually be accessed anymore, it's fine to use /dev/null.
set +u
substituteInPlace Cargo.lock \
--replace "registry+file://$rustRegistry" \
"registry+file:///dev/null"
set -u
mv Cargo.lock $out/
# The following is the $indexHash cargo uses for the registry index when
# its URL is file:///dev/null, which is the registry index URL we use to make
# sure our output is deterministic.
registryIndexDirName="-ba82b75dd6681d6f"
mv $out/registry/cache/* $out/registry/cache/$registryIndexDirName
# The registry index changes all the time, so it's not deterministic
# We'll symlink it before running 'cargo build'
rm -rf $out/registry/index/*
# Make git DBs deterministic
# TODO: test with git submodules
[[ ! -d $out/git/checkouts ]] || (cd $out/git/checkouts && for name in *; do
cd "$out/git/checkouts/$name"
revs=""
for branch in *; do
cd "$branch"
rev="$(git rev-parse HEAD)"
revs="$revs $rev"
cd ..
done
(
# The following code was adapted from nix-prefetch-git
cd "$out/git/db/$name"
export GIT_DIR=.
# Remove all remote branches
git branch -r | while read branch; do
git branch -rD "$branch" >&2
done
# Remove all tags
git tag | while read tag; do
git tag -d "$tag" >&2
done
# Remove all local branches
branchrefs=()
eval "$(git for-each-ref --shell --format='branchrefs+=(%(refname))' refs/heads/)"
for branchref in "${branchrefs[@]}"; do
git update-ref -d "$branchref" >&2
done
# Create ad-hoc branches for the revs we need
echo "$revs" | while read rev; do
echo "Creating git branch b_$rev $rev"
git branch b_$rev $rev
done
# Remove files that have timestamps or otherwise have non-deterministic
# properties.
rm -rf logs/ hooks/ index FETCH_HEAD ORIG_HEAD refs/remotes/origin/HEAD config
# Do a full repack. Must run single-threaded, or else we lose determinism.
git config pack.threads 1
git repack -A -d -f
rm -f config
# Garbage collect unreferenced objects.
git gc --prune=all
)
done)
# Remove unneeded outputs
[[ ! -d $out/registry/src ]] || rm -rf $out/registry/src
[[ ! -d $out/git/checkouts ]] || rm -rf $out/git/checkouts

View file

@ -0,0 +1,19 @@
{ stdenv, cacert, git, rustc, cargo, rustRegistry }:
{ name ? "cargo-deps", src, sha256, cargoUpdateHook ? "" }:
stdenv.mkDerivation {
name = "${name}-fetch";
buildInputs = [ rustc cargo git ];
builder = ./fetch-builder.sh;
fetcher = ./fetch-cargo-deps;
inherit src rustRegistry cargoUpdateHook;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
outputHash = sha256;
SSL_CERT_FILE = "${cacert}/etc/ca-bundle.crt";
impureEnvVars = [ "http_proxy" "https_proxy" "ftp_proxy" "all_proxy" "no_proxy" ];
preferLocalBuild = true;
}

View file

@ -0,0 +1,8 @@
for dir in pkg-config-*; do
[ -d "$dir" ] || continue
echo "Patching pkg-config registry dep"
substituteInPlace "$dir/src/lib.rs" \
--replace '"/usr"' '"/nix/store/"'
done

View file

@ -2,15 +2,15 @@
callPackage ./makeRustcDerivation.nix {
shortVersion = "1.0.0-dev";
isRelease = false;
# src rev for master on 2015/04/13
srcRev = "0cf99c3e06e84d20d68da649c888d63c72f33971";
srcSha = "0brnzsbxmidjnmvi36sz582k3kw6wk813y2y837zpmyxg9fjah0l";
snapshotHashLinux686 = "1ef82402ed16f5a6d2f87a9a62eaa83170e249ec";
snapshotHashLinux64 = "ef2154372e97a3cb687897d027fd51c8f2c5f349";
snapshotHashDarwin686 = "0310b1a970f2da7e61770fd14dbbbdca3b518234";
snapshotHashDarwin64 = "5f35d9c920b8083a7420ef8cf5b00d5ef3085dfa";
snapshotDate = "2015-03-27";
snapshotRev = "5520801";
# src rev for master on 2015-05-09
srcRev = "95400c51c31877ea4699adc051477edccb5cfbca";
srcSha = "1ldgc5nd42pcbr650rpyvpnc8h6bky6gmb116fwy1g6x2ql66djw";
snapshotHashLinux686 = "0bc8cffdce611fb71fd7d3d8e7cdbfaf748a4f16";
snapshotHashLinux64 = "94089740e48167c5975c92c139ae9c286764012f";
snapshotHashDarwin686 = "54cc35e76497e6e94fddf38d6e40e9d168491ddb";
snapshotHashDarwin64 = "43a1c1fba0d1dfee4c2ca310d506f8f5f51b3f6f";
snapshotDate = "2015-04-27";
snapshotRev = "857ef6e";
patches = [
./patches/head.patch
] ++ stdenv.lib.optional stdenv.needsPax ./patches/grsec.patch;

View file

@ -15,7 +15,7 @@ index ca59b1c..65ee7bf 100755
# do not fail if one of the above fails, as all we need is a working rustc!
exit 0
diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs
index ed44bf8..2b84627 100644
index 9f5751c..c98828f 100644
--- a/src/librustc_back/archive.rs
+++ b/src/librustc_back/archive.rs
@@ -57,7 +57,7 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
@ -28,10 +28,10 @@ index ed44bf8..2b84627 100644
let mut cmd = Command::new(ar);
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 3087a8e..578448f 100644
index ad77735..1764f71 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -352,8 +352,8 @@ pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> Stri
@@ -360,8 +360,8 @@ pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> Stri
pub fn get_cc_prog(sess: &Session) -> String {
match sess.opts.cg.linker {
@ -41,3 +41,17 @@ index 3087a8e..578448f 100644
+ None => "@ccPath@".to_string(),
}
}
diff --git a/src/test/run-pass/issue-20797.rs b/src/test/run-pass/issue-20797.rs
index 8b5e6f8..480ad79 100644
--- a/src/test/run-pass/issue-20797.rs
+++ b/src/test/run-pass/issue-20797.rs
@@ -97,7 +97,7 @@ impl<S: Strategy> Iterator for Subpaths<S> {
}
fn _foo() {
- let _walker: Subpaths<Recursive> = Subpaths::walk(&PathBuf::from("/home")).unwrap();
+ let _walker: Subpaths<Recursive> = Subpaths::walk(&PathBuf::from("/tmp")).unwrap();
}
fn main() {}

View file

@ -3,6 +3,16 @@
{
inherit version;
name = "cargo-${version}";
postInstall = ''
rm "$out/lib/rustlib/components" \
"$out/lib/rustlib/install.log" \
"$out/lib/rustlib/rust-installer-version" \
"$out/lib/rustlib/uninstall.sh" \
"$out/lib/rustlib/manifest-cargo"
'';
platform = if stdenv.system == "i686-linux"
then "i686-unknown-linux-gnu"
else if stdenv.system == "x86_64-linux"
@ -19,6 +29,4 @@
license = [ licenses.mit licenses.asl20 ];
platforms = platforms.linux;
};
name = "cargo-${version}";
}

View file

@ -0,0 +1,36 @@
{ stdenv, fetchgit, rustPlatform, file, curl, python, pkgconfig, openssl
, cmake, zlib }:
with ((import ./common.nix) { inherit stdenv; version = "2015-05-11"; });
with rustPlatform;
buildRustPackage rec {
inherit name version meta;
src = fetchgit {
url = "https://github.com/rust-lang/cargo.git";
rev = "a078e01ffab70738eafb7401704d1eaf90b94de2";
sha256 = "0vw62kxlmkajyix6n4cdz7w9l26dspjiw2fk4xkj33gzzc8rq9g8";
leaveDotGit = true;
};
depsSha256 = "1sk79w2wxvpgfkxr0nbrqqxdih4abiqvawdd88r2p9cqzrkdg8by";
buildInputs = [ file curl pkgconfig python openssl cmake zlib ];
configurePhase = ''
./configure --enable-optimize --prefix=$out --local-cargo=${cargo}/bin/cargo
'';
buildPhase = "make";
# Disable check phase as there are lots of failures (some probably due to
# trying to access the network).
doCheck = false;
installPhase = ''
make install
${postInstall}
'';
}

View file

@ -19,11 +19,8 @@ let snapshotHash = if stdenv.system == "i686-linux"
snapshotName = "cargo-nightly-${platform}.tar.gz";
in
stdenv.mkDerivation {
inherit name;
inherit version;
inherit meta;
inherit name version meta;
src = fetchurl {
url = "https://static-rust-lang-org.s3.amazonaws.com/cargo-dist/${snapshotDate}/${snapshotName}";
@ -35,10 +32,8 @@ stdenv.mkDerivation {
installPhase = ''
mkdir -p "$out"
./install.sh "--prefix=$out"
rm "$out/lib/rustlib/components" \
"$out/lib/rustlib/install.log" \
"$out/lib/rustlib/rust-installer-version" \
"$out/lib/rustlib/uninstall.sh"
${postInstall}
'' + (if stdenv.isLinux then ''
patchelf --interpreter "${stdenv.glibc}/lib/${stdenv.cc.dynamicLinker}" \
--set-rpath "${stdenv.cc.cc}/lib/:${stdenv.cc.cc}/lib64/:${zlib}/lib" \

View file

@ -1,18 +1,24 @@
{stdenv, fetchgit, rustc, cargo, makeWrapper }:
{stdenv, fetchgit, rustPlatform, makeWrapper }:
stdenv.mkDerivation rec {
with rustPlatform;
buildRustPackage rec {
#TODO add emacs support
name = "racer-git-2015-04-12";
name = "racer-git-2015-05-04";
src = fetchgit {
url = https://github.com/phildawes/racer;
rev = "5437e2074d87dfaab75a0f1bd2597bed61c0bbf1";
sha256 = "0a768gvjry86l0xa5q0122iyq7zn2h9adfniglsgrbs4fan49xyn";
rev = "bf2373ec08b0be03598283bd610c5b61bdb8738c";
sha256 = "0ldf05d19ghxk3fslxrc87j18zg8bam2y0ygdy456h37y2p1d1ck";
};
buildInputs = [ rustc cargo makeWrapper ];
patches = [ ./pr-232.patch ];
buildPhase = ''
CARGO_HOME="$NIX_BUILD_TOP/.cargo" cargo build --release
depsSha256 = "0rinyh365znx39aygxyyxmi496pw0alblf2dl7l8fbmz63nkhfv2";
buildInputs = [ makeWrapper ];
preCheck = ''
export RUST_SRC_PATH="${rustc.src}/src"
'';
installPhase = ''

View file

@ -0,0 +1,26 @@
From 3f354d69881424c7c902408d22f9138412a872b4 Mon Sep 17 00:00:00 2001
From: Ricardo Martins <ricardo@scarybox.net>
Date: Sat, 9 May 2015 17:12:55 +0100
Subject: [PATCH] Use `Vec::extend` instead of binary operation `+`.
---
src/racer/nameres.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/racer/nameres.rs b/src/racer/nameres.rs
index 60636c6..ad1e01c 100644
--- a/src/racer/nameres.rs
+++ b/src/racer/nameres.rs
@@ -620,9 +620,9 @@ pub fn search_scope(start: usize, point: usize, src: &str,
}
// There's a good chance of a match. Run the matchers
- out = out + &*run_matchers_on_blob(src, start+blobstart, start+blobend,
- searchstr,
- filepath, search_type, local, namespace);
+ out.extend(run_matchers_on_blob(src, start+blobstart, start+blobend,
+ searchstr,
+ filepath, search_type, local, namespace));
if let ExactMatch = search_type {
if !out.is_empty() {
return out.into_iter();

View file

@ -4397,6 +4397,24 @@ let
rustcMaster = callPackage ../development/compilers/rustc/head.nix {};
rustc = rustcBeta;
rustPlatform = rustStable;
rustStable = recurseIntoAttrs (makeRustPlatform rustc cargo rustStable);
rustUnstable = recurseIntoAttrs (makeRustPlatform rustcMaster cargo rustUnstable);
# rust platform to build cargo itself (with cargoSnapshot)
rustCargoPlatform = makeRustPlatform rustcMaster cargoSnapshot rustCargoPlatform;
makeRustPlatform = rustc: cargo: self:
let
callPackage = newScope self;
in {
inherit rustc cargo;
rustRegistry = callPackage ./rust-packages.nix { };
buildRustPackage = callPackage ../build-support/rust { };
};
sbclBootstrap = callPackage ../development/compilers/sbcl/bootstrap.nix {};
sbcl = callPackage ../development/compilers/sbcl {
@ -5011,6 +5029,11 @@ let
byacc = callPackage ../development/tools/parsing/byacc { };
cargo = callPackage ../development/tools/build-managers/cargo {
# cargo needs to be built with rustCargoPlatform, which uses cargoSnapshot
rustPlatform = rustCargoPlatform;
};
cargoSnapshot = callPackage ../development/tools/build-managers/cargo/snapshot.nix { };
casperjs = callPackage ../development/tools/casperjs { };
@ -5338,8 +5361,8 @@ let
premake = premake4;
racerRust = callPackage ../development/tools/rust/racer {
rustc = rustcMaster;
cargo = cargoSnapshot;
# racerRust still uses unstable features from the standard library
rustPlatform = rustUnstable;
};
radare = callPackage ../development/tools/analysis/radare {

View file

@ -0,0 +1,45 @@
# This file defines the source of Rust / cargo's crates registry
#
# buildRustPackage will automatically download dependencies from the registry
# version that we define here. If you're having problems downloading / finding
# a Rust library, try updating this to a newer commit.
{ runCommand, fetchgit, git }:
let
version = "2015-05-12";
src = fetchgit {
url = git://github.com/rust-lang/crates.io-index.git;
rev = "9bf9e7f2b242552ccec879b47b2225a76c7c79b0";
sha256 = "14rrpm6and52qasn7fv5fkflhnkyr86xy0k9pjgw407k7xms0cmw";
};
in
runCommand "rustRegistry-${version}-${builtins.substring 0 7 src.rev}" {} ''
# For some reason, cargo doesn't like fetchgit's git repositories, not even
# if we set leaveDotGit to true, set the fetchgit branch to 'master' and clone
# the repository (tested with registry rev
# 965b634156cc5c6f10c7a458392bfd6f27436e7e), failing with the message:
#
# "Target OID for the reference doesn't exist on the repository"
#
# So we'll just have to create a new git repository from scratch with the
# contents downloaded with fetchgit...
mkdir -p $out
cp -r ${src}/* $out/
cd $out
git="${git}/bin/git"
$git init
$git config --local user.email "example@example.com"
$git config --local user.name "example"
$git add .
$git commit -m 'Rust registry commit'
''