* `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; | ||||
| 
 | ||||
|   compileTest = main: link { | ||||
|     objects = [(compileC {inherit main; cFlags = "-I../aterm";})]; | ||||
|     objects = [(compileC {inherit main; localIncludePath = [ ../aterm ];})]; | ||||
|     libraries = libATerm; | ||||
|   }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -70,5 +70,4 @@ fi | |||
| 
 | ||||
| mkdir $out | ||||
| test "$prefix" && cd $prefix | ||||
| ls -l | ||||
| gcc -Wall $cFlags -c $mainName -o $out/$mainName.o | ||||
|  |  | |||
|  | @ -8,10 +8,17 @@ rec { | |||
|   stdenv = pkgs.stdenv; | ||||
|    | ||||
| 
 | ||||
|   compileC = {main, localIncludes ? "auto", cFlags ? "", sharedLib ? false}: | ||||
|   compileC = | ||||
|   { main | ||||
|   , localIncludes ? "auto" | ||||
|   , localIncludePath ? [] | ||||
|   , cFlags ? "" | ||||
|   , sharedLib ? false | ||||
|   }: | ||||
|   stdenv.mkDerivation { | ||||
|     name = "compile-c"; | ||||
|     builder = ./compile-c.sh; | ||||
|      | ||||
|     localIncludes = | ||||
|       if localIncludes == "auto" then | ||||
|         dependencyClosure { | ||||
|  | @ -19,24 +26,21 @@ rec { | |||
|             import (findIncludes { | ||||
|               inherit main; | ||||
|             }); | ||||
|           searchPath = localIncludePath; | ||||
|           startSet = [main]; | ||||
|         } | ||||
|       else | ||||
|         localIncludes; | ||||
|          | ||||
|     inherit main; | ||||
|      | ||||
|     cFlags = [ | ||||
|       cFlags | ||||
|       (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 { | ||||
|     name = "find-includes"; | ||||
|  | @ -45,12 +49,14 @@ rec { | |||
|     inherit main; | ||||
|   }; | ||||
| 
 | ||||
|      | ||||
|   link = {objects, programName ? "program", libraries ? []}: stdenv.mkDerivation { | ||||
|     name = "link"; | ||||
|     builder = ./link.sh; | ||||
|     inherit objects programName libraries; | ||||
|   }; | ||||
| 
 | ||||
|    | ||||
|   makeLibrary = {objects, libraryName ? [], sharedLib ? false}: | ||||
|   # assert sharedLib -> fold (obj: x: assert obj.sharedLib && x) false objects | ||||
|   stdenv.mkDerivation { | ||||
|  | @ -59,4 +65,5 @@ rec { | |||
|     inherit objects libraryName sharedLib; | ||||
|   }; | ||||
| 
 | ||||
|    | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,9 @@ print OUT "[\n"; | |||
| open IN, "<$root" or die "$!"; | ||||
| while (<IN>) { | ||||
|     if (/^\#include\s+\"(.*)\"/) { | ||||
|         print "DEP $1\n"; | ||||
|         print OUT "\"$1\"\n"; | ||||
|     } | ||||
|     if (/^\#include\s+\<(.*)\>/) { | ||||
|         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. */ | ||||
| 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( | ||||
|         format("illegal absolute dependency `%1%'") % dep); | ||||
| 
 | ||||
|     Path p = canonPath(dirOf(start) + "/" + dep); | ||||
|     Path p = canonPath(dir + "/" + dep); | ||||
| 
 | ||||
|     if (pathExists(p)) | ||||
|         return p; | ||||
|  | @ -464,11 +472,11 @@ static string relativise(Path pivot, Path p) | |||
| 
 | ||||
| static Expr primDependencyClosure(EvalState & state, const ATermVector & args) | ||||
| { | ||||
|     startNest(nest, lvlDebug, "finding dependencies"); | ||||
| 
 | ||||
|     Expr attrs = evalExpr(state, args[0]); | ||||
| 
 | ||||
|     Expr scanner = queryAttr(attrs, "scanner"); | ||||
|     if (!scanner) throw Error("attribute `scanner' required"); | ||||
|      | ||||
|     /* Get the start set. */ | ||||
|     Expr startSet = queryAttr(attrs, "startSet"); | ||||
|     if (!startSet) throw Error("attribute `startSet' required"); | ||||
|     ATermList startSet2 = evalList(state, startSet); | ||||
|  | @ -481,6 +489,20 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args) | |||
|         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
 | ||||
|        each path in `workSet', adding the dependencies to | ||||
|        `workSet'. */ | ||||
|  | @ -492,20 +514,39 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args) | |||
| 	if (doneSet.find(path) != doneSet.end()) continue; | ||||
|         doneSet.insert(path); | ||||
| 
 | ||||
|         try { | ||||
|              | ||||
|             /* 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)))); | ||||
| 
 | ||||
|             /* Try to find the dependencies relative to the `path'. */ | ||||
|             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 == "") | ||||
|                 printMsg(lvlError, format("did NOT find dependency `%1%'") % dep); | ||||
|                     debug(format("did NOT find dependency `%1%'") % s); | ||||
|                 else { | ||||
|                 printMsg(lvlError, format("found dependency `%1%'") % dep); | ||||
|                     debug(format("found dependency `%1%'") % 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. */ | ||||
|  | @ -515,7 +556,7 @@ static Expr primDependencyClosure(EvalState & state, const ATermVector & args) | |||
|         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); | ||||
| } | ||||
|  | @ -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() | ||||
| { | ||||
|     addPrimOp("true", 0, primTrue); | ||||
|  | @ -578,12 +627,12 @@ void EvalState::addPrimOps() | |||
|     addPrimOp("derivation!", 1, primDerivationStrict); | ||||
|     addPrimOp("derivation", 1, primDerivationLazy); | ||||
|     addPrimOp("baseNameOf", 1, primBaseNameOf); | ||||
|     addPrimOp("dirOf", 1, primDirOf); | ||||
|     addPrimOp("toString", 1, primToString); | ||||
|     addPrimOp("isNull", 1, primIsNull); | ||||
|     addPrimOp("dependencyClosure", 1, primDependencyClosure); | ||||
| 
 | ||||
|     addPrimOp("map", 2, primMap); | ||||
|     addPrimOp("removeAttrs", 2, primRemoveAttrs); | ||||
|     addPrimOp("relativise", 2, primRelativise); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue