mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 21:19:50 +01:00
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: https://github.com/nodejs/node/pull/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>
This commit is contained in:
parent
86e07b7c24
commit
410296c37a
@ -11,6 +11,11 @@
|
||||
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
|
||||
'python%': 'python',
|
||||
|
||||
'node_shared%': 'false',
|
||||
'node_use_v8_platform%': 'true',
|
||||
'node_use_bundled_v8%': 'true',
|
||||
'node_module_version%': '',
|
||||
|
||||
'node_tag%': '',
|
||||
'uv_library%': 'static_library',
|
||||
|
||||
@ -290,6 +295,9 @@
|
||||
],
|
||||
'ldflags!': [ '-rdynamic' ],
|
||||
}],
|
||||
[ 'node_shared=="true"', {
|
||||
'cflags': [ '-fPIC' ],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'OS=="android"', {
|
||||
|
28
configure
vendored
28
configure
vendored
@ -24,6 +24,10 @@ from gyp.common import GetFlavor
|
||||
sys.path.insert(0, os.path.join(root_dir, 'tools', 'configure.d'))
|
||||
import nodedownload
|
||||
|
||||
# imports in tools/
|
||||
sys.path.insert(0, os.path.join(root_dir, 'tools'))
|
||||
import getmoduleversion
|
||||
|
||||
# parse our options
|
||||
parser = optparse.OptionParser()
|
||||
|
||||
@ -420,6 +424,26 @@ parser.add_option('--without-inspector',
|
||||
dest='without_inspector',
|
||||
help='disable experimental V8 inspector support')
|
||||
|
||||
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('--without-v8-platform',
|
||||
action='store_true',
|
||||
dest='without_v8_platform',
|
||||
default=False,
|
||||
help='do not initialize v8 platform during node.js startup. ' +
|
||||
'(This mode is not officially supported for regular applications)')
|
||||
|
||||
parser.add_option('--without-bundled-v8',
|
||||
action='store_true',
|
||||
dest='without_bundled_v8',
|
||||
default=False,
|
||||
help='do not use V8 includes from the bundled deps folder. ' +
|
||||
'(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.
|
||||
@ -810,6 +834,10 @@ 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_use_v8_platform'] = b(not options.without_v8_platform)
|
||||
o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
|
||||
o['variables']['node_module_version'] = int(getmoduleversion.get_version())
|
||||
|
||||
if options.linked_module:
|
||||
o['variables']['library_files'] = options.linked_module
|
||||
|
81
node.gyp
81
node.gyp
@ -6,6 +6,10 @@
|
||||
'node_use_etw%': 'false',
|
||||
'node_use_perfctr%': 'false',
|
||||
'node_no_browser_globals%': 'false',
|
||||
'node_use_v8_platform%': 'true',
|
||||
'node_use_bundled_v8%': 'true',
|
||||
'node_shared%': 'false',
|
||||
'node_module_version%': '',
|
||||
'node_shared_zlib%': 'false',
|
||||
'node_shared_http_parser%': 'false',
|
||||
'node_shared_cares%': 'false',
|
||||
@ -14,7 +18,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',
|
||||
@ -100,6 +103,13 @@
|
||||
'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': [
|
||||
@ -109,8 +119,6 @@
|
||||
|
||||
'dependencies': [
|
||||
'node_js2c#host',
|
||||
'deps/v8/tools/gyp/v8.gyp:v8',
|
||||
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
|
||||
],
|
||||
|
||||
'include_dirs': [
|
||||
@ -118,7 +126,6 @@
|
||||
'tools/msvs/genfiles',
|
||||
'deps/uv/src/ares',
|
||||
'<(SHARED_INTERMEDIATE_DIR)', # for node_natives.h
|
||||
'deps/v8' # include/v8_platform.h
|
||||
],
|
||||
|
||||
'sources': [
|
||||
@ -217,6 +224,42 @@
|
||||
|
||||
|
||||
'conditions': [
|
||||
[ 'node_shared=="false"', {
|
||||
'msvs_settings': {
|
||||
'VCManifestTool': {
|
||||
'EmbedManifest': 'true',
|
||||
'AdditionalManifestFiles': 'src/res/node.exe.extra.manifest'
|
||||
}
|
||||
},
|
||||
}, {
|
||||
'defines': [
|
||||
'NODE_SHARED_MODE',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'node_module_version!=""', {
|
||||
'product_extension': 'so.<(node_module_version)',
|
||||
}]
|
||||
],
|
||||
}],
|
||||
[ 'node_use_bundled_v8=="true"', {
|
||||
'include_dirs': [
|
||||
'deps/v8', # include/v8_platform.h
|
||||
],
|
||||
|
||||
'dependencies': [
|
||||
'deps/v8/tools/gyp/v8.gyp:v8',
|
||||
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
|
||||
],
|
||||
}],
|
||||
[ 'node_use_v8_platform=="true"', {
|
||||
'defines': [
|
||||
'NODE_USE_V8_PLATFORM=1',
|
||||
],
|
||||
}, {
|
||||
'defines': [
|
||||
'NODE_USE_V8_PLATFORM=0',
|
||||
],
|
||||
}],
|
||||
[ 'node_tag!=""', {
|
||||
'defines': [ 'NODE_TAG="<(node_tag)"' ],
|
||||
}],
|
||||
@ -245,7 +288,8 @@
|
||||
'defines': [ 'NODE_HAVE_SMALL_ICU=1' ],
|
||||
}]],
|
||||
}],
|
||||
[ 'node_enable_v8_vtunejit=="true" and (target_arch=="x64" or \
|
||||
[ 'node_use_bundled_v8=="true" and \
|
||||
node_enable_v8_vtunejit=="true" and (target_arch=="x64" or \
|
||||
target_arch=="ia32" or target_arch=="x32")', {
|
||||
'defines': [ 'NODE_ENABLE_VTUNE_PROFILING' ],
|
||||
'dependencies': [
|
||||
@ -308,7 +352,7 @@
|
||||
],
|
||||
},
|
||||
'conditions': [
|
||||
['OS in "linux freebsd"', {
|
||||
['OS in "linux freebsd" and node_shared=="false"', {
|
||||
'ldflags': [
|
||||
'-Wl,--whole-archive <(PRODUCT_DIR)/<(OPENSSL_PRODUCT)',
|
||||
'-Wl,--no-whole-archive',
|
||||
@ -395,7 +439,7 @@
|
||||
[ 'node_no_browser_globals=="true"', {
|
||||
'defines': [ 'NODE_NO_BROWSER_GLOBALS' ],
|
||||
} ],
|
||||
[ 'v8_postmortem_support=="true"', {
|
||||
[ 'node_use_bundled_v8=="true" and v8_postmortem_support=="true"', {
|
||||
'dependencies': [ 'deps/v8/tools/gyp/v8.gyp:postmortem-metadata' ],
|
||||
'conditions': [
|
||||
# -force_load is not applicable for the static library
|
||||
@ -478,7 +522,7 @@
|
||||
'NODE_PLATFORM="sunos"',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="freebsd" or OS=="linux"', {
|
||||
[ '(OS=="freebsd" or OS=="linux") and node_shared=="false"', {
|
||||
'ldflags': [ '-Wl,-z,noexecstack',
|
||||
'-Wl,--whole-archive <(V8_BASE)',
|
||||
'-Wl,--no-whole-archive' ]
|
||||
@ -487,12 +531,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
|
||||
{
|
||||
@ -718,8 +756,6 @@
|
||||
'deps/http_parser/http_parser.gyp:http_parser',
|
||||
'deps/gtest/gtest.gyp:gtest',
|
||||
'deps/uv/uv.gyp:libuv',
|
||||
'deps/v8/tools/gyp/v8.gyp:v8',
|
||||
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
|
||||
],
|
||||
'include_dirs': [
|
||||
'src',
|
||||
@ -750,7 +786,18 @@
|
||||
'src/inspector_socket.cc',
|
||||
'test/cctest/test_inspector_socket.cc'
|
||||
]
|
||||
}]
|
||||
}],
|
||||
[ 'node_use_v8_platform=="true"', {
|
||||
'dependencies': [
|
||||
'deps/v8/tools/gyp/v8.gyp:v8_libplatform',
|
||||
],
|
||||
}],
|
||||
[ 'node_use_bundled_v8=="true"', {
|
||||
'dependencies': [
|
||||
'deps/v8/tools/gyp/v8.gyp:v8',
|
||||
'deps/v8/tools/gyp/v8.gyp:v8_libplatform'
|
||||
],
|
||||
}],
|
||||
]
|
||||
}
|
||||
], # end targets
|
||||
|
51
src/node.cc
51
src/node.cc
@ -39,7 +39,9 @@
|
||||
#include "string_bytes.h"
|
||||
#include "util.h"
|
||||
#include "uv.h"
|
||||
#if NODE_USE_V8_PLATFORM
|
||||
#include "libplatform/libplatform.h"
|
||||
#endif // NODE_USE_V8_PLATFORM
|
||||
#include "v8-debug.h"
|
||||
#include "v8-profiler.h"
|
||||
#include "zlib.h"
|
||||
@ -183,7 +185,42 @@ static uv_async_t dispatch_debug_messages_async;
|
||||
|
||||
static Mutex node_isolate_mutex;
|
||||
static v8::Isolate* node_isolate;
|
||||
static v8::Platform* default_platform;
|
||||
|
||||
static struct {
|
||||
#if NODE_USE_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;
|
||||
}
|
||||
|
||||
#if HAVE_INSPECTOR
|
||||
void StartInspector(Environment *env, int port, bool wait) {
|
||||
env->inspector_agent()->Start(platform_, port, wait);
|
||||
}
|
||||
#endif // HAVE_INSPECTOR
|
||||
|
||||
v8::Platform* platform_;
|
||||
#else // !NODE_USE_V8_PLATFORM
|
||||
void Initialize(int thread_pool_size) {}
|
||||
void PumpMessageLoop(Isolate* isolate) {}
|
||||
void Dispose() {}
|
||||
#if HAVE_INSPECTOR
|
||||
void StartInspector(Environment *env, int port, bool wait) {
|
||||
env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
|
||||
}
|
||||
#endif // HAVE_INSPECTOR
|
||||
|
||||
#endif // !NODE_USE_V8_PLATFORM
|
||||
} v8_platform;
|
||||
|
||||
#ifdef __POSIX__
|
||||
static uv_sem_t debug_semaphore;
|
||||
@ -3652,7 +3689,7 @@ static void StartDebug(Environment* env, bool wait) {
|
||||
CHECK(!debugger_running);
|
||||
#if HAVE_INSPECTOR
|
||||
if (use_inspector) {
|
||||
env->inspector_agent()->Start(default_platform, inspector_port, wait);
|
||||
v8_platform.StartInspector(env, inspector_port, wait);
|
||||
debugger_running = true;
|
||||
} else {
|
||||
#endif
|
||||
@ -4299,11 +4336,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
|
||||
@ -4364,8 +4401,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;
|
||||
@ -4382,8 +4418,7 @@ int Start(int argc, char** argv) {
|
||||
}
|
||||
V8::Dispose();
|
||||
|
||||
delete default_platform;
|
||||
default_platform = nullptr;
|
||||
v8_platform.Dispose();
|
||||
|
||||
delete[] exec_argv;
|
||||
exec_argv = nullptr;
|
||||
|
14
src/node.h
14
src/node.h
@ -411,17 +411,23 @@ extern "C" NODE_EXTERN void node_module_register(void* mod);
|
||||
# define NODE_MODULE_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#ifdef NODE_SHARED_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) \
|
||||
|
10
test/parallel/test-module-version.js
Normal file
10
test/parallel/test-module-version.js
Normal file
@ -0,0 +1,10 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
var assert = require('assert');
|
||||
|
||||
// check for existence
|
||||
assert(process.config.variables.hasOwnProperty('node_module_version'));
|
||||
|
||||
// ensure that `node_module_version` is an Integer > 0
|
||||
assert(Number.isInteger(process.config.variables.node_module_version));
|
||||
assert(process.config.variables.node_module_version > 0);
|
24
tools/getmoduleversion.py
Normal file
24
tools/getmoduleversion.py
Normal file
@ -0,0 +1,24 @@
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import re
|
||||
|
||||
def get_version():
|
||||
node_version_h = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'..',
|
||||
'src',
|
||||
'node_version.h')
|
||||
|
||||
f = open(node_version_h)
|
||||
|
||||
regex = '^#define NODE_MODULE_VERSION [0-9]+'
|
||||
|
||||
for line in f:
|
||||
if re.match(regex, line):
|
||||
major = line.split()[2]
|
||||
return major
|
||||
|
||||
raise Exception('Could not find pattern matching %s' % regex)
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(get_version())
|
@ -1,16 +1,20 @@
|
||||
import os,re
|
||||
import os
|
||||
import re
|
||||
|
||||
node_version_h = os.path.join(os.path.dirname(__file__), '..', 'src',
|
||||
node_version_h = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'..',
|
||||
'src',
|
||||
'node_version.h')
|
||||
|
||||
f = open(node_version_h)
|
||||
|
||||
for line in f:
|
||||
if re.match('#define NODE_MAJOR_VERSION', line):
|
||||
if re.match('^#define NODE_MAJOR_VERSION', line):
|
||||
major = line.split()[2]
|
||||
if re.match('#define NODE_MINOR_VERSION', line):
|
||||
if re.match('^#define NODE_MINOR_VERSION', line):
|
||||
minor = line.split()[2]
|
||||
if re.match('#define NODE_PATCH_VERSION', line):
|
||||
if re.match('^#define NODE_PATCH_VERSION', line):
|
||||
patch = line.split()[2]
|
||||
|
||||
print '%(major)s.%(minor)s.%(patch)s'% locals()
|
||||
|
@ -6,6 +6,7 @@ import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
from getmoduleversion import get_version
|
||||
|
||||
# set at init time
|
||||
node_prefix = '/usr/local' # PREFIX variable from Makefile
|
||||
@ -107,9 +108,22 @@ def subdir_files(path, dest, action):
|
||||
|
||||
def files(action):
|
||||
is_windows = sys.platform == 'win32'
|
||||
output_file = 'node'
|
||||
output_prefix = 'out/Release/'
|
||||
|
||||
exeext = '.exe' if is_windows else ''
|
||||
action(['out/Release/node' + exeext], 'bin/node' + exeext)
|
||||
if 'false' == variables.get('node_shared'):
|
||||
if is_windows:
|
||||
output_file += '.exe'
|
||||
else:
|
||||
if is_windows:
|
||||
output_file += '.dll'
|
||||
else:
|
||||
# GYP will output to lib.target, this is hardcoded in its source,
|
||||
# see the _InstallableTargetInstallPath function.
|
||||
output_prefix += 'lib.target/'
|
||||
output_file = 'lib' + output_file + '.so.' + get_version()
|
||||
|
||||
action([output_prefix + output_file], 'bin/' + output_file)
|
||||
|
||||
if 'true' == variables.get('node_use_dtrace'):
|
||||
action(['out/Release/node.d'], 'lib/dtrace/node.d')
|
||||
|
Loading…
Reference in New Issue
Block a user