diff --git a/README.md b/README.md index 12cf2e5..8ec17f3 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,12 @@ Nexe is a command-line utility that compiles your Node.js application into a sin ## Requirements -- Linux / Mac +- Linux / Mac / BSD / Windows +- Windows: Python 2.6 or 2.7 (in PATH), Visual Studio 2010 or 2012 ## Caveats - Doesn't support native modules (yet). -- Doesn't support windows (yet). ## Installation @@ -47,7 +47,7 @@ Options: -o, --output The output binary [default: cwd/release/app.nex] -r, --runtime The node.js runtime to use [default: "0.8.15"] -t, --temp The path to store node.js sources [default: /tmp/nexe] - + -f, --flags Don't parse node and v8 flags, pass through app flags [default: false] ```` @@ -58,7 +58,7 @@ Options: var nexe = require('nexe'); -nexe.compile({ input: 'input.js', output: 'path/to/bin', runtime: '0.8.15' } function() { +nexe.compile({ input: 'input.js', output: 'path/to/bin', runtime: '0.8.15', flags: true } function() { }); diff --git a/bin/nexe b/bin/nexe index 8f9f7ac..960e5c7 100755 --- a/bin/nexe +++ b/bin/nexe @@ -26,6 +26,11 @@ options('t', { default: '/tmp/nexe', description: 'The path to store node.js sources' }). +options('f', { + alias: 'flags', + description: 'Don\'t parse node and v8 flags, pass through app flags', + default: false +}). options('v', { alias: 'version', description: 'Display version number' @@ -54,6 +59,7 @@ function toRelative(pt) { require('../lib').compile({ input : toRelative(argv.i), output : toRelative(argv.o), + flags : argv.f, nodeVersion : argv.r, nodeTempDir : toRelative(argv.t) }, function(error) { diff --git a/lib/exe.js b/lib/exe.js index 4558863..31158ea 100644 --- a/lib/exe.js +++ b/lib/exe.js @@ -9,13 +9,16 @@ ProgressBar = require("progress"), child_process = require("child_process"), glob = require("glob"), sardines = require("sardines"), -os = require("os"), +os = require("os"), +targz = require('tar.gz'), spawn = child_process.spawn; var _log = require("./log"), _monkeypatch = require("./monkeypatch"); +var isWin = /^win/.test(process.platform); + /** */ @@ -63,6 +66,17 @@ exports.compile = function (options, complete) { _monkeyPatchNodeConfig(nodeCompiler, next); }, + /** + * monkeypatch node.cc to prevent v8 and node from processing CLI flags + */ + function monkeyPatchNodeCc (next) { + if (options.flags) { + _monkeyPatchMainCc(nodeCompiler, next); + } else { + next(); + } + }, + /** * compile the node application */ @@ -94,8 +108,8 @@ exports.compile = function (options, complete) { function _downloadNode (version, directory, complete) { - var nodeFileDir = path.join(directory, version), - nodeFilePath = path.join(nodeFileDir, "node-" + version + ".tar.gz"); + var nodeFileDir = path.resolve(path.join(process.cwd(), directory, version)), + nodeFilePath = path.resolve(path.join(nodeFileDir, "node-" + version + ".tar.gz")); // might already be downloaded, and unzipped @@ -111,7 +125,8 @@ function _downloadNode (version, directory, complete) { */ function makeDirectory (next) { - mkdirp(path.dirname(nodeFilePath), function () { next(); }) + mkdirp.sync(path.dirname(nodeFilePath)); + next(); }, /** @@ -119,7 +134,6 @@ function _downloadNode (version, directory, complete) { */ function downloadNode (next) { - if (fs.existsSync(nodeFilePath)) return next(); var url, prefix = "http://nodejs.org/dist"; @@ -145,15 +159,19 @@ function _downloadNode (version, directory, complete) { */ function unzipNodeTarball (next) { + if(isWin) { + _log("Extracting the .tar.gz."); + new targz().extract(nodeFilePath, nodeFileDir, next); + } else { + var cmd = ["tar", "-xf", nodeFilePath, "-C", nodeFileDir]; + _log(cmd.join(" ")); - var cmd = ["tar", "-xf", nodeFilePath, "-C", nodeFileDir]; - _log(cmd.join(" ")); + var tar = spawn(cmd.shift(), cmd); + tar.stdout.pipe(process.stdout); + tar.stderr.pipe(process.stderr); - var tar = spawn(cmd.shift(), cmd); - tar.stdout.pipe(process.stdout); - tar.stderr.pipe(process.stderr); - - tar.on("close", function () { next(); }) + tar.on("close", function () { next(); }) + } }, /** @@ -174,28 +192,44 @@ function _getNodeCompiler (nodeFileDir, complete) { var dir = _getFirstDirectory(nodeFileDir); if (dir) { - complete(null, { - dir: dir, - version: path.basename(nodeFileDir), - releasePath: path.join(dir, "out", "Release", "node"), - make: function (next) { - var configure = spawn("./configure", [], { cwd: dir }); - configure.stdout.pipe(process.stdout); - configure.stderr.pipe(process.stderr); - configure.on("close", function () { - var platformMake = "make"; - if (os.platform().match(/bsd$/) != null) { - platformMake = "gmake"; - } - var make = spawn(platformMake, [], { cwd: dir }); - make.stdout.pipe(process.stdout); - make.stderr.pipe(process.stderr); - make.on("close", function () { + if(isWin) { + complete(null, { + dir: dir, + version: path.basename(nodeFileDir), + releasePath: path.join(dir, "Release", "node.exe"), + make: function(next) { + var vcbuild = spawn("vcbuild.bat", ["nosign", "release"], { cwd: dir }); + vcbuild.stdout.pipe(process.stdout); + vcbuild.stderr.pipe(process.stderr); + vcbuild.on("close", function() { next(); }); - }) - } - }); + } + }); + } else { + complete(null, { + dir: dir, + version: path.basename(nodeFileDir), + releasePath: path.join(dir, "out", "Release", "node"), + make: function (next) { + var configure = spawn("./configure", [], { cwd: dir }); + configure.stdout.pipe(process.stdout); + configure.stderr.pipe(process.stderr); + configure.on("close", function () { + var platformMake = "make"; + if (os.platform().match(/bsd$/) != null) { + platformMake = "gmake"; + } + var make = spawn(platformMake, [], { cwd: dir }); + make.stdout.pipe(process.stdout); + make.stderr.pipe(process.stderr); + make.on("close", function () { + next(); + }); + }) + } + }); + } return true; } @@ -223,6 +257,7 @@ function _monkeyPatchNodeConfig (compiler, complete) { function (next) { _monkeyPatchMainJs(compiler, next) } + ], complete); } @@ -263,6 +298,34 @@ function _monkeyPatchMainJs (compiler, complete) { ); } +/** + */ + +function _monkeyPatchMainCc(compiler, complete) { + var mainPath = path.join(compiler.dir, "src", "node.cc"); + _monkeypatch( + mainPath, + function (content) { + return ~content.indexOf('// // TODO use parse opts'); + }, + function (content, next) { + var lines = content.split('\n'); + /* These lines exist until v0.11.6 */ + var startLine = lines.indexOf(' // TODO use parse opts'); + var endLine = lines.indexOf(' option_end_index = i;'); + + for (var i = startLine; i < endLine; i++) { + lines[i] = '//' + lines[i]; + } + + lines[endLine] = ' option_end_index = 1;'; + lines = lines.join('\n'); + next(null, lines); + }, + complete + ); +} + /** */ diff --git a/package.json b/package.json index 219dded..4f6b71f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Craig Condon ", "name": "nexe", "description": "Roll node.s applications into a single executable", - "version": "0.2.8", + "version": "0.2.9", "repository": { "type": "git", "url": "git://github.com/crcn/nexe.git" @@ -21,6 +21,8 @@ "colors": "~0.6.2", "glob": "~3.2.9", "progress": "~1.1.3" + "progress": "~1.1.3", + "tar.gz": "0.1.1" }, "preferGlobal": "true", "bin": {