Skip to content

Commit 40db774

Browse files
committed
deps,src,test: do not require extra build step.
Signed-off-by: Paolo Insogna <paolo@cowtech.it>
1 parent 12cce78 commit 40db774

9 files changed

Lines changed: 164 additions & 80 deletions

File tree

Makefile

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ v8: ## Build deps/v8.
320320
tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS)
321321

322322
.PHONY: jstest
323-
jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests ## Run addon tests and JS tests.
323+
jstest: build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests ## Run addon tests and JS tests.
324324
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \
325325
$(TEST_CI_ARGS) \
326326
--skip-tests=$(CI_SKIP_TESTS) \
@@ -346,7 +346,6 @@ test: all ## Run default tests, linters, and build docs.
346346
$(MAKE) -s build-js-native-api-tests
347347
$(MAKE) -s build-node-api-tests
348348
$(MAKE) -s build-sqlite-tests
349-
$(MAKE) -s build-ffi-tests
350349
$(MAKE) -s cctest
351350
$(MAKE) -s jstest
352351

@@ -356,7 +355,6 @@ test-only: all ## Run default tests, without linters or building the docs.
356355
$(MAKE) build-js-native-api-tests
357356
$(MAKE) build-node-api-tests
358357
$(MAKE) build-sqlite-tests
359-
$(MAKE) build-ffi-tests
360358
$(MAKE) cctest
361359
$(MAKE) jstest
362360
$(MAKE) tooltest
@@ -368,7 +366,6 @@ test-cov: all ## Run coverage tests.
368366
$(MAKE) build-js-native-api-tests
369367
$(MAKE) build-node-api-tests
370368
$(MAKE) build-sqlite-tests
371-
$(MAKE) build-ffi-tests
372369
$(MAKE) cctest
373370
CI_SKIP_TESTS=$(COV_SKIP_TESTS) $(MAKE) jstest
374371

@@ -547,24 +544,6 @@ else
547544
build-sqlite-tests:
548545
endif
549546

550-
FFI_BINDING_GYPS := $(wildcard test/ffi/*/binding.gyp)
551-
552-
FFI_BINDING_SOURCES := \
553-
$(wildcard test/ffi/*/*.c) \
554-
$(wildcard test/ffi/*/*.def)
555-
556-
# Implicitly depends on $(NODE_EXE), see the build-ffi-tests rule for rationale.
557-
test/ffi/.buildstamp: $(ADDONS_PREREQS) \
558-
$(FFI_BINDING_GYPS) $(FFI_BINDING_SOURCES)
559-
@$(call run_build_addons,"$$PWD/test/ffi",$@)
560-
561-
.PHONY: build-ffi-tests
562-
# .buildstamp needs $(NODE_EXE) but cannot depend on it
563-
# directly because it calls make recursively. The parent make cannot know
564-
# if the subprocess touched anything so it pessimistically assumes that
565-
# .buildstamp is out of date and need a rebuild.
566-
build-ffi-tests: | $(NODE_EXE) test/ffi/.buildstamp ## Build FFI tests.
567-
568547
.PHONY: clear-stalled
569548
clear-stalled: ## Clear any stalled processes.
570549
$(info Clean up any leftover processes but don't error if found.)
@@ -575,7 +554,7 @@ clear-stalled: ## Clear any stalled processes.
575554
fi
576555

577556
.PHONY: test-build
578-
test-build: | all build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests ## Build all tests.
557+
test-build: | all build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests ## Build all tests.
579558

580559
.PHONY: test-build-js-native-api
581560
test-build-js-native-api: all build-js-native-api-tests ## Build JS Native-API tests.
@@ -637,7 +616,7 @@ test-ci-js: | clear-stalled ## Build and test JavaScript with building anything
637616
.PHONY: test-ci
638617
# Related CI jobs: most CI tests, excluding node-test-commit-arm-fanned
639618
test-ci: LOGLEVEL := info ## Build and test everything (CI).
640-
test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests build-ffi-tests doc-only
619+
test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tests build-node-api-tests build-sqlite-tests doc-only
641620
out/Release/cctest --gtest_output=xml:out/junit/cctest.xml
642621
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
643622
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \

deps/libffi/generate-headers.py

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python3
22

33
import argparse
4+
import os
5+
import platform
46
import sys
57
from pathlib import Path
68

@@ -175,15 +177,62 @@ def generate_headers(output_dir, target_arch, os_name):
175177
encoding='utf-8')
176178

177179

180+
def detect_os_name():
181+
if sys.platform.startswith('win'):
182+
return 'win'
183+
if sys.platform == 'darwin':
184+
return 'mac'
185+
if sys.platform.startswith('linux'):
186+
return 'linux'
187+
if sys.platform.startswith('freebsd'):
188+
return 'freebsd'
189+
raise ValueError(f'Unsupported host platform {sys.platform!r}')
190+
191+
192+
def detect_target_arch():
193+
candidates = [
194+
os.environ.get('TARGET_ARCH'),
195+
os.environ.get('npm_config_arch'),
196+
os.environ.get('VSCMD_ARG_TGT_ARCH'),
197+
os.environ.get('Platform'),
198+
os.environ.get('PROCESSOR_ARCHITECTURE'),
199+
platform.machine(),
200+
]
201+
202+
aliases = {
203+
'amd64': 'x64',
204+
'x86_64': 'x64',
205+
'x64': 'x64',
206+
'win32': 'x64',
207+
'i386': 'x86',
208+
'i686': 'x86',
209+
'x86': 'x86',
210+
'arm64': 'arm64',
211+
'aarch64': 'arm64',
212+
'arm': 'arm',
213+
}
214+
215+
for candidate in candidates:
216+
if not candidate:
217+
continue
218+
normalized = aliases.get(candidate.lower())
219+
if normalized is not None:
220+
return normalized
221+
222+
raise ValueError('Unable to determine target architecture for libffi headers')
223+
224+
178225
def main(argv=None):
179226
parser = argparse.ArgumentParser(description='Generate libffi headers')
180227
parser.add_argument('--output-dir', required=True)
181-
parser.add_argument('--target-arch', required=True)
182-
parser.add_argument('--os', required=True)
228+
parser.add_argument('--target-arch')
229+
parser.add_argument('--os')
183230
args = parser.parse_args(argv)
184231

185232
try:
186-
generate_headers(args.output_dir, args.target_arch, args.os)
233+
generate_headers(args.output_dir,
234+
args.target_arch or detect_target_arch(),
235+
args.os or detect_os_name())
187236
except Exception as exc: # pylint: disable=broad-except
188237
print(exc, file=sys.stderr)
189238
return 1

test/ffi/ffi-test-common.js

Lines changed: 103 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const common = require('../common');
4+
const childProcess = require('node:child_process');
45
const fs = require('node:fs');
56
const path = require('node:path');
67

@@ -18,14 +19,111 @@ const libraryPath = path.join(
1819
process.platform === 'darwin' ? 'ffi_test_library.dylib' :
1920
'ffi_test_library.so',
2021
);
22+
const fixtureSourcePath = path.join(__dirname, 'fixture_library', 'ffi_test_library.c');
23+
const fixtureExportsPath = path.join(__dirname, 'fixture_library', 'ffi_test_library.def');
24+
const buildLockPath = `${libraryPath}.lock`;
25+
26+
function sleep(ms) {
27+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
28+
}
29+
30+
function getBuildCommand() {
31+
if (process.platform === 'win32') {
32+
return {
33+
command: process.env.CC || 'cl',
34+
args: [
35+
'/nologo',
36+
'/LD',
37+
`/Fe:${libraryPath}`,
38+
fixtureSourcePath,
39+
'/link',
40+
`/DEF:${fixtureExportsPath}`,
41+
],
42+
};
43+
}
44+
45+
if (process.platform === 'darwin') {
46+
return {
47+
command: process.env.CC || 'cc',
48+
args: [
49+
'-dynamiclib',
50+
'-fPIC',
51+
'-o',
52+
libraryPath,
53+
fixtureSourcePath,
54+
],
55+
};
56+
}
57+
58+
return {
59+
command: process.env.CC || 'cc',
60+
args: [
61+
'-shared',
62+
'-fPIC',
63+
'-o',
64+
libraryPath,
65+
fixtureSourcePath,
66+
],
67+
};
68+
}
69+
70+
function buildFixtureLibrary() {
71+
fs.mkdirSync(fixtureBuildDir, { recursive: true });
72+
73+
const { command, args } = getBuildCommand();
74+
const { status, error, stderr } = childProcess.spawnSync(command, args, {
75+
stdio: ['ignore', 'ignore', 'pipe'],
76+
});
77+
78+
if (status === 0 && fs.existsSync(libraryPath)) {
79+
return;
80+
}
81+
82+
const renderedCommand = [command, ...args].join(' ');
83+
const details = (error?.message || stderr?.toString() || `exit code ${status}`).trim();
84+
throw new Error(
85+
`Unable to build FFI test fixture library with \`${renderedCommand}\`: ${details}`,
86+
);
87+
}
2188

2289
function ensureFixtureLibrary() {
90+
if (fs.existsSync(libraryPath)) {
91+
return;
92+
}
93+
94+
fs.mkdirSync(path.dirname(buildLockPath), { recursive: true });
95+
96+
try {
97+
fs.mkdirSync(buildLockPath);
98+
} catch (error) {
99+
if (error.code !== 'EEXIST') {
100+
throw error;
101+
}
102+
103+
const deadline = Date.now() + 30000;
104+
while (Date.now() < deadline) {
105+
if (fs.existsSync(libraryPath)) {
106+
return;
107+
}
108+
if (!fs.existsSync(buildLockPath)) {
109+
break;
110+
}
111+
sleep(50);
112+
}
113+
114+
if (fs.existsSync(libraryPath)) {
115+
return;
116+
}
117+
}
118+
119+
try {
120+
buildFixtureLibrary();
121+
} finally {
122+
fs.rmSync(buildLockPath, { recursive: true, force: true });
123+
}
124+
23125
if (!fs.existsSync(libraryPath)) {
24-
throw new Error(
25-
`Missing FFI test fixture library: ${libraryPath}. ` +
26-
'Build it first with `make build-ffi-tests`, `vcbuild.bat build-ffi-tests`, ' +
27-
'or the equivalent test build step.',
28-
);
126+
throw new Error(`Missing FFI test fixture library: ${libraryPath}.`);
29127
}
30128
}
31129

test/ffi/ffi.status

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/ffi/fixture_library/binding.gyp

Lines changed: 0 additions & 18 deletions
This file was deleted.

test/ffi/testcfg.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,5 @@
22
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
33
import testpy
44

5-
class FFITestConfiguration(testpy.ParallelTestConfiguration):
6-
def GetBuildRequirements(self):
7-
return ['build-ffi-tests']
8-
95
def GetConfiguration(context, root):
10-
return FFITestConfiguration(context, root, 'ffi')
6+
return testpy.ParallelTestConfiguration(context, root, 'ffi')

tools/nix/sharedLibDeps.nix

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
inherit (pkgs)
1111
ada
1212
brotli
13-
libffi
1413
gtest
1514
libuv
1615
merve
@@ -21,7 +20,7 @@
2120
zlib
2221
zstd
2322
;
24-
ffi = libffi;
23+
ffi = pkgs.libffi;
2524
cares = pkgs.c-ares;
2625
hdr-histogram = pkgs.hdrhistogram_c;
2726
http-parser = pkgs.llhttp;

tools/test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,6 @@ def RunBuildRequirements(root, paths, context, modes):
961961
for path in paths:
962962
requirements += root.GetBuildRequirements(path, context)
963963

964-
requirements = [r for r in requirements if r == 'build-ffi-tests']
965964
requirements = list(dict.fromkeys(requirements))
966965
modes = list(dict.fromkeys(modes))
967966

vcbuild.bat

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,11 @@ if /i "%1"=="v8temporal" set v8temporal=1&goto arg-ok
108108
if /i "%1"=="v8windbg" set v8windbg=1&goto arg-ok
109109
if /i "%1"=="licensertf" set licensertf=1&goto arg-ok
110110
if /i "%1"=="test" set test_args=%test_args% %common_test_suites%&set lint_cpp=1&set lint_js=1&set lint_md=1&goto arg-ok
111-
if /i "%1"=="test-ci-native" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap %CI_NATIVE_SUITES% %CI_DOC%&set build_addons=1&set build_js_native_api_tests=1&set build_node_api_tests=1&set build_ffi_tests=1&set cctest_args=%cctest_args% --gtest_output=xml:cctest.junit.xml&goto arg-ok
111+
if /i "%1"=="test-ci-native" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap %CI_NATIVE_SUITES% %CI_DOC%&set build_addons=1&set build_js_native_api_tests=1&set build_node_api_tests=1&set cctest_args=%cctest_args% --gtest_output=xml:cctest.junit.xml&goto arg-ok
112112
if /i "%1"=="test-ci-js" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap %CI_JS_SUITES%&set no_cctest=1&goto arg-ok
113113
if /i "%1"=="build-addons" set build_addons=1&goto arg-ok
114114
if /i "%1"=="build-js-native-api-tests" set build_js_native_api_tests=1&goto arg-ok
115115
if /i "%1"=="build-node-api-tests" set build_node_api_tests=1&goto arg-ok
116-
if /i "%1"=="build-ffi-tests" set build_ffi_tests=1&goto arg-ok
117116
if /i "%1"=="test-addons" set test_args=%test_args% addons&set build_addons=1&goto arg-ok
118117
if /i "%1"=="test-doc" set test_args=%test_args% %CI_DOC%&set doc=1&&set lint_js=1&set lint_md=1&goto arg-ok
119118
if /i "%1"=="test-js-native-api" set test_args=%test_args% js-native-api&set build_js_native_api_tests=1&goto arg-ok
@@ -718,10 +717,10 @@ endlocal
718717
goto build-node-api-tests
719718

720719
:build-node-api-tests
721-
if not defined build_node_api_tests goto build-ffi-tests
720+
if not defined build_node_api_tests goto run-tests
722721
if not exist "%node_exe%" (
723722
echo Failed to find node.exe
724-
goto build-ffi-tests
723+
goto run-tests
725724
)
726725
echo Building node-api
727726
:: clear
@@ -733,19 +732,6 @@ setlocal
733732
python "%~dp0tools\build_addons.py" "%~dp0test\node-api" --config %config%
734733
if errorlevel 1 exit /b 1
735734
endlocal
736-
goto build-ffi-tests
737-
738-
:build-ffi-tests
739-
if not defined build_ffi_tests goto run-tests
740-
if not exist "%node_exe%" (
741-
echo Failed to find node.exe
742-
goto run-tests
743-
)
744-
echo Building ffi tests
745-
setlocal
746-
python "%~dp0tools\build_addons.py" "%~dp0test\ffi" --config %config%
747-
if errorlevel 1 exit /b 1
748-
endlocal
749735
goto run-tests
750736

751737
:run-tests
@@ -879,14 +865,13 @@ set exit_code=1
879865
goto exit
880866

881867
:help
882-
echo vcbuild.bat [debug/release] [msi] [doc] [test/test-all/test-addons/test-doc/test-js-native-api/test-node-api/test-internet/test-tick-processor/test-known-issues/test-node-inspect/test-check-deopts/test-npm/test-v8/test-v8-intl/test-v8-benchmarks/test-v8-all] [ignore-flaky] [static/dll] [noprojgen] [projgen] [clang-cl] [ccache path-to-ccache] [small-icu/full-icu/without-intl] [nobuild] [nosnapshot] [nonpm] [ltcg] [licensetf] [sign] [x64/arm64] [vs2022/vs2026] [download-all] [enable-vtune] [lint/lint-ci/lint-js/lint-md] [lint-md-build] [format-md] [package] [build-release] [upload] [no-NODE-OPTIONS] [link-module path-to-module] [debug-http2] [debug-nghttp2] [clean] [cctest] [no-cctest] [openssl-no-asm] [build-ffi-tests] [without-ffi/shared-ffi/shared-ffi-includes path/shared-ffi-libname name/shared-ffi-libpath path]
868+
echo vcbuild.bat [debug/release] [msi] [doc] [test/test-all/test-addons/test-doc/test-js-native-api/test-node-api/test-internet/test-tick-processor/test-known-issues/test-node-inspect/test-check-deopts/test-npm/test-v8/test-v8-intl/test-v8-benchmarks/test-v8-all] [ignore-flaky] [static/dll] [noprojgen] [projgen] [clang-cl] [ccache path-to-ccache] [small-icu/full-icu/without-intl] [nobuild] [nosnapshot] [nonpm] [ltcg] [licensetf] [sign] [x64/arm64] [vs2022/vs2026] [download-all] [enable-vtune] [lint/lint-ci/lint-js/lint-md] [lint-md-build] [format-md] [package] [build-release] [upload] [no-NODE-OPTIONS] [link-module path-to-module] [debug-http2] [debug-nghttp2] [clean] [cctest] [no-cctest] [openssl-no-asm] [without-ffi/shared-ffi/shared-ffi-includes path/shared-ffi-libname name/shared-ffi-libpath path]
883869
echo Examples:
884870
echo vcbuild.bat : builds release build
885871
echo vcbuild.bat debug : builds debug build
886872
echo vcbuild.bat release msi : builds release build and MSI installer package
887873
echo vcbuild.bat test : builds debug build and runs tests
888874
echo vcbuild.bat build-release : builds the release distribution as used by nodejs.org
889-
echo vcbuild.bat build-ffi-tests : builds the FFI fixture library used by test/ffi
890875
echo vcbuild.bat enable-vtune : builds Node.js with Intel VTune profiling support to profile JavaScript
891876
echo vcbuild.bat link-module my_module.js : bundles my_module as built-in module
892877
echo vcbuild.bat lint : runs the C++, documentation and JavaScript linter

0 commit comments

Comments
 (0)