Skip to content

Instantly share code, notes, and snippets.

@viperscape
Last active April 10, 2018 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save viperscape/d765a8a673dbadbddfeddb95d7d1d0e8 to your computer and use it in GitHub Desktop.
Save viperscape/d765a8a673dbadbddfeddb95d7d1d0e8 to your computer and use it in GitHub Desktop.
condapiler
node ./condapiler/condapiler.js $1
const toml = require("toml");
const watcher = require("chokidar");
const fs = require("fs");
const { exec } = require("child_process");
const cwd = process.cwd();
const watchfile = process.argv[2] ? process.argv[2] : cwd+"//watch.txt";
console.log("watching with " + watchfile);
const config_ = fs.readFileSync(watchfile);
watched = {};
to_bin = [];
const config = toml.parse(config_);
const src_path = config.src_path ? cwd + "//" + config.src_path : cwd + "//";
const out_path = config.out_path ? config.out_path : cwd;
let compile = (path) => {
console.log("compiling source:", path);
exec("gcc -Wall -c " + path + ".c", (error, stdout, stderr) => {
if (!error) {
var split = path.split("/");
split = split[split.length-1];
try {
fs.rename(split + ".o", out_path + "//" + split + ".o", (error) => {
if (error) console.error("cannot move file", error);
else if ((config.entry) && (split == config.entry)) { // if main, start link
if (config.trigger) exec("touch "+config.trigger);
}
});
}
catch (error) { console.error("cannot move file", error); }
}
else console.error("cannot compile file", path, error);
});
};
for (var dep in config.deps) {
var w = src_path + "//" + dep + ".h";
console.log("watching", dep, "with", config.deps[dep]);
for (var src in config.deps[dep]) {
if (!to_bin[config.deps[dep][src]]) to_bin[config.deps[dep][src]] = true;
}
watched[w] = config.deps[dep];
// check if header-only is set
var is_header = false;
for (h in config.header_only) {
if (config.header_only[h] == dep) {
is_header = true;
}
}
if (!is_header) {
watched[w].push(dep);
to_bin[dep] = true;
}
watcher.watch(w).on("all", (event, path) => {
if (event == "change") {
watched[path].forEach(v => {
console.log("compiling deps:", src_path + "//" + v + ".c");
compile(src_path + "//" + v);
});
}
});
}
for (var source in to_bin) {
var source_ = src_path + "//" + source;
console.log("watching source", source_);
watcher.watch(source_ + ".c").on("all", (event, path) => {
if (event == "change") {
compile(path.split(".c")[0]); // we need to remove .c from name
}
});
// compile on start
compile(source_);
}
setTimeout(function() {
// compile trigger
watcher.watch(config.trigger).on("all", (event, path) => {
if (path != config.trigger) return; // sometimes paths are similar but not same and double-trigger
console.log("compile and linking from", path, "trigger");
cmd = "gcc -Wall -g ";
for (var pre in config.prepend) cmd += config.prepend[pre] + " ";
if (config.bin) cmd += "-o " + config.bin + " ";
for (var src in config.include) cmd += config.include[src] + " ";
for (var src in to_bin) cmd += out_path + "//" + src + ".o ";
for (var link in config.link) cmd += "-l" + config.link[link] + " ";
exec(cmd, (error, stdout, stderr) => {
if (error) {
console.error("cannot link and compile", error);
}
});
});
}, 1500);
{
"name": "condapiler",
"author": "Chris Gill <chrisfgill@gmail.com>",
"version": "0.1.0",
"description": "conditional compilation for c",
"license": "Apache2",
"dependencies": {
"chokidar": "^2.0.2",
"toml": "^2.3.3"
}
}
out_path = "build"
bin = "bloodeagle"
link = ["SDL2main", "SDL2"]
src_path = "src"
trigger = "build//compile"
prepend = ["-std=c99"]
[deps]
gfx = ["main"]
sprite = ["main"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment