* Merge remaining stuff from the nix-make branch.
* Add support for the creation of shared libraries to `compileC', `link', and `makeLibrary'. * Enable the ATerm library to be made into a shared library.
This commit is contained in:
		
							parent
							
								
									02f2da0142
								
							
						
					
					
						commit
						36fb29f8f0
					
				
					 22 changed files with 347 additions and 0 deletions
				
			
		
							
								
								
									
										34
									
								
								make/examples/aterm/aterm/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								make/examples/aterm/aterm/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| {sharedLib ? true}: | ||||
| 
 | ||||
| rec { | ||||
| 
 | ||||
|   inherit (import ../../../lib) compileC makeLibrary; | ||||
| 
 | ||||
|   sources = [ | ||||
|     ./afun.c | ||||
|     ./aterm.c | ||||
|     ./bafio.c | ||||
|     ./byteio.c | ||||
|     ./gc.c | ||||
|     ./hash.c | ||||
|     ./list.c | ||||
|     ./make.c | ||||
|     ./md5c.c | ||||
|     ./memory.c | ||||
|     ./tafio.c | ||||
|     ./version.c | ||||
|   ]; | ||||
| 
 | ||||
|   compile = fn: compileC { | ||||
|     main = fn; | ||||
|     localIncludes = "auto"; | ||||
|     forSharedLib = sharedLib; | ||||
|   }; | ||||
| 
 | ||||
|   libATerm = makeLibrary { | ||||
|     libraryName = "ATerm"; | ||||
|     objects = map compile sources; | ||||
|     inherit sharedLib; | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										1
									
								
								make/examples/aterm/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								make/examples/aterm/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| import test/default.nix | ||||
							
								
								
									
										18
									
								
								make/examples/aterm/test/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								make/examples/aterm/test/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| let { | ||||
| 
 | ||||
|   inherit (import ../../../lib) compileC link; | ||||
| 
 | ||||
|   inherit (import ../aterm {}) libATerm; | ||||
| 
 | ||||
|   compile = fn: compileC { | ||||
|     main = fn; | ||||
|     localIncludes = "auto"; | ||||
|     cFlags = "-I../aterm"; | ||||
|   }; | ||||
| 
 | ||||
|   fib = link {objects = compile ./fib.c; libraries = libATerm;}; | ||||
| 
 | ||||
|   primes = link {objects = compile ./primes.c; libraries = libATerm;}; | ||||
|    | ||||
|   body = [fib primes]; | ||||
| } | ||||
							
								
								
									
										6
									
								
								make/examples/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								make/examples/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| [ (import ./trivial) | ||||
|   (import ./simple-header) | ||||
|   (import ./not-so-simple-header) | ||||
|   (import ./not-so-simple-header-auto) | ||||
|   (import ./aterm) | ||||
| ] | ||||
							
								
								
									
										1
									
								
								make/examples/not-so-simple-header-auto/bar/hello.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								make/examples/not-so-simple-header-auto/bar/hello.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| #define WHAT "World" | ||||
							
								
								
									
										11
									
								
								make/examples/not-so-simple-header-auto/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								make/examples/not-so-simple-header-auto/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| let { | ||||
| 
 | ||||
|   inherit (import ../../lib) compileC findIncludes link; | ||||
| 
 | ||||
|   hello = link {programName = "hello"; objects = compileC { | ||||
|     main = ./foo/hello.c; | ||||
|     localIncludes = "auto"; | ||||
|   };}; | ||||
| 
 | ||||
|   body = [hello]; | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| #define HELLO "Hello" | ||||
| 
 | ||||
| #include "../../bar/hello.h" | ||||
							
								
								
									
										9
									
								
								make/examples/not-so-simple-header-auto/foo/hello.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								make/examples/not-so-simple-header-auto/foo/hello.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "fnord/indirect.h" | ||||
| 
 | ||||
| int main(int argc, char * * argv) | ||||
| { | ||||
|     printf(HELLO " " WHAT "\n"); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										1
									
								
								make/examples/not-so-simple-header/bar/hello.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								make/examples/not-so-simple-header/bar/hello.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| #define WHAT "World" | ||||
							
								
								
									
										14
									
								
								make/examples/not-so-simple-header/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								make/examples/not-so-simple-header/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| let { | ||||
| 
 | ||||
|   inherit (import ../../lib) compileC link; | ||||
| 
 | ||||
|   hello = link {programName = "hello"; objects = compileC { | ||||
|     main = ./foo/hello.c; | ||||
|     localIncludes = [ | ||||
|       [./foo/fnord/indirect.h "fnord/indirect.h"] | ||||
|       [./bar/hello.h "fnord/../../bar/hello.h"] | ||||
|     ]; | ||||
|   };}; | ||||
| 
 | ||||
|   body = [hello]; | ||||
| } | ||||
							
								
								
									
										3
									
								
								make/examples/not-so-simple-header/foo/fnord/indirect.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								make/examples/not-so-simple-header/foo/fnord/indirect.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #define HELLO "Hello" | ||||
| 
 | ||||
| #include "../../bar/hello.h" | ||||
							
								
								
									
										9
									
								
								make/examples/not-so-simple-header/foo/hello.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								make/examples/not-so-simple-header/foo/hello.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "fnord/indirect.h" | ||||
| 
 | ||||
| int main(int argc, char * * argv) | ||||
| { | ||||
|     printf(HELLO " " WHAT "\n"); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										11
									
								
								make/examples/simple-header/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								make/examples/simple-header/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| let { | ||||
| 
 | ||||
|   inherit (import ../../lib) compileC link; | ||||
| 
 | ||||
|   hello = link {objects = compileC { | ||||
|     main = ./hello.c; | ||||
|     localIncludes = [ [./hello.h "hello.h"] ]; | ||||
|   };}; | ||||
| 
 | ||||
|   body = [hello]; | ||||
| } | ||||
							
								
								
									
										9
									
								
								make/examples/simple-header/hello.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								make/examples/simple-header/hello.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "hello.h" | ||||
| 
 | ||||
| int main(int argc, char * * argv) | ||||
| { | ||||
|     printf("Hello " WHAT "\n"); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										1
									
								
								make/examples/simple-header/hello.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								make/examples/simple-header/hello.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| #define WHAT "World" | ||||
							
								
								
									
										8
									
								
								make/examples/trivial/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								make/examples/trivial/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| let { | ||||
| 
 | ||||
|   inherit (import ../../lib) compileC link; | ||||
| 
 | ||||
|   hello = link {objects = compileC {main = ./hello.c;};}; | ||||
| 
 | ||||
|   body = [hello]; | ||||
| } | ||||
							
								
								
									
										7
									
								
								make/examples/trivial/hello.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								make/examples/trivial/hello.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #include <stdio.h> | ||||
| 
 | ||||
| int main(int argc, char * * argv) | ||||
| { | ||||
|     printf("Hello World\n"); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										73
									
								
								make/lib/compile-c.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								make/lib/compile-c.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,73 @@ | |||
| . $stdenv/setup | ||||
| 
 | ||||
| mainName=$(basename $main | cut -c34-) | ||||
| 
 | ||||
| echo "compiling \`$mainName'..." | ||||
| 
 | ||||
| # Turn $localIncludes into an array. | ||||
| localIncludes=($localIncludes) | ||||
| 
 | ||||
| # Determine how many `..' levels appear in the header file references. | ||||
| # E.g., if there is some reference `../../foo.h', then we have to | ||||
| # insert two extra levels in the directory structure, so that `a.c' is | ||||
| # stored at `dotdot/dotdot/a.c', and a reference from it to | ||||
| # `../../foo.h' resolves to `dotdot/dotdot/../../foo.h' == `foo.h'. | ||||
| n=0 | ||||
| maxDepth=0 | ||||
| for ((n = 0; n < ${#localIncludes[*]}; n += 2)); do | ||||
|     target=${localIncludes[$((n + 1))]} | ||||
| 
 | ||||
|     # Split the target name into path components using some IFS magic. | ||||
|     savedIFS="$IFS" | ||||
|     IFS=/ | ||||
|     components=($target) | ||||
|     depth=0 | ||||
|     for ((m = 0; m < ${#components[*]}; m++)); do | ||||
|         c=${components[m]} | ||||
|         if test "$c" = ".."; then | ||||
|             depth=$((depth + 1)) | ||||
|         fi | ||||
|     done | ||||
|     IFS="$savedIFS" | ||||
| 
 | ||||
|     if test $depth -gt $maxDepth; then | ||||
|         maxDepth=$depth; | ||||
|     fi | ||||
| done | ||||
| 
 | ||||
| # Create the extra levels in the directory hierarchy. | ||||
| prefix= | ||||
| for ((n = 0; n < maxDepth; n++)); do | ||||
|     prefix="dotdot/$prefix" | ||||
| done | ||||
| 
 | ||||
| # Create symlinks to the header files. | ||||
| for ((n = 0; n < ${#localIncludes[*]}; n += 2)); do | ||||
|     source=${localIncludes[n]} | ||||
|     target=${localIncludes[$((n + 1))]} | ||||
| 
 | ||||
|     # Create missing directories.  We use IFS magic to split the path | ||||
|     # into path components. | ||||
|     savedIFS="$IFS" | ||||
|     IFS=/ | ||||
|     components=($prefix$target) | ||||
|     fullPath=(.) | ||||
|     for ((m = 0; m < ${#components[*]} - 1; m++)); do | ||||
|         fullPath=("${fullPath[@]}" ${components[m]}) | ||||
|         if ! test -d "${fullPath[*]}"; then | ||||
|             mkdir "${fullPath[*]}" | ||||
|         fi | ||||
|     done | ||||
|     IFS="$savedIFS" | ||||
|      | ||||
|     ln -sf $source $prefix$target | ||||
| done | ||||
| 
 | ||||
| # Create a symlink to the main file. | ||||
| if ! test "$(readlink $prefix$mainName)" = $main; then | ||||
|     ln -s $main $prefix$mainName | ||||
| fi | ||||
| 
 | ||||
| mkdir $out | ||||
| test "$prefix" && cd $prefix | ||||
| gcc -Wall $cFlags -c $mainName -o $out/$mainName.o | ||||
							
								
								
									
										59
									
								
								make/lib/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								make/lib/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| rec { | ||||
| 
 | ||||
|   # Should point at your Nixpkgs installation. | ||||
|   pkgPath = ./pkgs; | ||||
| 
 | ||||
|   pkgs = import (pkgPath + /system/all-packages.nix) {}; | ||||
| 
 | ||||
|   stdenv = pkgs.stdenv; | ||||
|    | ||||
| 
 | ||||
|   compileC = {main, localIncludes ? [], cFlags ? "", forSharedLib ? false}: | ||||
|   stdenv.mkDerivation { | ||||
|     name = "compile-c"; | ||||
|     builder = ./compile-c.sh; | ||||
|     localIncludes = | ||||
|       if localIncludes == "auto" then | ||||
|         import (findIncludes { | ||||
|           main = toString main; | ||||
|           hack = __currentTime; | ||||
|           inherit cFlags; | ||||
|         }) | ||||
|       else | ||||
|         localIncludes; | ||||
|     inherit main; | ||||
|     cFlags = [ | ||||
|       cFlags | ||||
|       (if forSharedLib then ["-fpic"] else []) | ||||
|     ]; | ||||
|   }; | ||||
| 
 | ||||
|   /* | ||||
|   runCommand = {command}: { | ||||
|     name = "run-command"; | ||||
|     builder = ./run-command.sh; | ||||
|     inherit command; | ||||
|   }; | ||||
|   */ | ||||
| 
 | ||||
|   findIncludes = {main, hack, cFlags ? ""}: stdenv.mkDerivation { | ||||
|     name = "find-includes"; | ||||
|     builder = ./find-includes.sh; | ||||
|     inherit main hack cFlags; | ||||
|   }; | ||||
|    | ||||
|   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 { | ||||
|     name = "library"; | ||||
|     builder = ./make-library.sh; | ||||
|     inherit objects libraryName sharedLib; | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										20
									
								
								make/lib/find-includes.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								make/lib/find-includes.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| . $stdenv/setup | ||||
| 
 | ||||
| echo "finding includes of \`$(basename $main)'..." | ||||
| 
 | ||||
| makefile=$NIX_BUILD_TOP/makefile | ||||
| 
 | ||||
| mainDir=$(dirname $main) | ||||
| (cd $mainDir && gcc $cFlags -MM $(basename $main) -MF $makefile) || false | ||||
| 
 | ||||
| echo "[" >$out | ||||
| 
 | ||||
| while read line; do | ||||
|     line=$(echo "$line" | sed 's/.*://') | ||||
|     for i in $line; do | ||||
|         fullPath=$(readlink -f $mainDir/$i) | ||||
|         echo "  [ $fullPath \"$i\" ]" >>$out | ||||
|     done | ||||
| done < $makefile | ||||
| 
 | ||||
| echo "]" >>$out | ||||
							
								
								
									
										21
									
								
								make/lib/link.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								make/lib/link.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| . $stdenv/setup | ||||
| 
 | ||||
| shopt -s nullglob | ||||
| 
 | ||||
| objs= | ||||
| for i in $objects; do | ||||
|     obj=$(echo $i/*.o) | ||||
|     objs="$objs $obj" | ||||
| done | ||||
| 
 | ||||
| libs= | ||||
| for i in $libraries; do | ||||
|     lib=$(echo $i/*.a; echo $i/*.so) | ||||
|     name=$(echo $(basename $lib) | sed -e 's/^lib//' -e 's/.a$//' -e 's/.so$//') | ||||
|     libs="$libs -L$(dirname $lib) -l$name"  | ||||
| done | ||||
| 
 | ||||
| echo "linking object files into \`$programName'..." | ||||
| 
 | ||||
| mkdir $out | ||||
| gcc -o $out/$programName $objs $libs | ||||
							
								
								
									
										28
									
								
								make/lib/make-library.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								make/lib/make-library.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,28 @@ | |||
| . $stdenv/setup | ||||
| 
 | ||||
| objs= | ||||
| for i in $objects; do | ||||
|     obj=$(echo $i/*.o) | ||||
|     objs="$objs $obj" | ||||
| done | ||||
| 
 | ||||
| echo "archiving object files into library \`$libraryName'..." | ||||
| 
 | ||||
| ensureDir $out | ||||
| 
 | ||||
| if test -z "$sharedLib"; then | ||||
| 
 | ||||
|     outPath=$out/lib${libraryName}.a | ||||
| 
 | ||||
|     ar crs $outPath $objs | ||||
|     ranlib $outPath | ||||
| 
 | ||||
| else | ||||
| 
 | ||||
|     outPath=$out/lib${libraryName}.so | ||||
| 
 | ||||
|     gcc -shared -o $outPath $objs | ||||
| 
 | ||||
| fi     | ||||
| 
 | ||||
|      | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue