From 9cc969b585947b10482e0f0f9a6bba798a8e7d80 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Sat, 26 Mar 2016 20:17:55 -0400 Subject: [PATCH] build: configure --embedded/--no-v8-platform Add configure flag for building shared library that could be used to embed node.js in some application (like Electron). This commit is esentially a merged and refined version of: * atom/node@289649a919d557182ff951589fc9859778206e4c * atom/node@f76669ffdcb8613133dc9c3764fb21c10207582e * atom/node@0828dfa193038209b7b337ba5479c3373f7cf87f --- common.gypi | 3 +++ configure | 14 ++++++++++ node.gyp | 74 +++++++++++++++++++++++++++++++++++++++++++---------- src/node.cc | 39 ++++++++++++++++++++++------ src/node.h | 14 +++++++--- 5 files changed, 118 insertions(+), 26 deletions(-) diff --git a/common.gypi b/common.gypi index ac06e55b181e67..086e6f6f89b2f3 100644 --- a/common.gypi +++ b/common.gypi @@ -11,6 +11,9 @@ 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way 'python%': 'python', + 'node_shared%': 'false', + 'node_no_v8_platform%': 'false', + 'node_tag%': '', 'uv_library%': 'static_library', diff --git a/configure b/configure index 03a889d04a400f..6589ddd5a904c3 100755 --- a/configure +++ b/configure @@ -400,6 +400,18 @@ parser.add_option('--no-browser-globals', help='do not export browser globals like setTimeout, console, etc. ' + '(This mode is not officially supported for regular applications)') +parser.add_option('--shared', + action='store_true', + dest='shared', + help='compile shared library for embedding node in another project. ' + + '(This mode is not officially supported for regular applications)') + +parser.add_option('--no-v8-platform', + action='store_true', + dest='no_v8_platform', + help='do not initialize v8 platform during node.js startup. ' + + '(This mode is not officially supported for regular applications)') + (options, args) = parser.parse_args() # Expand ~ in the install prefix now, it gets written to multiple files. @@ -793,6 +805,8 @@ def configure_node(o): o['variables']['node_target_type'] = 'static_library' o['variables']['node_no_browser_globals'] = b(options.no_browser_globals) + o['variables']['node_shared'] = b(options.shared) + o['variables']['node_no_v8_platform'] = b(options.no_v8_platform) if options.linked_module: o['variables']['library_files'] = options.linked_module diff --git a/node.gyp b/node.gyp index 0e9fe40c419af6..6babc72a45053f 100644 --- a/node.gyp +++ b/node.gyp @@ -6,6 +6,8 @@ 'node_use_etw%': 'false', 'node_use_perfctr%': 'false', 'node_no_browser_globals%': 'false', + 'node_no_v8_platform%': 'false', + 'node_shared%': 'false', 'node_shared_zlib%': 'false', 'node_shared_http_parser%': 'false', 'node_shared_cares%': 'false', @@ -14,7 +16,6 @@ 'node_shared_openssl%': 'false', 'node_v8_options%': '', 'node_enable_v8_vtunejit%': 'false', - 'node_target_type%': 'executable', 'node_core_target_name%': 'node', 'library_files': [ 'lib/internal/bootstrap_node.js', @@ -99,6 +100,14 @@ 'deps/v8/tools/SourceMap.js', 'deps/v8/tools/tickprocessor-driver.js', ], + + 'conditions': [ + [ 'node_shared=="true"', { + 'node_target_type%': 'shared_library', + }, { + 'node_target_type%': 'executable', + }], + ], }, 'targets': [ @@ -108,8 +117,6 @@ 'dependencies': [ 'node_js2c#host', - 'deps/v8/tools/gyp/v8.gyp:v8', - 'deps/v8/tools/gyp/v8.gyp:v8_libplatform' ], 'include_dirs': [ @@ -117,7 +124,6 @@ 'tools/msvs/genfiles', 'deps/uv/src/ares', '<(SHARED_INTERMEDIATE_DIR)', # for node_natives.h - 'deps/v8' # include/v8_platform.h ], 'sources': [ @@ -214,6 +220,39 @@ 'conditions': [ + [ 'node_shared=="false"', { + 'dependencies': [ + 'deps/v8/tools/gyp/v8.gyp:v8', + ], + + 'msvs_settings': { + 'VCManifestTool': { + 'EmbedManifest': 'true', + 'AdditionalManifestFiles': 'src/res/node.exe.extra.manifest' + } + }, + }, { + 'defines': [ + 'NODE_SHARED_MODE', + ], + + 'libraries': [ + '-lv8', + ], + }], + [ 'node_no_v8_platform=="false"', { + 'include_dirs': [ + 'deps/v8', # include/v8_platform.h + ], + + 'dependencies': [ + 'deps/v8/tools/gyp/v8.gyp:v8_libplatform', + ], + }, { + 'defines': [ + 'NODE_NO_V8_PLATFORM', + ], + }], [ 'node_tag!=""', { 'defines': [ 'NODE_TAG="<(node_tag)"' ], }], @@ -242,7 +281,8 @@ 'defines': [ 'NODE_HAVE_SMALL_ICU=1' ], }]], }], - [ 'node_enable_v8_vtunejit=="true" and (target_arch=="x64" or \ + [ 'node_shared=="false" and \ + node_enable_v8_vtunejit=="true" and (target_arch=="x64" or \ target_arch=="ia32" or target_arch=="x32")', { 'defines': [ 'NODE_ENABLE_VTUNE_PROFILING' ], 'dependencies': [ @@ -370,7 +410,7 @@ [ 'node_no_browser_globals=="true"', { 'defines': [ 'NODE_NO_BROWSER_GLOBALS' ], } ], - [ 'v8_postmortem_support=="true"', { + [ 'node_shared=="false" and v8_postmortem_support=="true"', { 'dependencies': [ 'deps/v8/tools/gyp/v8.gyp:postmortem-metadata' ], 'conditions': [ # -force_load is not applicable for the static library @@ -462,12 +502,6 @@ 'ldflags': [ '-Wl,-M,/usr/lib/ld/map.noexstk' ], }], ], - 'msvs_settings': { - 'VCManifestTool': { - 'EmbedManifest': 'true', - 'AdditionalManifestFiles': 'src/res/node.exe.extra.manifest' - } - }, }, # generate ETW header and resource files { @@ -690,9 +724,21 @@ 'type': 'executable', 'dependencies': [ 'deps/gtest/gtest.gyp:gtest', - 'deps/v8/tools/gyp/v8.gyp:v8', - 'deps/v8/tools/gyp/v8.gyp:v8_libplatform' ], + + 'conditions': [ + [ 'node_shared=="false"', { + 'dependencies': [ + 'deps/v8/tools/gyp/v8.gyp:v8', + ], + }], + [ 'node_no_v8_platform=="false"', { + 'dependencies': [ + 'deps/v8/tools/gyp/v8.gyp:v8_libplatform', + ], + }], + ], + 'include_dirs': [ 'src', 'deps/v8/include' diff --git a/src/node.cc b/src/node.cc index 53d390a467983a..c0f9878fca1c2a 100644 --- a/src/node.cc +++ b/src/node.cc @@ -39,7 +39,9 @@ #include "string_bytes.h" #include "util.h" #include "uv.h" -#include "libplatform/libplatform.h" +#ifndef NODE_NO_V8_PLATFORM +# include "libplatform/libplatform.h" +#endif // NODE_NO_V8_PLATFORM #include "v8-debug.h" #include "v8-profiler.h" #include "zlib.h" @@ -183,7 +185,30 @@ static bool debugger_running; static uv_async_t dispatch_debug_messages_async; static node::atomic node_isolate; -static v8::Platform* default_platform; + +static struct { +#ifdef NODE_NO_V8_PLATFORM + void Initialize(int thread_pool_size) {} + void PumpMessageLoop(Isolate* isolate) {} + void Dispose() {} +#else // !NODE_NO_V8_PLATFORM + void Initialize(int thread_pool_size) { + platform = v8::platform::CreateDefaultPlatform(thread_pool_size); + V8::InitializePlatform(platform); + } + + void PumpMessageLoop(Isolate* isolate) { + v8::platform::PumpMessageLoop(platform, isolate); + } + + void Dispose() { + delete platform; + platform = nullptr; + } + + static v8::Platform* platform; +#endif // !NODE_NO_V8_PLATFORM +} v8_platform; static void PrintErrorString(const char* format, ...) { va_list ap; @@ -4299,11 +4324,11 @@ static void StartNodeInstance(void* arg) { SealHandleScope seal(isolate); bool more; do { - v8::platform::PumpMessageLoop(default_platform, isolate); + v8_platform.PumpMessageLoop(isolate); more = uv_run(env->event_loop(), UV_RUN_ONCE); if (more == false) { - v8::platform::PumpMessageLoop(default_platform, isolate); + v8_platform.PumpMessageLoop(isolate); EmitBeforeExit(env); // Emit `beforeExit` if the loop became alive either after emitting @@ -4367,8 +4392,7 @@ int Start(int argc, char** argv) { V8::SetEntropySource(crypto::EntropySource); #endif - default_platform = v8::platform::CreateDefaultPlatform(v8_thread_pool_size); - V8::InitializePlatform(default_platform); + v8_platform.Initialize(v8_thread_pool_size); V8::Initialize(); int exit_code = 1; @@ -4385,8 +4409,7 @@ int Start(int argc, char** argv) { } V8::Dispose(); - delete default_platform; - default_platform = nullptr; + v8_platform.Dispose(); delete[] exec_argv; exec_argv = nullptr; diff --git a/src/node.h b/src/node.h index 59df8e18b4f626..d64d1a49abcb2c 100644 --- a/src/node.h +++ b/src/node.h @@ -403,17 +403,23 @@ extern "C" NODE_EXTERN void node_module_register(void* mod); # define NODE_MODULE_EXPORT __attribute__((visibility("default"))) #endif +#ifdef NODE_EMBEDDED_MODE +# define NODE_CTOR_PREFIX +#else +# define NODE_CTOR_PREFIX static +#endif + #if defined(_MSC_VER) #pragma section(".CRT$XCU", read) #define NODE_C_CTOR(fn) \ - static void __cdecl fn(void); \ + NODE_CTOR_PREFIX void __cdecl fn(void); \ __declspec(dllexport, allocate(".CRT$XCU")) \ void (__cdecl*fn ## _)(void) = fn; \ - static void __cdecl fn(void) + NODE_CTOR_PREFIX void __cdecl fn(void) #else #define NODE_C_CTOR(fn) \ - static void fn(void) __attribute__((constructor)); \ - static void fn(void) + NODE_CTOR_PREFIX void fn(void) __attribute__((constructor)); \ + NODE_CTOR_PREFIX void fn(void) #endif #define NODE_MODULE_X(modname, regfunc, priv, flags) \