Skip to content

Commit

Permalink
Initial import of the nodejs build system (far from complete)
Browse files Browse the repository at this point in the history
  • Loading branch information
radare committed Jul 17, 2013
1 parent be46b9d commit 11ca512
Show file tree
Hide file tree
Showing 6 changed files with 460 additions and 0 deletions.
4 changes: 4 additions & 0 deletions build/Makefile
@@ -0,0 +1,4 @@
T=all install clean util cons reg db sdb libr binr shlr
.PHONY: ${T}
${T}:
@node radare2.js $@
4 changes: 4 additions & 0 deletions build/config.json
@@ -0,0 +1,4 @@
{
'name': 'radare2',
'version': '0.9.5'
}
226 changes: 226 additions & 0 deletions build/make.js/index.js
@@ -0,0 +1,226 @@
/* make.js - Public Domain - copyright 2013 - pancake */

var U = require ('./utils.js');
var fs = require ("fs");
var cleaning = [];
var targets = [];

module.exports = M = {
make: function(cfg) {
var argv = process.argv.slice(2);
var A = { targets: [] };
for (var i = 0; i< argv.length; i++) {
var k = argv[i];
if (k[0]=='-') {
switch(k) {
case '-h':
case '--help':
U.print ("Help message");
process.exit (0);
break;
}
} else A.targets[A.targets.length] = k;
}
A.run = function(t) {
const k = (A.targets[0] == 'clean');
U.iterate (t||A.targets, function (t, next, done) {
if (k) {
M.clean_target (cfg, t);
next ();
} else {
M.run_target (cfg, t, done);
next ();
}
});
}
return A;
},
mustCompile: function(s, b, file) {
try {
var x = fs.statSync (s+'/'+file);
var y = fs.statSync (b+'/'+file.replace ('.c','.o'));
return (x.atime > y.atime);
} catch (e) { }
return true;
},
link: function(cfg, b, n, f, l, cb) {
var objs = []
for (var x in f)
objs.push (b+'/'+f[x].replace ('.c', '.o'));
var ofile = b+'/'+n;
var libs = '';
for (var x in l) {
var T = cfg[l[x]];
if (!T)
U.error ("Cannot find target: "+l[x]);
libs += ' -L'+T.path+' -l'+T.name;
}
if (ofile.indexOf ('/lib'))
libs += ' -shared';
var cmd = this.cfg.CC+' -liconv '+libs+' '+
this.cfg.ldflags+' -o '+ofile+' '+objs.join(' ');
console.log ("LINK: "+cmd);
U.exec (cmd, function (oops, out, err) {
if (oops) console.log (oops, out, err);
cb ();
});
},
clean: function(s, b, f, cb) {
U.exec ('rm -rf '+b, function() {
U.print ("CLEAN done");
});
},
compile: function(s, b, f, cb) {
if (!f || f.length<1)
U.error ("Missing list of files in target.");
var ctr = f.length;
var done = 0;
for (var x in f) {
var file = f[x];
if (M.mustCompile (s, b, file)) {
var sfile = s+'/'+file;
var ofile = b+'/'+file.replace ('.c', '.o');
(function (cfg) {
var cmd = cfg.CC+' '+cfg.cflags+' -c -o '+
ofile+' '+sfile;
U.mkdir_p (b, undefined, function (err) {
if (err) U.error ("Cannot mkdir "+b);
done++;
U.print (cmd);
U.exec (cmd, function (oops, out, err) {
if (err) console.log (err);
if (oops) U.error ("Cannot compile: "+file);
if (--ctr<1) cb (done);
});
});
})(this.cfg);
} else {
ctr--;
if (ctr<1) cb (done);
}
}
},
build_program: function (cfg, t, cb) {
var sdir = cfg.root+'/'+t.path;
var bdir = t.path;
var libname = 'lib'+t.name+'.'+cfg.soext;
this.cfg = cfg;
M.compile (sdir, bdir, t.files, function() {
U.print ("LIB "+libname);
M.link (cfg, bdir, libname, t.files, t.targets, function() {
U.print ("LINK done");
cb ();
});
});
},
build_library: function (cfg, t, cb) {
var sdir = cfg.root+'/'+t.path;
var bdir = t.path;
var libname = 'lib'+t.name+'.'+cfg.soext;
this.cfg = cfg;
M.compile (sdir, bdir, t.files, function(count) {
U.print ("LIB "+libname);
if (count>0 || !U.exists (bdir+'/'+libname)) {
M.link (cfg, bdir, libname, t.files, t.targets, function() {
U.print ("LINK done for "+libname);
cb ();
});
}// else cb ();
});
},
clean_target: function(cfg, t) {
const T = cfg[t];
function rmrf(p) {
if (!cleaning[p]) {
cleaning[p] = true;
if (p && p.length>1 && U.exists (p)) {
console.log ("rm -rf "+p);
U.exec ('rm -rf ./'+p);
}
}
 }
U.iterate (T.targets, function (t, next) {
M.clean_target (cfg, t);
rmrf (T.path);
next ();
}, function() {
rmrf (T.path);
});
},
install_target: function() {
U.error ("TODO: install");
},
run_target: function(cfg, t, cb) {
const T = cfg[t];
if (targets[t]) {
targets[t].push (cb);
return;
}
function callbacks(n, x) {
for (var i in targets[n])
targets[n][i](x);
targets[n] = undefined;
}
targets [t] = [cb];
console.log ("DO "+t);
if (!T) return callbacks (t, false);
U.print ("Running target "+t);
U.iterate (T.targets, function (t, next, done) {
M.run_target (cfg, t, function() {
done ();
});
next ();
}, function(x) {
console.log ("NOW RUN "+t+ "--- "+x);
//return;
//if (!x) return;
if (T.type) {
switch (T.type) {
case 'program':
U.print ("Building program: "+T.name);
M.build_program (cfg, T, function() {
callbacks (t, true);
});
break;
case 'library':
U.print ("Building library: "+T.name);
M.build_library (cfg, T, function() {
callbacks (t, true);
});
break;
case undefined:
break;
default:
U.error ("Unknown type for target: "+t+" : "+ T.type);
break;
}
}
//callbacks (t, true);
});
//}, 1000*Math.random()%10000);
//callbacks (t, true);
/*
if (T.targets) {
var count = T.targets.length;
for (var i in T.targets) {
M.run_target (cfg, T.targets[i], function() {
count--;
if (count ==0) {
console.log ("DONE "+t);
cb ();
}
});
}
*/
/*
// Run dependencies
console.log ("T", T, "t", t);
*/
},
cast_install: function(I) {
return merge (I, {
prefix: '/usr',
destdir: ''
});
},
}
103 changes: 103 additions & 0 deletions build/make.js/utils.js
@@ -0,0 +1,103 @@
/* utils.js - Public Domain - copyright 2013 - pancake */

var fs = require ('fs');
var exec = require('child_process').exec;
var cmds = 0;
var mkdir_callbacks = {};

var U = module.exports = {
red: "\x1b[31m",
green: "\x1b[32m",
reset: "\x1b[0m",
slurp: function(file) {
return fs.readFileSync (file);;
},
exists: function (f) {
try { return !!fs.statSync (f);
} catch(e) { return false; }
},
exec: function (cmd, cb) {
cmds ++;
exec(cmd,cb);
/*
if (cmds>10) {
setTimeout (function () {
exec(cmd,cb);
//exec (cmd, function() { cb(a,b,c);cmds--; });
}, 300);
} else {
// exec (cmd, function(a,b,c) { cb(a,b,c);cmds--; });
exec(cmd,cb);
}
*/
},
error: function() {
var x = arguments
x[0] = module.exports.red + x[0];
x[x.length-1] = x[x.length-1] + module.exports.reset;
console.log (x[0]);
process.exit (1);
},
print: function() {
var x = arguments
x[0] = module.exports.green + x[0];
x[x.length-1] = x[x.length-1] + module.exports.reset;
console.log (x[0]);
},
load_config: function() {
this.slurp (file)
},
merge: function(I, defaults) {
for (var a in defaults)
I[a] = I[a] || defaults[a];
return I;
},
iterate: function(list, cb, eb) {
if (list && list.length>0) {
var count = list.length;
(function iterate (list, cb, eb) {
if (list.length>0) {
cb (list[0],
function() { iterate (list.slice(1), cb, eb); },
function() { count--; if (eb && count==0) eb(true); }
);
} else if (eb) eb (false);
})(list, cb, eb);
} else {
//if (cb) cb ();
if (eb) eb (false);
}
},
mkdir_p: function (path, mode, cb, position) {
mode = mode || 0755;
position = position || 0;
parts = require ('path').normalize (path).split('/');
if (position == 0) {
if (mkdir_callbacks[path]) {
mkdir_callbacks[path].push (cb);
return;
} else {
mkdir_callbacks[path] = [cb];
}
}
function callbacks(x) {
for (var i in mkdir_callbacks[path])
mkdir_callbacks[path][i](x);
mkdir_callbacks[path] = undefined;
}
if (position >= parts.length)
return callbacks (false); // full path created

var directory = parts.slice (0, position + 1).join('/');
fs.stat (directory, function (err) {
if (err === null) {
return U.mkdir_p (path, mode, cb, position + 1);
}
fs.mkdir (directory, mode, function (err) {
if (err)
return callbacks(true);
U.mkdir_p (path, mode, cb, position + 1);
})
});
}
}

0 comments on commit 11ca512

Please sign in to comment.