diff --git a/generate/templates/manual/include/init_ssh2.h b/generate/templates/manual/include/init_ssh2.h new file mode 100644 index 000000000..d7f92b71a --- /dev/null +++ b/generate/templates/manual/include/init_ssh2.h @@ -0,0 +1,6 @@ +#ifndef INIT_SSH2 +#define INIT_SSH2 + +void init_ssh2(); + +#endif diff --git a/generate/templates/manual/src/init_ssh2.cc b/generate/templates/manual/src/init_ssh2.cc new file mode 100644 index 000000000..a8e2543c2 --- /dev/null +++ b/generate/templates/manual/src/init_ssh2.cc @@ -0,0 +1,12 @@ +// We are initializing libssh2 from a separate .cc file to avoid ssize_t +// redefinition conflicts caused by incliding both node.h and libssh2.h from +// the same file (e.g. nodegit.cc) +// +// The redefinition can also be avoided by #defines but that is risky in case +// the libraries depend on the different definitions. + +#include + +void init_ssh2() { + libssh2_init(0); +} diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp index 81b7a8708..9c5649abb 100644 --- a/generate/templates/templates/binding.gyp +++ b/generate/templates/templates/binding.gyp @@ -16,6 +16,7 @@ "sources": [ "src/lock_master.cc", "src/nodegit.cc", + "src/init_ssh2.cc", "src/promise_completion.cc", "src/wrapper.cc", "src/functions/copy.cc", @@ -32,6 +33,8 @@ "include_dirs": [ "vendor/libv8-convert", + "vendor/libssh2/include", + "vendor/openssl/openssl/include", " + #include #include #include #include #include +#include + +#include "../include/init_ssh2.h" #include "../include/lock_master.h" #include "../include/wrapper.h" #include "../include/promise_completion.h" @@ -39,7 +43,35 @@ void LockMasterGetDiagnostics(const FunctionCallbackInfo& info) { info.GetReturnValue().Set(result); } +static uv_mutex_t *opensslMutexes; + +void OpenSSL_LockingCallback(int mode, int type, const char *, int) { + if (mode & CRYPTO_LOCK) { + uv_mutex_lock(&opensslMutexes[type]); + } else { + uv_mutex_unlock(&opensslMutexes[type]); + } +} + +unsigned long OpenSSL_IDCallback() { + return (unsigned long)uv_thread_self(); +} + +void OpenSSL_ThreadSetup() { + opensslMutexes=(uv_mutex_t *)malloc(CRYPTO_num_locks() * sizeof(uv_mutex_t)); + + for (int i=0; i target) { + // Initialize thread safety in openssl and libssh2 + OpenSSL_ThreadSetup(); + init_ssh2(); // Initialize libgit2. git_libgit2_init(); diff --git a/lifecycleScripts/configureLibssh2.js b/lifecycleScripts/configureLibssh2.js index a7faefed1..efc3920c1 100644 --- a/lifecycleScripts/configureLibssh2.js +++ b/lifecycleScripts/configureLibssh2.js @@ -9,9 +9,19 @@ module.exports = function retrieveExternalDependencies() { return new Promise(function(resolve, reject) { console.info("[nodegit] Configuring libssh2."); - cp.execFile( - rooted("vendor/libssh2/") + "configure", - {cwd: rooted("vendor/libssh2/")}, + var opensslDir = rooted("vendor/openssl/openssl"); + var newEnv = {}; + Object.keys(process.env).forEach(function(key) { + newEnv[key] = process.env[key]; + }); + newEnv.CPPFLAGS = newEnv.CPPFLAGS || ""; + newEnv.CPPFLAGS += " -I" + path.join(opensslDir, "include"); + newEnv.CPPFLAGS = newEnv.CPPFLAGS.trim(); + + cp.exec( + rooted("vendor/libssh2/configure") + + " --with-libssl-prefix=" + opensslDir, + {cwd: rooted("vendor/libssh2/"), env: newEnv}, function(err, stdout, stderr) { if (err) { console.error(err); diff --git a/lifecycleScripts/install.js b/lifecycleScripts/install.js index 29a23afc3..56628d212 100644 --- a/lifecycleScripts/install.js +++ b/lifecycleScripts/install.js @@ -1,11 +1,11 @@ var promisify = require("promisify-node"); var path = require("path"); var fs = require("fs"); - +var cp = require("child_process"); var prepareForBuild = require("./prepareForBuild"); var exec = promisify(function(command, opts, callback) { - return require("child_process").exec(command, opts, callback); + return cp.exec(command, opts, callback); }); var fromRegistry; @@ -52,7 +52,9 @@ function installPrebuilt() { function pathForTool(name) { var toolPath = path.resolve(".", "node_modules", ".bin", name); - toolPath = "\"" + toolPath + "\""; + if (process.platform == "win32") { + toolPath += ".cmd"; + } return toolPath; } @@ -72,7 +74,8 @@ function build() { var opts = { cwd: ".", maxBuffer: Number.MAX_VALUE, - env: process.env + env: process.env, + stdio: "inherit" }; var builder = "node-gyp"; @@ -104,26 +107,27 @@ function build() { opts.env.HOME = path.join(home, ".nodegit-gyp"); - var cmd = [ - pathForTool(builder), + var cmd = pathForTool(builder); + var args = [ "rebuild", debug, target, distUrl ] .join(" ") - .trim(); - - return exec(cmd, opts) - .then(function() { - console.info("[nodegit] Compilation complete."); - console.info("[nodegit] Completed installation successfully."); - process.exitCode = 0; - }, - function(err, stderr) { - console.error(err); - console.error(stderr); + .trim() + .split(" "); + return new Promise(function(resolve, reject) { + var child = cp.spawn(cmd, args, opts); + child.on("close", function(code) { + console.log(code); + if (code) { + reject(code); process.exitCode = 13; } - ); + else { + resolve(); + } + }); + }); }