Skip to content

Commit 91744aa

Browse files
stefanmbFishrock123
authored andcommitted
build: configure --shared
Add configure flag for building a shared library that can be embedded in other applications (like Electron). Add flags --without-bundled-v8 and --without-v8-platform to control V8 dependencies used. PR-URL: #6994 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Fedor Indutny <fedor@indutny.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Conflicts: src/node.cc
1 parent bc37e6a commit 91744aa

File tree

9 files changed

+212
-36
lines changed

9 files changed

+212
-36
lines changed

common.gypi

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
1212
'python%': 'python',
1313

14+
'node_shared%': 'false',
15+
'node_use_v8_platform%': 'true',
16+
'node_use_bundled_v8%': 'true',
17+
'node_module_version%': '',
18+
1419
'node_tag%': '',
1520
'uv_library%': 'static_library',
1621

@@ -290,6 +295,9 @@
290295
],
291296
'ldflags!': [ '-rdynamic' ],
292297
}],
298+
[ 'node_shared=="true"', {
299+
'cflags': [ '-fPIC' ],
300+
}],
293301
],
294302
}],
295303
[ 'OS=="android"', {

configure

+28
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ from gyp.common import GetFlavor
2424
sys.path.insert(0, os.path.join(root_dir, 'tools', 'configure.d'))
2525
import nodedownload
2626

27+
# imports in tools/
28+
sys.path.insert(0, os.path.join(root_dir, 'tools'))
29+
import getmoduleversion
30+
2731
# parse our options
2832
parser = optparse.OptionParser()
2933

@@ -420,6 +424,26 @@ parser.add_option('--without-inspector',
420424
dest='without_inspector',
421425
help='disable experimental V8 inspector support')
422426

427+
parser.add_option('--shared',
428+
action='store_true',
429+
dest='shared',
430+
help='compile shared library for embedding node in another project. ' +
431+
'(This mode is not officially supported for regular applications)')
432+
433+
parser.add_option('--without-v8-platform',
434+
action='store_true',
435+
dest='without_v8_platform',
436+
default=False,
437+
help='do not initialize v8 platform during node.js startup. ' +
438+
'(This mode is not officially supported for regular applications)')
439+
440+
parser.add_option('--without-bundled-v8',
441+
action='store_true',
442+
dest='without_bundled_v8',
443+
default=False,
444+
help='do not use V8 includes from the bundled deps folder. ' +
445+
'(This mode is not officially supported for regular applications)')
446+
423447
(options, args) = parser.parse_args()
424448

425449
# Expand ~ in the install prefix now, it gets written to multiple files.
@@ -810,6 +834,10 @@ def configure_node(o):
810834
o['variables']['node_target_type'] = 'static_library'
811835

812836
o['variables']['node_no_browser_globals'] = b(options.no_browser_globals)
837+
o['variables']['node_shared'] = b(options.shared)
838+
o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform)
839+
o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
840+
o['variables']['node_module_version'] = int(getmoduleversion.get_version())
813841

814842
if options.linked_module:
815843
o['variables']['library_files'] = options.linked_module

node.gyp

+64-17
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
'node_use_etw%': 'false',
77
'node_use_perfctr%': 'false',
88
'node_no_browser_globals%': 'false',
9+
'node_use_v8_platform%': 'true',
10+
'node_use_bundled_v8%': 'true',
11+
'node_shared%': 'false',
12+
'node_module_version%': '',
913
'node_shared_zlib%': 'false',
1014
'node_shared_http_parser%': 'false',
1115
'node_shared_cares%': 'false',
@@ -14,7 +18,6 @@
1418
'node_shared_openssl%': 'false',
1519
'node_v8_options%': '',
1620
'node_enable_v8_vtunejit%': 'false',
17-
'node_target_type%': 'executable',
1821
'node_core_target_name%': 'node',
1922
'library_files': [
2023
'lib/internal/bootstrap_node.js',
@@ -100,6 +103,13 @@
100103
'deps/v8/tools/SourceMap.js',
101104
'deps/v8/tools/tickprocessor-driver.js',
102105
],
106+
'conditions': [
107+
[ 'node_shared=="true"', {
108+
'node_target_type%': 'shared_library',
109+
}, {
110+
'node_target_type%': 'executable',
111+
}],
112+
],
103113
},
104114

105115
'targets': [
@@ -109,16 +119,13 @@
109119

110120
'dependencies': [
111121
'node_js2c#host',
112-
'deps/v8/tools/gyp/v8.gyp:v8',
113-
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
114122
],
115123

116124
'include_dirs': [
117125
'src',
118126
'tools/msvs/genfiles',
119127
'deps/uv/src/ares',
120128
'<(SHARED_INTERMEDIATE_DIR)', # for node_natives.h
121-
'deps/v8' # include/v8_platform.h
122129
],
123130

124131
'sources': [
@@ -217,6 +224,42 @@
217224

218225

219226
'conditions': [
227+
[ 'node_shared=="false"', {
228+
'msvs_settings': {
229+
'VCManifestTool': {
230+
'EmbedManifest': 'true',
231+
'AdditionalManifestFiles': 'src/res/node.exe.extra.manifest'
232+
}
233+
},
234+
}, {
235+
'defines': [
236+
'NODE_SHARED_MODE',
237+
],
238+
'conditions': [
239+
[ 'node_module_version!=""', {
240+
'product_extension': 'so.<(node_module_version)',
241+
}]
242+
],
243+
}],
244+
[ 'node_use_bundled_v8=="true"', {
245+
'include_dirs': [
246+
'deps/v8', # include/v8_platform.h
247+
],
248+
249+
'dependencies': [
250+
'deps/v8/tools/gyp/v8.gyp:v8',
251+
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
252+
],
253+
}],
254+
[ 'node_use_v8_platform=="true"', {
255+
'defines': [
256+
'NODE_USE_V8_PLATFORM=1',
257+
],
258+
}, {
259+
'defines': [
260+
'NODE_USE_V8_PLATFORM=0',
261+
],
262+
}],
220263
[ 'node_tag!=""', {
221264
'defines': [ 'NODE_TAG="<(node_tag)"' ],
222265
}],
@@ -245,7 +288,8 @@
245288
'defines': [ 'NODE_HAVE_SMALL_ICU=1' ],
246289
}]],
247290
}],
248-
[ 'node_enable_v8_vtunejit=="true" and (target_arch=="x64" or \
291+
[ 'node_use_bundled_v8=="true" and \
292+
node_enable_v8_vtunejit=="true" and (target_arch=="x64" or \
249293
target_arch=="ia32" or target_arch=="x32")', {
250294
'defines': [ 'NODE_ENABLE_VTUNE_PROFILING' ],
251295
'dependencies': [
@@ -308,7 +352,7 @@
308352
],
309353
},
310354
'conditions': [
311-
['OS in "linux freebsd"', {
355+
['OS in "linux freebsd" and node_shared=="false"', {
312356
'ldflags': [
313357
'-Wl,--whole-archive <(PRODUCT_DIR)/<(OPENSSL_PRODUCT)',
314358
'-Wl,--no-whole-archive',
@@ -395,7 +439,7 @@
395439
[ 'node_no_browser_globals=="true"', {
396440
'defines': [ 'NODE_NO_BROWSER_GLOBALS' ],
397441
} ],
398-
[ 'v8_postmortem_support=="true"', {
442+
[ 'node_use_bundled_v8=="true" and v8_postmortem_support=="true"', {
399443
'dependencies': [ 'deps/v8/tools/gyp/v8.gyp:postmortem-metadata' ],
400444
'conditions': [
401445
# -force_load is not applicable for the static library
@@ -478,7 +522,7 @@
478522
'NODE_PLATFORM="sunos"',
479523
],
480524
}],
481-
[ 'OS=="freebsd" or OS=="linux"', {
525+
[ '(OS=="freebsd" or OS=="linux") and node_shared=="false"', {
482526
'ldflags': [ '-Wl,-z,noexecstack',
483527
'-Wl,--whole-archive <(V8_BASE)',
484528
'-Wl,--no-whole-archive' ]
@@ -487,12 +531,6 @@
487531
'ldflags': [ '-Wl,-M,/usr/lib/ld/map.noexstk' ],
488532
}],
489533
],
490-
'msvs_settings': {
491-
'VCManifestTool': {
492-
'EmbedManifest': 'true',
493-
'AdditionalManifestFiles': 'src/res/node.exe.extra.manifest'
494-
}
495-
},
496534
},
497535
# generate ETW header and resource files
498536
{
@@ -718,8 +756,6 @@
718756
'deps/http_parser/http_parser.gyp:http_parser',
719757
'deps/gtest/gtest.gyp:gtest',
720758
'deps/uv/uv.gyp:libuv',
721-
'deps/v8/tools/gyp/v8.gyp:v8',
722-
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
723759
],
724760
'include_dirs': [
725761
'src',
@@ -750,7 +786,18 @@
750786
'src/inspector_socket.cc',
751787
'test/cctest/test_inspector_socket.cc'
752788
]
753-
}]
789+
}],
790+
[ 'node_use_v8_platform=="true"', {
791+
'dependencies': [
792+
'deps/v8/tools/gyp/v8.gyp:v8_libplatform',
793+
],
794+
}],
795+
[ 'node_use_bundled_v8=="true"', {
796+
'dependencies': [
797+
'deps/v8/tools/gyp/v8.gyp:v8',
798+
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
799+
],
800+
}],
754801
]
755802
}
756803
], # end targets

src/node.cc

+43-8
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
#include "string_bytes.h"
4040
#include "util.h"
4141
#include "uv.h"
42+
#if NODE_USE_V8_PLATFORM
4243
#include "libplatform/libplatform.h"
44+
#endif // NODE_USE_V8_PLATFORM
4345
#include "v8-debug.h"
4446
#include "v8-profiler.h"
4547
#include "zlib.h"
@@ -184,7 +186,42 @@ static uv_async_t dispatch_debug_messages_async;
184186

185187
static Mutex node_isolate_mutex;
186188
static v8::Isolate* node_isolate;
187-
static v8::Platform* default_platform;
189+
190+
static struct {
191+
#if NODE_USE_V8_PLATFORM
192+
void Initialize(int thread_pool_size) {
193+
platform_ = v8::platform::CreateDefaultPlatform(thread_pool_size);
194+
V8::InitializePlatform(platform_);
195+
}
196+
197+
void PumpMessageLoop(Isolate* isolate) {
198+
v8::platform::PumpMessageLoop(platform_, isolate);
199+
}
200+
201+
void Dispose() {
202+
delete platform_;
203+
platform_ = nullptr;
204+
}
205+
206+
#if HAVE_INSPECTOR
207+
void StartInspector(Environment *env, int port, bool wait) {
208+
env->inspector_agent()->Start(platform_, port, wait);
209+
}
210+
#endif // HAVE_INSPECTOR
211+
212+
v8::Platform* platform_;
213+
#else // !NODE_USE_V8_PLATFORM
214+
void Initialize(int thread_pool_size) {}
215+
void PumpMessageLoop(Isolate* isolate) {}
216+
void Dispose() {}
217+
#if HAVE_INSPECTOR
218+
void StartInspector(Environment *env, int port, bool wait) {
219+
env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
220+
}
221+
#endif // HAVE_INSPECTOR
222+
223+
#endif // !NODE_USE_V8_PLATFORM
224+
} v8_platform;
188225

189226
#ifdef __POSIX__
190227
static uv_sem_t debug_semaphore;
@@ -3736,7 +3773,7 @@ static void StartDebug(Environment* env, bool wait) {
37363773
CHECK(!debugger_running);
37373774
#if HAVE_INSPECTOR
37383775
if (use_inspector) {
3739-
env->inspector_agent()->Start(default_platform, inspector_port, wait);
3776+
v8_platform.StartInspector(env, inspector_port, wait);
37403777
debugger_running = true;
37413778
} else {
37423779
#endif
@@ -4467,11 +4504,11 @@ static void StartNodeInstance(void* arg) {
44674504
SealHandleScope seal(isolate);
44684505
bool more;
44694506
do {
4470-
v8::platform::PumpMessageLoop(default_platform, isolate);
4507+
v8_platform.PumpMessageLoop(isolate);
44714508
more = uv_run(env->event_loop(), UV_RUN_ONCE);
44724509

44734510
if (more == false) {
4474-
v8::platform::PumpMessageLoop(default_platform, isolate);
4511+
v8_platform.PumpMessageLoop(isolate);
44754512
EmitBeforeExit(env);
44764513

44774514
// Emit `beforeExit` if the loop became alive either after emitting
@@ -4537,8 +4574,7 @@ int Start(int argc, char** argv) {
45374574
V8::SetEntropySource(crypto::EntropySource);
45384575
#endif
45394576

4540-
default_platform = v8::platform::CreateDefaultPlatform(v8_thread_pool_size);
4541-
V8::InitializePlatform(default_platform);
4577+
v8_platform.Initialize(v8_thread_pool_size);
45424578
V8::Initialize();
45434579

45444580
int exit_code = 1;
@@ -4555,8 +4591,7 @@ int Start(int argc, char** argv) {
45554591
}
45564592
V8::Dispose();
45574593

4558-
delete default_platform;
4559-
default_platform = nullptr;
4594+
v8_platform.Dispose();
45604595

45614596
delete[] exec_argv;
45624597
exec_argv = nullptr;

src/node.h

+10-4
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,23 @@ extern "C" NODE_EXTERN void node_module_register(void* mod);
415415
# define NODE_MODULE_EXPORT __attribute__((visibility("default")))
416416
#endif
417417

418+
#ifdef NODE_SHARED_MODE
419+
# define NODE_CTOR_PREFIX
420+
#else
421+
# define NODE_CTOR_PREFIX static
422+
#endif
423+
418424
#if defined(_MSC_VER)
419425
#pragma section(".CRT$XCU", read)
420426
#define NODE_C_CTOR(fn) \
421-
static void __cdecl fn(void); \
427+
NODE_CTOR_PREFIX void __cdecl fn(void); \
422428
__declspec(dllexport, allocate(".CRT$XCU")) \
423429
void (__cdecl*fn ## _)(void) = fn; \
424-
static void __cdecl fn(void)
430+
NODE_CTOR_PREFIX void __cdecl fn(void)
425431
#else
426432
#define NODE_C_CTOR(fn) \
427-
static void fn(void) __attribute__((constructor)); \
428-
static void fn(void)
433+
NODE_CTOR_PREFIX void fn(void) __attribute__((constructor)); \
434+
NODE_CTOR_PREFIX void fn(void)
429435
#endif
430436

431437
#define NODE_MODULE_X(modname, regfunc, priv, flags) \

test/parallel/test-module-version.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
require('../common');
3+
var assert = require('assert');
4+
5+
// check for existence
6+
assert(process.config.variables.hasOwnProperty('node_module_version'));
7+
8+
// ensure that `node_module_version` is an Integer > 0
9+
assert(Number.isInteger(process.config.variables.node_module_version));
10+
assert(process.config.variables.node_module_version > 0);

0 commit comments

Comments
 (0)