* `dependencyClosure' now allows a search path, e.g.,
dependencyClosure { ... searchPath = [ ../foo ../bar ]; ... } * Primop `dirOf' to return the directory part of a path (e.g., dirOf /a/b/c == /a/b). * Primop `relativise' (according to Webster that's a real word!) that given paths A and B returns a string representing path B relative path to A; e.g., relativise /a/b/c a/b/x/y => "../x/y".
This commit is contained in:
parent
08c53923db
commit
e1a6fb7870
5 changed files with 89 additions and 32 deletions
|
@ -4,7 +4,7 @@ let {
|
||||||
inherit (import ../aterm {}) libATerm;
|
inherit (import ../aterm {}) libATerm;
|
||||||
|
|
||||||
compileTest = main: link {
|
compileTest = main: link {
|
||||||
objects = [(compileC {inherit main; cFlags = "-I../aterm";})];
|
objects = [(compileC {inherit main; localIncludePath = [ ../aterm ];})];
|
||||||
libraries = libATerm;
|
libraries = libATerm;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,5 +70,4 @@ fi
|
||||||
|
|
||||||
mkdir $out
|
mkdir $out
|
||||||
test "$prefix" && cd $prefix
|
test "$prefix" && cd $prefix
|
||||||
ls -l
|
|
||||||
gcc -Wall $cFlags -c $mainName -o $out/$mainName.o
|
gcc -Wall $cFlags -c $mainName -o $out/$mainName.o
|
||||||
|
|
|
@ -8,10 +8,17 @@ rec {
|
||||||
stdenv = pkgs.stdenv;
|
stdenv = pkgs.stdenv;
|
||||||
|
|
||||||
|
|
||||||
compileC = {main, localIncludes ? "auto", cFlags ? "", sharedLib ? false}:
|
compileC =
|
||||||
|
{ main
|
||||||
|
, localIncludes ? "auto"
|
||||||
|
, localIncludePath ? []
|
||||||
|
, cFlags ? ""
|
||||||
|
, sharedLib ? false
|
||||||
|
}:
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
name = "compile-c";
|
name = "compile-c";
|
||||||
builder = ./compile-c.sh;
|
builder = ./compile-c.sh;
|
||||||
|
|
||||||
localIncludes =
|
localIncludes =
|
||||||
if localIncludes == "auto" then
|
if localIncludes == "auto" then
|
||||||
dependencyClosure {
|
dependencyClosure {
|
||||||
|
@ -19,24 +26,21 @@ rec {
|
||||||
import (findIncludes {
|
import (findIncludes {
|
||||||
inherit main;
|
inherit main;
|
||||||
});
|
});
|
||||||
|
searchPath = localIncludePath;
|
||||||
startSet = [main];
|
startSet = [main];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
localIncludes;
|
localIncludes;
|
||||||
|
|
||||||
inherit main;
|
inherit main;
|
||||||
|
|
||||||
cFlags = [
|
cFlags = [
|
||||||
cFlags
|
cFlags
|
||||||
(if sharedLib then ["-fpic"] else [])
|
(if sharedLib then ["-fpic"] else [])
|
||||||
|
(map (p: "-I" + (relativise (dirOf main) p)) localIncludePath)
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
runCommand = {command}: {
|
|
||||||
name = "run-command";
|
|
||||||
builder = ./run-command.sh;
|
|
||||||
inherit command;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
findIncludes = {main}: stdenv.mkDerivation {
|
findIncludes = {main}: stdenv.mkDerivation {
|
||||||
name = "find-includes";
|
name = "find-includes";
|
||||||
|
@ -45,12 +49,14 @@ rec {
|
||||||
inherit main;
|
inherit main;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
link = {objects, programName ? "program", libraries ? []}: stdenv.mkDerivation {
|
link = {objects, programName ? "program", libraries ? []}: stdenv.mkDerivation {
|
||||||
name = "link";
|
name = "link";
|
||||||
builder = ./link.sh;
|
builder = ./link.sh;
|
||||||
inherit objects programName libraries;
|
inherit objects programName libraries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
makeLibrary = {objects, libraryName ? [], sharedLib ? false}:
|
makeLibrary = {objects, libraryName ? [], sharedLib ? false}:
|
||||||
# assert sharedLib -> fold (obj: x: assert obj.sharedLib && x) false objects
|
# assert sharedLib -> fold (obj: x: assert obj.sharedLib && x) false objects
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
|
@ -59,4 +65,5 @@ rec {
|
||||||
inherit objects libraryName sharedLib;
|
inherit objects libraryName sharedLib;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ print OUT "[\n";
|
||||||
open IN, "<$root" or die "$!";
|
open IN, "<$root" or die "$!";
|
||||||
while (<IN>) {
|
while (<IN>) {
|
||||||
if (/^\#include\s+\"(.*)\"/) {
|
if (/^\#include\s+\"(.*)\"/) {
|
||||||
print "DEP $1\n";
|
print OUT "\"$1\"\n";
|
||||||
|
}
|
||||||
|
if (/^\#include\s+\<(.*)\>/) {
|
||||||
print OUT "\"$1\"\n";
|
print OUT "\"$1\"\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,6 +372,14 @@ static Expr primBaseNameOf(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the directory of the given path, i.e., everything before the
|
||||||
|
last slash. */
|
||||||
|
static Expr primDirOf(EvalState & state, const ATermVector & args)
|
||||||
|
{
|
||||||
|
return makePath(toATerm(dirOf(evalPath(state, args[0]))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert the argument (which can be a path or a uri) to a string. */
|
/* Convert the argument (which can be a path or a uri) to a string. */
|
||||||
static Expr primToString(EvalState & state, const ATermVector & args)
|
static Expr primToString(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
|
@ -410,12 +418,12 @@ static Expr primIsNull(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Path findDependency(Path start, string dep)
|
static Path findDependency(Path dir, string dep)
|
||||||
{
|
{
|
||||||
if (dep[0] == '/') throw Error(
|
if (dep[0] == '/') throw Error(
|
||||||
format("illegal absolute dependency `%1%'") % dep);
|
format("illegal absolute dependency `%1%'") % dep);
|
||||||
|
|
||||||
Path p = canonPath(dirOf(start) + "/" + dep);
|
Path p = canonPath(dir + "/" + dep);
|
||||||
|
|
||||||
if (pathExists(p))
|
if (pathExists(p))
|
||||||
return p;
|
return p;
|
||||||
|
@ -464,11 +472,11 @@ static string relativise(Path pivot, Path p)
|
||||||
|
|
||||||
static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
||||||
{
|
{
|
||||||
|
startNest(nest, lvlDebug, "finding dependencies");
|
||||||
|
|
||||||
Expr attrs = evalExpr(state, args[0]);
|
Expr attrs = evalExpr(state, args[0]);
|
||||||
|
|
||||||
Expr scanner = queryAttr(attrs, "scanner");
|
/* Get the start set. */
|
||||||
if (!scanner) throw Error("attribute `scanner' required");
|
|
||||||
|
|
||||||
Expr startSet = queryAttr(attrs, "startSet");
|
Expr startSet = queryAttr(attrs, "startSet");
|
||||||
if (!startSet) throw Error("attribute `startSet' required");
|
if (!startSet) throw Error("attribute `startSet' required");
|
||||||
ATermList startSet2 = evalList(state, startSet);
|
ATermList startSet2 = evalList(state, startSet);
|
||||||
|
@ -481,6 +489,20 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
||||||
pivot = dirOf(p);
|
pivot = dirOf(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the search path. */
|
||||||
|
PathSet searchPath;
|
||||||
|
Expr e = queryAttr(attrs, "searchPath");
|
||||||
|
if (e) {
|
||||||
|
ATermList list = evalList(state, e);
|
||||||
|
for (ATermIterator i(list); i; ++i) {
|
||||||
|
Path p = evalPath(state, *i);
|
||||||
|
searchPath.insert(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr scanner = queryAttr(attrs, "scanner");
|
||||||
|
if (!scanner) throw Error("attribute `scanner' required");
|
||||||
|
|
||||||
/* Construct the dependency closure by querying the dependency of
|
/* Construct the dependency closure by querying the dependency of
|
||||||
each path in `workSet', adding the dependencies to
|
each path in `workSet', adding the dependencies to
|
||||||
`workSet'. */
|
`workSet'. */
|
||||||
|
@ -492,20 +514,39 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
||||||
if (doneSet.find(path) != doneSet.end()) continue;
|
if (doneSet.find(path) != doneSet.end()) continue;
|
||||||
doneSet.insert(path);
|
doneSet.insert(path);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
/* Call the `scanner' function with `path' as argument. */
|
/* Call the `scanner' function with `path' as argument. */
|
||||||
printMsg(lvlError, format("finding dependencies in `%1%'") % path);
|
debug(format("finding dependencies in `%1%'") % path);
|
||||||
ATermList deps = evalList(state, makeCall(scanner, makePath(toATerm(path))));
|
ATermList deps = evalList(state, makeCall(scanner, makePath(toATerm(path))));
|
||||||
|
|
||||||
/* Try to find the dependencies relative to the `path'. */
|
/* Try to find the dependencies relative to the `path'. */
|
||||||
for (ATermIterator i(deps); i; ++i) {
|
for (ATermIterator i(deps); i; ++i) {
|
||||||
Path dep = findDependency(path, evalString(state, *i));
|
string s = evalString(state, *i);
|
||||||
|
|
||||||
|
Path dep = findDependency(dirOf(path), s);
|
||||||
|
|
||||||
|
if (dep == "") {
|
||||||
|
for (PathSet::iterator j = searchPath.begin();
|
||||||
|
j != searchPath.end(); ++j)
|
||||||
|
{
|
||||||
|
dep = findDependency(*j, s);
|
||||||
|
if (dep != "") break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dep == "")
|
if (dep == "")
|
||||||
printMsg(lvlError, format("did NOT find dependency `%1%'") % dep);
|
debug(format("did NOT find dependency `%1%'") % s);
|
||||||
else {
|
else {
|
||||||
printMsg(lvlError, format("found dependency `%1%'") % dep);
|
debug(format("found dependency `%1%'") % dep);
|
||||||
workSet.insert(dep);
|
workSet.insert(dep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (Error & e) {
|
||||||
|
throw Error(format("while finding dependencies in `%1%':\n%2%")
|
||||||
|
% path % e.msg());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a list of the dependencies we've just found. */
|
/* Return a list of the dependencies we've just found. */
|
||||||
|
@ -515,7 +556,7 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args)
|
||||||
deps = ATinsert(deps, makePath(toATerm(*i)));
|
deps = ATinsert(deps, makePath(toATerm(*i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
printMsg(lvlError, format("RESULT is `%1%'") % makeList(deps));
|
debug(format("dependency list is `%1%'") % makeList(deps));
|
||||||
|
|
||||||
return makeList(deps);
|
return makeList(deps);
|
||||||
}
|
}
|
||||||
|
@ -566,6 +607,14 @@ static Expr primRemoveAttrs(EvalState & state, const ATermVector & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Expr primRelativise(EvalState & state, const ATermVector & args)
|
||||||
|
{
|
||||||
|
Path pivot = evalPath(state, args[0]);
|
||||||
|
Path path = evalPath(state, args[1]);
|
||||||
|
return makeStr(toATerm(relativise(pivot, path)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EvalState::addPrimOps()
|
void EvalState::addPrimOps()
|
||||||
{
|
{
|
||||||
addPrimOp("true", 0, primTrue);
|
addPrimOp("true", 0, primTrue);
|
||||||
|
@ -578,12 +627,12 @@ void EvalState::addPrimOps()
|
||||||
addPrimOp("derivation!", 1, primDerivationStrict);
|
addPrimOp("derivation!", 1, primDerivationStrict);
|
||||||
addPrimOp("derivation", 1, primDerivationLazy);
|
addPrimOp("derivation", 1, primDerivationLazy);
|
||||||
addPrimOp("baseNameOf", 1, primBaseNameOf);
|
addPrimOp("baseNameOf", 1, primBaseNameOf);
|
||||||
|
addPrimOp("dirOf", 1, primDirOf);
|
||||||
addPrimOp("toString", 1, primToString);
|
addPrimOp("toString", 1, primToString);
|
||||||
addPrimOp("isNull", 1, primIsNull);
|
addPrimOp("isNull", 1, primIsNull);
|
||||||
addPrimOp("dependencyClosure", 1, primDependencyClosure);
|
addPrimOp("dependencyClosure", 1, primDependencyClosure);
|
||||||
|
|
||||||
addPrimOp("map", 2, primMap);
|
addPrimOp("map", 2, primMap);
|
||||||
addPrimOp("removeAttrs", 2, primRemoveAttrs);
|
addPrimOp("removeAttrs", 2, primRemoveAttrs);
|
||||||
|
addPrimOp("relativise", 2, primRelativise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue