Skip to content

Commit 26adcc2

Browse files
author
Gabriel Schulhof
committed
build: place N-API-related changes behind a configure/runtime flag
Currently support for N-API modules is on by default both at compile time and at runtime. Fixes #80 Closes #89
1 parent 30da58a commit 26adcc2

14 files changed

Lines changed: 140 additions & 158 deletions

File tree

Makefile

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ FLAKY_TESTS ?= run
99
TEST_CI_ARGS ?=
1010
STAGINGSERVER ?= node-www
1111
LOGLEVEL ?= silent
12+
NAPI ?= True
1213
OSTYPE := $(shell uname -s | tr '[A-Z]' '[a-z]')
1314

1415
ifdef JOBS
@@ -120,12 +121,17 @@ v8:
120121
tools/make-v8.sh
121122
$(MAKE) -C deps/v8 $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS)
122123

124+
ifeq ($(NAPI),True)
125+
BUILD_ADDONS = build-addons build-addons-abi
126+
TESTS_TO_RUN = addons addons-abi doctool inspector known_issues message pseudo-tty parallel sequential
127+
else
128+
BUILD_ADDONS = build-addons
129+
TESTS_TO_RUN = addons doctool inspector known_issues message pseudo-tty parallel sequential
130+
endif
131+
123132
test: all
124-
$(MAKE) build-addons
125-
$(MAKE) build-addons-abi
126-
$(MAKE) cctest
127-
$(PYTHON) tools/test.py --mode=release -J \
128-
addons addons-abi doctool inspector known_issues message pseudo-tty parallel sequential
133+
$(MAKE) $(BUILD_ADDONS) cctest
134+
$(PYTHON) tools/test.py --mode=release -J $(TESTS_TO_RUN)
129135
$(MAKE) lint
130136

131137
test-parallel: all
@@ -189,6 +195,8 @@ test/addons/.buildstamp: config.gypi \
189195
# TODO(bnoordhuis) Force rebuild after gyp update.
190196
build-addons: $(NODE_EXE) test/addons/.buildstamp
191197

198+
ifeq ($(NAPI),True)
199+
192200
ADDONS_ABI_BINDING_GYPS := \
193201
$(filter-out test/addons-abi/??_*/binding.gyp, \
194202
$(wildcard test/addons-abi/*/binding.gyp))
@@ -215,23 +223,26 @@ test/addons-abi/.buildstamp: $(ADDONS_ABI_BINDING_GYPS) \
215223
# TODO(bnoordhuis) Force rebuild after gyp or node-gyp update.
216224
build-addons-abi: $(NODE_EXE) test/addons-abi/.buildstamp
217225

226+
endif #eq ($(NAPI),True)
218227

219228
test-gc: all test/gc/node_modules/weak/build/Release/weakref.node
220229
$(PYTHON) tools/test.py --mode=release gc
221230

222-
test-build: | all build-addons build-addons-abi
231+
test-build: | all $(BUILD_ADDONS)
223232

224233
test-build-addons: all build-addons
225234

235+
ifeq ($(NAPI),True)
226236
test-build-addons-abi: all build-addons-abi
237+
endif #eq ($(NAPI),True)
227238

228239
test-all: test-build test/gc/node_modules/weak/build/Release/weakref.node
229240
$(PYTHON) tools/test.py --mode=debug,release
230241

231242
test-all-valgrind: test-build
232243
$(PYTHON) tools/test.py --mode=debug,release --valgrind
233244

234-
CI_NATIVE_SUITES := addons addons-abi
245+
CI_NATIVE_SUITES := addons $(if $(filter $(NAPI),True),addons-abi)
235246
CI_JS_SUITES := doctool inspector known_issues message parallel pseudo-tty sequential
236247

237248
# Build and test addons without building anything else
@@ -248,7 +259,7 @@ test-ci-js:
248259
$(TEST_CI_ARGS) $(CI_JS_SUITES)
249260

250261
test-ci: LOGLEVEL := info
251-
test-ci: | build-addons build-addons-abi
262+
test-ci: | $(BUILD_ADDONS)
252263
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
253264
--mode=release --flaky-tests=$(FLAKY_TESTS) \
254265
$(TEST_CI_ARGS) $(CI_NATIVE_SUITES) addon-abi $(CI_JS_SUITES)
@@ -292,8 +303,10 @@ test-npm-publish: $(NODE_EXE)
292303
test-addons: test-build-addons
293304
$(PYTHON) tools/test.py --mode=release addons
294305

306+
ifeq ($(NAPI),True)
295307
test-addons-abi: test-build-addons-abi
296308
$(PYTHON) tools/test.py --mode=release addons-abi
309+
endif #eq ($(NAPI),True)
297310

298311
test-timers:
299312
$(MAKE) --directory=tools faketime
@@ -753,7 +766,9 @@ CPPLINT_EXCLUDE += src/node_root_certs.h
753766
CPPLINT_EXCLUDE += src/queue.h
754767
CPPLINT_EXCLUDE += src/tree.h
755768
CPPLINT_EXCLUDE += $(wildcard test/addons/??_*/*.cc test/addons/??_*/*.h)
769+
ifeq ($(NAPI),True)
756770
CPPLINT_EXCLUDE += $(wildcard test/addons-abi/??_*/*.cc test/addons-abi/??_*/*.h)
771+
endif #eq ($(NAPI),True)
757772

758773
CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard \
759774
src/*.c \
@@ -763,8 +778,8 @@ CPPLINT_FILES = $(filter-out $(CPPLINT_EXCLUDE), $(wildcard \
763778
test/addons/*/*.h \
764779
test/cctest/*.cc \
765780
test/cctest/*.h \
766-
test/addons-abi/*/*.cc \
767-
test/addons-abi/*/*.h \
781+
$(if $(filter $(NAPI),True),test/addons-abi/*/*.cc) \
782+
$(if $(filter $(NAPI),True),test/addons-abi/*/*.h) \
768783
tools/icu/*.cc \
769784
tools/icu/*.h \
770785
))
@@ -794,13 +809,17 @@ lint:
794809
lint-ci: lint
795810
endif
796811

812+
ifeq ($(NAPI),True)
813+
PHONY_ABI = test-addons-abi build-addons-abi
814+
else
815+
PHONY_ABI =
816+
endif #eq ($(NAPI),True)
817+
797818
.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean \
798819
check uninstall install install-includes install-bin all staticlib \
799-
dynamiclib test test-all \
800-
test-addons build-addons test-addons-abi build-addons-abi \
801-
test-addons-abi build-addons-abi website-upload pkg \
820+
dynamiclib test test-all test-addons build-addons website-upload pkg \
802821
blog blogclean tar binary release-only bench-http-simple bench-idle \
803822
bench-all bench bench-misc bench-array bench-buffer bench-net \
804823
bench-http bench-fs bench-tls cctest run-ci test-v8 test-v8-intl \
805824
test-v8-benchmarks test-v8-all v8 lint-ci bench-ci jslint-ci doc-only \
806-
$(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci
825+
$(TARBALL)-headers test-ci test-ci-native test-ci-js build-ci $(PHONY_ABI)

configure

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,18 @@ parser.add_option('--without-bundled-v8',
474474
help='do not use V8 includes from the bundled deps folder. ' +
475475
'(This mode is not officially supported for regular applications)')
476476

477+
parser.add_option('--with-napi',
478+
action='store_true',
479+
dest='enable_napi',
480+
default=True,
481+
help='Build with ABI-stable API for addons. (Default)')
482+
483+
parser.add_option('--without-napi',
484+
action='store_false',
485+
dest='enable_napi',
486+
default=True,
487+
help='Build without ABI-stable API for addons.')
488+
477489
(options, args) = parser.parse_args()
478490

479491
# Expand ~ in the install prefix now, it gets written to multiple files.
@@ -767,6 +779,7 @@ def configure_mips(o):
767779
def configure_node(o):
768780
if options.dest_os == 'android':
769781
o['variables']['OS'] = 'android'
782+
o['variables']['enable_napi'] = b(options.enable_napi)
770783
o['variables']['node_prefix'] = options.prefix
771784
o['variables']['node_install_npm'] = b(not options.without_npm)
772785
o['default_configuration'] = 'Debug' if options.debug else 'Release'
@@ -1336,6 +1349,7 @@ config = {
13361349
'BUILDTYPE': 'Debug' if options.debug else 'Release',
13371350
'USE_XCODE': str(int(options.use_xcode or 0)),
13381351
'PYTHON': sys.executable,
1352+
'NAPI': str(options.enable_napi)
13391353
}
13401354

13411355
if options.prefix:

node.gyp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@
156156
'src/handle_wrap.cc',
157157
'src/js_stream.cc',
158158
'src/node.cc',
159-
'src/node_asyncapi.cc',
160159
'src/node_buffer.cc',
161160
'src/node_config.cc',
162161
'src/node_constants.cc',
@@ -165,7 +164,6 @@
165164
'src/node_file.cc',
166165
'src/node_http_parser.cc',
167166
'src/node_javascript.cc',
168-
'src/node_jsvmapi.cc',
169167
'src/node_main.cc',
170168
'src/node_os.cc',
171169
'src/node_revert.cc',
@@ -207,10 +205,6 @@
207205
'src/handle_wrap.h',
208206
'src/js_stream.h',
209207
'src/node.h',
210-
'src/node_api_helpers.h',
211-
'src/node_asyncapi.h',
212-
'src/node_asyncapi_internal.h',
213-
'src/node_asyncapi_types.h',
214208
'src/node_buffer.h',
215209
'src/node_constants.h',
216210
'src/node_debug_options.h',
@@ -219,9 +213,6 @@
219213
'src/node_internals.h',
220214
'src/node_javascript.h',
221215
'src/node_mutex.h',
222-
'src/node_jsvmapi.h',
223-
'src/node_jsvmapi_internal.h',
224-
'src/node_jsvmapi_types.h',
225216
'src/node_root_certs.h',
226217
'src/node_version.h',
227218
'src/node_watchdog.h',
@@ -265,6 +256,22 @@
265256

266257

267258
'conditions': [
259+
[ 'enable_napi=="true"', {
260+
'sources': [
261+
'src/node_asyncapi.cc',
262+
'src/node_jsvmapi.cc',
263+
'src/node_api_helpers.h',
264+
'src/node_asyncapi.h',
265+
'src/node_asyncapi_internal.h',
266+
'src/node_asyncapi_types.h',
267+
'src/node_jsvmapi.h',
268+
'src/node_jsvmapi_internal.h',
269+
'src/node_jsvmapi_types.h'
270+
],
271+
'defines': [
272+
'ENABLE_NAPI'
273+
]
274+
}],
268275
[ 'node_shared=="false"', {
269276
'msvs_settings': {
270277
'VCManifestTool': {

src/node.cc

Lines changed: 27 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
#include "node_lttng.h"
3030
#endif
3131

32+
#if defined ENABLE_NAPI
3233
#include "node_jsvmapi_internal.h"
34+
#endif
3335

3436
#include "ares.h"
3537
#include "async-wrap.h"
@@ -98,7 +100,6 @@ typedef int mode_t;
98100
extern char **environ;
99101
#endif
100102

101-
102103
namespace node {
103104

104105
using v8::Array;
@@ -162,6 +163,9 @@ static const char* trace_enabled_categories = nullptr;
162163
static const char* icu_data_dir = nullptr;
163164
#endif
164165

166+
// By default we accept N-API addons
167+
bool no_napi_modules = false;
168+
165169
// used by C++ modules as well
166170
bool no_deprecation = false;
167171

@@ -2418,73 +2422,19 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
24182422
return;
24192423
}
24202424

2421-
// try loading with node 0.10 manner in case of node 0.10
2422-
struct node_module_old* mod;
2423-
char symbol[1024], *base, *pos;
2424-
int r;
2425-
if (mp == NULL) {
2426-
node::Utf8Value path(env->isolate(), args[1]);
2427-
base = *path;
2428-
2429-
/* Find the shared library filename within the full path. */
2430-
#ifdef __POSIX__
2431-
pos = strrchr(base, '/');
2432-
if (pos != NULL) {
2433-
base = pos + 1;
2434-
}
2435-
#else // Windows
2436-
for (;;) {
2437-
pos = strpbrk(base, "\\/:");
2438-
if (pos == NULL) {
2439-
break;
2440-
}
2441-
base = pos + 1;
2442-
}
2443-
#endif
2444-
2445-
/* Strip the .node extension. */
2446-
pos = strrchr(base, '.');
2447-
if (pos != NULL) {
2448-
*pos = '\0';
2449-
}
2450-
/* Add the `_module` suffix to the extension name. */
2451-
r = snprintf(symbol, sizeof symbol, "%s_module", base);
2452-
if (r <= 0 || static_cast<size_t>(r) >= sizeof symbol) {
2453-
env->ThrowError("Out of memory.");
2454-
}
2455-
2456-
/* Replace dashes with underscores. When loading foo-bar.node,
2457-
* look for foo_bar_module, not foo-bar_module.
2458-
*/
2459-
for (pos = symbol; *pos != '\0'; ++pos) {
2460-
if (*pos == '-') *pos = '_';
2461-
}
2462-
2463-
if (uv_dlsym(&lib, symbol, reinterpret_cast<void**>(&mod))) {
2464-
char errmsg[1024];
2465-
snprintf(errmsg, sizeof(errmsg), "Symbol %s not found.", symbol);
2466-
env->ThrowError(errmsg);
2467-
return;
2468-
}
2469-
mp = new struct node_module;
2470-
mp->nm_version = mod->version;
2471-
mp->nm_flags = 0;
2472-
mp->nm_filename = mod->filename;
2473-
mp->nm_register_func =
2474-
reinterpret_cast<node::addon_register_func>(mod->register_func);
2475-
mp->nm_context_register_func = NULL;
2476-
mp->nm_modname = mod->modname;
2477-
}
2478-
24792425
if (mp == nullptr) {
24802426
uv_dlclose(&lib);
24812427
env->ThrowError("Module did not self-register.");
24822428
return;
24832429
}
24842430

2485-
bool isNapiModule = mp->nm_version == -1;
2431+
#ifdef ENABLE_NAPI
2432+
bool isNapiModule = (!no_napi_modules && mp->nm_version == -1);
24862433

24872434
if (mp->nm_version != NODE_MODULE_VERSION && !isNapiModule) {
2435+
#else /* !defined ENABLE_NAPI */
2436+
if (mp->nm_version != NODE_MODULE_VERSION) {
2437+
#endif /* def ENABLE_NAPI */
24882438
char errmsg[1024];
24892439
snprintf(errmsg,
24902440
sizeof(errmsg),
@@ -2515,6 +2465,7 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
25152465
Local<String> exports_string = env->exports_string();
25162466
Local<Object> exports = module->Get(exports_string)->ToObject(env->isolate());
25172467

2468+
#ifdef ENABLE_NAPI
25182469
if (isNapiModule) {
25192470
if (mp->nm_register_func != nullptr) {
25202471
reinterpret_cast<node::addon_abi_register_func>(mp->nm_register_func)(
@@ -2525,18 +2476,18 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) {
25252476
} else {
25262477
uv_dlclose(&lib);
25272478
env->ThrowError("Module has no declared entry point.");
2528-
return;
25292479
}
2480+
return;
2481+
}
2482+
#endif /* def ENABLE_NAPI */
2483+
if (mp->nm_context_register_func != nullptr) {
2484+
mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2485+
} else if (mp->nm_register_func != nullptr) {
2486+
mp->nm_register_func(exports, module, mp->nm_priv);
25302487
} else {
2531-
if (mp->nm_context_register_func != nullptr) {
2532-
mp->nm_context_register_func(exports, module, env->context(), mp->nm_priv);
2533-
} else if (mp->nm_register_func != nullptr) {
2534-
mp->nm_register_func(exports, module, mp->nm_priv);
2535-
} else {
2536-
uv_dlclose(&lib);
2537-
env->ThrowError("Module has no declared entry point.");
2538-
return;
2539-
}
2488+
uv_dlclose(&lib);
2489+
env->ThrowError("Module has no declared entry point.");
2490+
return;
25402491
}
25412492

25422493
// Tell coverity that 'handle' should not be freed when we return.
@@ -2763,6 +2714,7 @@ static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
27632714
env->context(),
27642715
mod->nm_priv);
27652716
} else if (mod->nm_register_func != nullptr) {
2717+
#ifdef ENABLE_NAPI
27662718
if (mod->nm_version != -1) {
27672719
mod->nm_register_func(exports, module, mod->nm_priv);
27682720
} else {
@@ -2772,6 +2724,9 @@ static void LinkedBinding(const FunctionCallbackInfo<Value>& args) {
27722724
v8impl::JsValueFromV8LocalValue(module),
27732725
mod->nm_priv);
27742726
}
2727+
#else /* !defined ENABLE_NAPI */
2728+
mod->nm_register_func(exports, module, mod->nm_priv);
2729+
#endif /* def ENABLE_NAPI */
27752730
} else {
27762731
return env->ThrowError("Linked module has no declared entry point.");
27772732
}
@@ -3755,6 +3710,8 @@ static void ParseArgs(int* argc,
37553710
force_repl = true;
37563711
} else if (strcmp(arg, "--no-deprecation") == 0) {
37573712
no_deprecation = true;
3713+
} else if (strcmp(arg, "--no-napi-modules") == 0) {
3714+
no_napi_modules = true;
37583715
} else if (strcmp(arg, "--no-warnings") == 0) {
37593716
no_process_warnings = true;
37603717
} else if (strcmp(arg, "--trace-warnings") == 0) {

0 commit comments

Comments
 (0)