Compare commits
11 Commits
Author | SHA1 | Date |
---|---|---|
Eelco Dolstra | f1ed34081e | |
Eelco Dolstra | 17e20716c0 | |
Eelco Dolstra | 5d48dd6912 | |
Eelco Dolstra | af54a60204 | |
Eelco Dolstra | 7d386d5c29 | |
Eelco Dolstra | fa50c0849e | |
Eelco Dolstra | 321be4649d | |
Eelco Dolstra | 0920fe3038 | |
Eelco Dolstra | 08de98f8b6 | |
Eelco Dolstra | 15646244ba | |
Eelco Dolstra | a2e33d200e |
|
@ -0,0 +1,30 @@
|
|||
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";
|
||||
};
|
||||
|
||||
libATerm = makeLibrary {
|
||||
libraryName = "ATerm";
|
||||
objects = map {function = compile; list = sources;};
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import test/default.nix
|
|
@ -0,0 +1,16 @@
|
|||
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;};
|
||||
|
||||
body = [fib];
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
[ (import ./trivial)
|
||||
(import ./simple-header)
|
||||
(import ./not-so-simple-header)
|
||||
(import ./not-so-simple-header-auto)
|
||||
(import ./aterm)
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
#define WHAT "World"
|
|
@ -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"
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "fnord/indirect.h"
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf(HELLO " " WHAT "\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#define WHAT "World"
|
|
@ -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];
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#define HELLO "Hello"
|
||||
|
||||
#include "../../bar/hello.h"
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "fnord/indirect.h"
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf(HELLO " " WHAT "\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
let {
|
||||
|
||||
inherit (import ../../lib) compileC link;
|
||||
|
||||
hello = link {objects = compileC {
|
||||
main = ./hello.c;
|
||||
localIncludes = [ [./hello.h "hello.h"] ];
|
||||
};};
|
||||
|
||||
body = [hello];
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "hello.h"
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf("Hello " WHAT "\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
#define WHAT "World"
|
|
@ -0,0 +1,8 @@
|
|||
let {
|
||||
|
||||
inherit (import ../../lib) compileC link;
|
||||
|
||||
hello = link {objects = compileC {main = ./hello.c;};};
|
||||
|
||||
body = [hello];
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char * * argv)
|
||||
{
|
||||
printf("Hello World\n");
|
||||
return 0;
|
||||
}
|
|
@ -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 -s $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
|
|
@ -0,0 +1,46 @@
|
|||
rec {
|
||||
|
||||
inherit (import /home/eelco/nixpkgs/pkgs/system/i686-linux.nix) stdenv;
|
||||
|
||||
compileC = {main, localIncludes ? [], cFlags ? ""}: stdenv.mkDerivation {
|
||||
name = "compile-c";
|
||||
builder = ./compile-c.sh;
|
||||
localIncludes =
|
||||
if localIncludes == "auto" then
|
||||
import (findIncludes {
|
||||
main = toString main;
|
||||
hack = curTime;
|
||||
inherit cFlags;
|
||||
})
|
||||
else
|
||||
localIncludes;
|
||||
inherit main cFlags;
|
||||
};
|
||||
|
||||
/*
|
||||
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 ? []}: stdenv.mkDerivation {
|
||||
name = "library";
|
||||
builder = ./make-library.sh;
|
||||
inherit objects libraryName;
|
||||
};
|
||||
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,19 @@
|
|||
. $stdenv/setup
|
||||
|
||||
objs=
|
||||
for i in $objects; do
|
||||
obj=$(echo $i/*.o)
|
||||
objs="$objs $obj"
|
||||
done
|
||||
|
||||
libs=
|
||||
for i in $libraries; do
|
||||
lib=$(echo $i/*.a)
|
||||
name=$(echo $(basename $lib) | sed -e 's/^lib//' -e 's/.a$//')
|
||||
libs="$libs -L$(dirname $lib) -l$name"
|
||||
done
|
||||
|
||||
echo "linking object files into \`$programName'..."
|
||||
|
||||
mkdir $out
|
||||
gcc -o $out/$programName $objs $libs
|
|
@ -0,0 +1,15 @@
|
|||
. $stdenv/setup
|
||||
|
||||
objs=
|
||||
for i in $objects; do
|
||||
obj=$(echo $i/*.o)
|
||||
objs="$objs $obj"
|
||||
done
|
||||
|
||||
echo "archiving object files into library \`$libraryName'..."
|
||||
|
||||
outPath=$out/lib${libraryName}.a
|
||||
|
||||
mkdir $out
|
||||
ar crs $outPath $objs
|
||||
ranlib $outPath
|
|
@ -28,12 +28,14 @@ EvalState::EvalState()
|
|||
addPrimOp0("true", primTrue);
|
||||
addPrimOp0("false", primFalse);
|
||||
addPrimOp0("null", primNull);
|
||||
addPrimOp0("curTime", primCurTime);
|
||||
|
||||
addPrimOp1("import", primImport);
|
||||
addPrimOp1("derivation", primDerivation);
|
||||
addPrimOp1("baseNameOf", primBaseNameOf);
|
||||
addPrimOp1("toString", primToString);
|
||||
addPrimOp1("isNull", primIsNull);
|
||||
addPrimOp1("map", primMap);
|
||||
|
||||
primOpsAll.add(primOps0);
|
||||
primOpsAll.add(primOps1);
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "primops.hh"
|
||||
#include "normalise.hh"
|
||||
#include "globals.hh"
|
||||
|
@ -6,9 +8,35 @@
|
|||
Expr primImport(EvalState & state, Expr arg)
|
||||
{
|
||||
ATMatcher m;
|
||||
string path;
|
||||
if (!(atMatch(m, arg) >> "Path" >> path))
|
||||
throw Error("path expected");
|
||||
ATermList es;
|
||||
Path path;
|
||||
|
||||
arg = evalExpr(state, arg);
|
||||
|
||||
if (atMatch(m, arg) >> "Path" >> path)
|
||||
;
|
||||
|
||||
else if (atMatch(m, arg) >> "Attrs" >> es) {
|
||||
Expr a = queryAttr(arg, "type");
|
||||
|
||||
/* If it is a derivation, we have to realise it and load the
|
||||
Nix expression created at the derivation's output path. */
|
||||
if (a && evalString(state, a) == "derivation") {
|
||||
a = queryAttr(arg, "drvPath");
|
||||
if (!a) throw Error("bad derivation in import");
|
||||
Path drvPath = evalPath(state, a);
|
||||
|
||||
realiseStoreExpr(drvPath);
|
||||
|
||||
a = queryAttr(arg, "outPath");
|
||||
if (!a) throw Error("bad derivation in import");
|
||||
path = evalPath(state, a);
|
||||
}
|
||||
}
|
||||
|
||||
if (path == "")
|
||||
throw Error("path or derivation expected in import");
|
||||
|
||||
return evalFile(state, path);
|
||||
}
|
||||
|
||||
|
@ -267,7 +295,7 @@ Expr primToString(EvalState & state, Expr arg)
|
|||
atMatch(m, arg) >> "Path" >> s ||
|
||||
atMatch(m, arg) >> "Uri" >> s)
|
||||
return ATmake("Str(<str>)", s.c_str());
|
||||
else throw Error("cannot coerce value to string");
|
||||
throw Error("cannot coerce value to string");
|
||||
}
|
||||
|
||||
|
||||
|
@ -295,3 +323,41 @@ Expr primIsNull(EvalState & state, Expr arg)
|
|||
ATMatcher m;
|
||||
return makeBool(atMatch(m, arg) >> "Null");
|
||||
}
|
||||
|
||||
|
||||
Expr primCurTime(EvalState & state)
|
||||
{
|
||||
return ATmake("Int(<int>)", time(0));
|
||||
}
|
||||
|
||||
|
||||
Expr primMap(EvalState & state, Expr arg)
|
||||
{
|
||||
arg = evalExpr(state, arg);
|
||||
|
||||
ATMatcher m;
|
||||
ATermList es;
|
||||
if (!(atMatch(m, arg) >> "Attrs" >> es))
|
||||
throw Error("function `map' expects an attribute set");
|
||||
|
||||
Expr function = queryAttr(arg, "function");
|
||||
if (!function)
|
||||
throw Error("function `map' expects an attribute `function'");
|
||||
|
||||
Expr list = queryAttr(arg, "list");
|
||||
if (!list)
|
||||
throw Error("function `map' expects an attribute `list'");
|
||||
|
||||
list = evalExpr(state, list);
|
||||
|
||||
ATermList es2;
|
||||
if (!(atMatch(m, list) >> "List" >> es2))
|
||||
throw Error("attribute `list' in call to `map' must be a list");
|
||||
|
||||
ATermList res = ATempty;
|
||||
for (ATermIterator i(es2); i; ++i)
|
||||
res = ATinsert(res,
|
||||
ATmake("Call(<term>, <term>)", function, *i));
|
||||
|
||||
return ATmake("List(<term>)", ATreverse(res));
|
||||
}
|
||||
|
|
|
@ -34,5 +34,13 @@ Expr primNull(EvalState & state);
|
|||
/* Determine whether the argument is the null value. */
|
||||
Expr primIsNull(EvalState & state, Expr arg);
|
||||
|
||||
/* Return the current time. !!! hack, impure - although due to
|
||||
memoization of evaluation results this should always yield the same
|
||||
value for a particular run of the program. */
|
||||
Expr primCurTime(EvalState & state);
|
||||
|
||||
/* Apply a function to each element of a list. */
|
||||
Expr primMap(EvalState & state, Expr arg);
|
||||
|
||||
|
||||
#endif /* !__PRIMOPS_H */
|
||||
|
|
Loading…
Reference in New Issue