* `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…
	
	Add table
		Add a link
		
	
		Reference in a new issue