diff --git a/nixctor/README.md b/nixctor/README.md new file mode 100644 index 0000000..2eca27e --- /dev/null +++ b/nixctor/README.md @@ -0,0 +1,30 @@ +## ctor.nix - C/C++/D buildsystem written in Nixlang + +Here is a buildsystem I made that incrementally compiles a program and +then links it together at the end. The file default.nix shows an +example on how to use this code in a real derivation, it's as simple +as just adding your source files into the `sourceFiles` array and +ctor.nix will generate a build phase and an install phase for you. It +just calls `stdenv.mkDerivation` so you'll have to supply the required +arguments to that too. + +To test: + + nix-build + +To use a different compiler or flags, you can use the `compiler` and +`cflags` arguments: + +```nix +# Example for a D program +constructProgram { + pname = "hello-world"; + version = "1.0.0"; + + src = fetchFromWhatever {}; + + compiler = "ldc2"; + cflags = "-O -wi"; + sourceFiles = [ "main.d" "lib.d" ]; +} +``` diff --git a/nixctor/ctor.nix b/nixctor/ctor.nix new file mode 100644 index 0000000..e904e73 --- /dev/null +++ b/nixctor/ctor.nix @@ -0,0 +1,54 @@ +# ctor.nix: simple buildsystem written in Nix +# It can be adapted for any language, just substitute the default arguments +args @ +{ pkgs ? import { } +, lib ? pkgs.lib +, stdenv ? pkgs.stdenv + +# Name of the compiler to use when compiling source code +, compiler ? "cc" +# Flags passed to the compiler during compilation stages. +, cflags ? "-O2 -c" +# Flags passed to the compiler at link time +, ldflags ? "" +# Flag passed to the compiler to specify the output file +, outFlag ? "-o" +# Source code files to compile +, sourceFiles ? [ "main.c" ] +# Suffix of source code files +, suffix ? ".c" +# Name of the binary file to produce +, programName ? "main" + +, ... +}: + +with builtins; +let + newline = " +"; + run = command: '' + printf '%s\n' "${command}" + ${command} + ''; + objify = sourceFile: replaceStrings [ suffix ] [ ".o" ] sourceFile; + compile = sourceFile: + "${compiler} ${cflags} ${outFlag} ${objify sourceFile} ${sourceFile}"; + link = objs: + "${compiler} ${outFlag} ${programName} ${concatStringsSep " " objs} ${ldflags}"; +in +stdenv.mkDerivation ({ + buildPhase = '' + runHook preBuild + ${concatStringsSep newline (map + (source: run (compile source)) sourceFiles)} + ${run "${link (map objify sourceFiles)}"} + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + install -Dm755 ${programName} $out/bin/${programName} + runHook postInstall + ''; +} // args) diff --git a/nixctor/default.nix b/nixctor/default.nix new file mode 100644 index 0000000..b21bb0b --- /dev/null +++ b/nixctor/default.nix @@ -0,0 +1,9 @@ +{ constructProgram ? import ./ctor.nix }: +constructProgram { + pname = "hello-world"; + version = "1.0.0"; + + src = ./.; # use the current directory + + sourceFiles = [ "main.c" "lib.c" ]; +} diff --git a/nixctor/lib.c b/nixctor/lib.c new file mode 100644 index 0000000..393d90c --- /dev/null +++ b/nixctor/lib.c @@ -0,0 +1,7 @@ +#include + +void +libfunc(void) +{ + puts("hello, world!"); +} diff --git a/nixctor/main.c b/nixctor/main.c new file mode 100644 index 0000000..b6f7838 --- /dev/null +++ b/nixctor/main.c @@ -0,0 +1,7 @@ +void libfunc(void); + +int +main(int argc, char *argv[]) +{ + libfunc(); +}