Permalink
Browse files

Initial import of the nodejs build system (far from complete)

  • Loading branch information...
1 parent be46b9d commit 11ca51269f206819ffdee472a5264edae7ef138d @radare committed Jul 17, 2013
Showing with 460 additions and 0 deletions.
  1. +4 −0 build/Makefile
  2. +4 −0 build/config.json
  3. +226 −0 build/make.js/index.js
  4. +103 −0 build/make.js/utils.js
  5. +88 −0 build/radare2.js
  6. +35 −0 build/stress.js
View
@@ -0,0 +1,4 @@
+T=all install clean util cons reg db sdb libr binr shlr
+.PHONY: ${T}
+${T}:
+ @node radare2.js $@
View
@@ -0,0 +1,4 @@
+{
+ 'name': 'radare2',
+ 'version': '0.9.5'
+}
View
@@ -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: ''
+ });
+ },
+}
View
@@ -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);
+ })
+ });
+ }
+}
Oops, something went wrong.

0 comments on commit 11ca512

Please sign in to comment.