Skip to content

Commit b5428c8

Browse files
Merge pull request #13 from fourieraudio/TF-905
TF-905: Bump versions of Electron, Node and capnp Bumps versions of Electron (from 20.3.3 to 35.1.2) and capnp (from 0.10.3 to 1.1.0) to allow using this library in newer Electron versions. Tested by replacing previous version in a project that makes heavy use of this on Windows, Apple arm64 and x64. The specific project that this change was tested on has shown a noticeable overall performance improvement on all platforms when moving from Electron 20.3.3 to 35.1.2 which may mean that any performance degradation (if any) due to extra allocation and memcpy introduced in this change should be negligible.
2 parents e2cfa53 + 5bd51b6 commit b5428c8

File tree

6 files changed

+40
-28
lines changed

6 files changed

+40
-28
lines changed

build-capnp.bat

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ IF NOT EXIST %BUILD_DIR% MKDIR %BUILD_DIR%
2727

2828
PUSHD %BUILD_DIR%
2929

30+
SET CAPNP_FILENAME=capnproto-c++-1.1.0.tar.gz
31+
3032
:: Download and unzip the capnproto source. It's pretty small (1.6 MiB), so this should be fast.
3133
:: curl.exe and tar.exe come pre-installed from Windows 10 onwards.
32-
curl.exe -O https://capnproto.org/capnproto-c++-win32-0.10.3.zip || EXIT /B %ERRORLEVEL%
33-
tar.exe --strip-components=1 -xf capnproto-c++-win32-0.10.3.zip || EXIT /B %ERRORLEVEL%
34-
DEL capnproto-c++-win32-0.10.3.zip || EXIT /B %ERRORLEVEL%
34+
curl.exe -O https://capnproto.org/%CAPNP_FILENAME% || EXIT /B %ERRORLEVEL%
35+
tar.exe --strip-components=1 -xf %CAPNP_FILENAME% || EXIT /B %ERRORLEVEL%
36+
DEL %CAPNP_FILENAME% || EXIT /B %ERRORLEVEL%
3537

3638
:: Build the library, making sure that the MSVC runtime library is statically linked. Note that
3739
:: cmake won't respect that setting unless we also enable policy CMP0091.

build-capnp.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ here=$(cd "$(dirname "$BASH_SOURCE")"; \
3232
# We store all of our build artefacts in a subdirectory. If that directory already exists, remove
3333
# it so that we can cleanly restart from scratch. Preserve the capnproto source distribution if
3434
# it's present, so that we don't need to redownload it.
35-
capnp_filename="capnproto-c++-0.10.3.tar.gz"
35+
capnp_filename="capnproto-c++-1.1.0.tar.gz"
3636
build_dir="${here}/build-capnp"
3737

3838
if [[ -f "${build_dir}/${capnp_filename}" ]]; then
@@ -51,7 +51,7 @@ pushd ${build_dir}
5151
# Download the capnproto source, if we don't already have it, and then unpack it. It's pretty small
5252
# (1.6 MiB), so the download should be fast.
5353
if [[ ! -f "${capnp_filename}" ]]; then
54-
curl -O https://capnproto.org/capnproto-c++-0.10.3.tar.gz
54+
curl -O "https://capnproto.org/${capnp_filename}"
5555
fi
5656

5757
tar --strip-components=1 -zxf "${capnp_filename}"
@@ -63,7 +63,7 @@ if [[ $1 == "linux" ]]; then
6363
CC="clang" \
6464
CXX="clang++" \
6565
CFLAGS="-fPIC" \
66-
CXXFLAGS="-std=c++17 -fPIC" \
66+
CXXFLAGS="-std=c++20 -fPIC" \
6767
./configure --disable-shared
6868
make -j
6969
make install-data DESTDIR=capnp-root

build.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ function buildCapnp() {
126126

127127
buildCapnpResult = childProcess.spawnSync("build-capnp.bat", [], {
128128
stdio: "inherit",
129+
// shell: true is required on Windows since node v20.12.2:
130+
// https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2
131+
shell: true
129132
});
130133
} else {
131134
throw new Error(
@@ -172,7 +175,7 @@ if (process.platform === "linux" && args.targetPlatform === "linux") {
172175
buildEnvironment.CC = "clang";
173176
buildEnvironment.CXX = "clang++";
174177
buildEnvironment.CFLAGS = "-I" + capnpIncPath;
175-
buildEnvironment.CXXFLAGS = buildEnvironment.CFLAGS;
178+
buildEnvironment.CXXFLAGS = buildEnvironment.CFLAGS + " -std=c++20";
176179
buildEnvironment.LDFLAGS = "-L" + capnpLibPath;
177180
}
178181

@@ -190,7 +193,7 @@ if (process.platform === "linux" && args.targetPlatform === "darwin") {
190193
}
191194

192195
buildEnvironment.CFLAGS =
193-
"-mmacosx-version-min=10.7 -std=c++17 " +
196+
"-mmacosx-version-min=10.7 -std=c++20 " +
194197
"-stdlib=libc++ -I" +
195198
capnpIncPath;
196199
buildEnvironment.CXXFLAGS = buildEnvironment.CFLAGS;
@@ -259,10 +262,18 @@ function build(buildEnvironment) {
259262
`Executing ${command} with the following arguments:\n${commandArgs}`
260263
);
261264

262-
const nodeGypResult = childProcess.spawnSync(command, commandArgs, {
265+
const spawnSyncOptions = {
263266
stdio: "inherit",
264267
env: buildEnvironment,
265-
});
268+
};
269+
270+
if (process.platform === "win32") {
271+
// shell: true is required on Windows since node v20.12.2:
272+
// https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2
273+
spawnSyncOptions.shell = true;
274+
}
275+
276+
const nodeGypResult = childProcess.spawnSync(command, commandArgs, spawnSyncOptions);
266277

267278
if (nodeGypResult.error) {
268279
throw nodeGypResult.error;
@@ -335,7 +346,7 @@ function moveBuildResult(builtPath, buildEnvironment) {
335346
* @param target - The target binary to be modified
336347
*/
337348
function patchLibs(patchTool, patchPath, target) {
338-
var libVersion = "0.10.3";
349+
var libVersion = "1.1.0";
339350
var libExt = "so";
340351
var libs = ["libkj", "libkj-async", "libcapnp", "libcapnpc", "libcapnp-rpc"];
341352

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "capnp",
3-
"version": "0.5.7",
3+
"version": "0.6.0",
44
"description": "A wrapper for the C++ Cap'n Proto library",
55
"keywords": [
66
"capnproto",
@@ -21,16 +21,16 @@
2121
"main": "src/node-capnp/capnp.js",
2222
"types": "src/node-capnp/capnp.d.ts",
2323
"scripts": {
24-
"install": "node ./build.js --dist-url=https://electronjs.org/headers --target=20.3.3",
24+
"install": "node ./build.js --dist-url=https://electronjs.org/headers --target=35.1.2",
2525
"test": "electron src/node-capnp/capnp-test.js"
2626
},
2727
"dependencies": {
2828
"nan": "^2.17.0",
2929
"yargs": "^17.6.2"
3030
},
3131
"devDependencies": {
32-
"electron": "^20.3.3",
33-
"node-gyp": "^9.1.0"
32+
"electron": "^35.1.2",
33+
"node-gyp": "^11.2.0"
3434
},
3535
"repository": {
3636
"type": "git",

prebuilt/win32-x64/capnp.node

-2.46 MB
Binary file not shown.

src/node-capnp/capnp.cc

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,16 +1272,15 @@ kj::Maybe<kj::ArrayPtr<const byte>> unwrapBuffer(v8::Local<v8::Value> value) {
12721272
kj::ArrayPtr<const byte>& name = KJ_ASSERT_NONNULL(name##_maybe)
12731273

12741274
template <typename T>
1275-
void deleteArray(char*, void* hint) {
1276-
delete reinterpret_cast<kj::Array<T>*>(hint);
1277-
}
1278-
1279-
template <typename T>
1280-
v8::Local<v8::Value> wrapBuffer(kj::Array<T>&& array) {
1275+
v8::Local<v8::Value> copyToNodeBuffer(kj::Array<T>&& array) {
12811276
char* data = reinterpret_cast<char*>(array.begin());
12821277
size_t size = array.size() * sizeof(T);
1283-
return check(node::Buffer::New(v8::Isolate::GetCurrent(), data, size, &deleteArray<T>,
1284-
new kj::Array<T>(kj::mv(array))));
1278+
// We need to copy the data into a V8 ArrayBuffer as since version 21 Electron
1279+
// does not allow externally allocated pointers to be passed to JavaScript.
1280+
// See https://www.electronjs.org/blog/v8-memory-cage
1281+
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(v8::Isolate::GetCurrent(), size);
1282+
memcpy(ab->Data(), data, size);
1283+
return check(node::Buffer::New(v8::Isolate::GetCurrent(), ab, 0, size));
12851284
}
12861285

12871286
// =======================================================================================
@@ -2037,7 +2036,7 @@ v8::Local<v8::Value> valueToJs(CapnpContext& context, capnp::DynamicValue::Reade
20372036
} else {
20382037
capnp::MallocMessageBuilder message;
20392038
message.setRoot(value.as<capnp::AnyPointer>());
2040-
return scope.Escape(wrapBuffer(capnp::messageToFlatArray(message)));
2039+
return scope.Escape(copyToNodeBuffer(capnp::messageToFlatArray(message)));
20412040
}
20422041
}
20432042
}
@@ -2255,17 +2254,17 @@ void toBytes(const v8::FunctionCallbackInfo<v8::Value>& args) {
22552254
kj::VectorOutputStream output;
22562255
capnp::_::PackedOutputStream packer(output);
22572256
packer.write(words.asBytes().begin(), words.asBytes().size());
2258-
return wrapBuffer(kj::heapArray(output.getArray()));
2257+
return copyToNodeBuffer(kj::heapArray(output.getArray()));
22592258
} else {
2260-
return wrapBuffer(kj::mv(words));
2259+
return copyToNodeBuffer(kj::mv(words));
22612260
}
22622261
} else if (packed) {
22632262
kj::VectorOutputStream output;
22642263
capnp::writePackedMessage(output, builder.message);
22652264
auto packedMessage = heapArray(output.getArray());
2266-
return wrapBuffer(kj::mv(packedMessage));
2265+
return copyToNodeBuffer(kj::mv(packedMessage));
22672266
} else {
2268-
return wrapBuffer(capnp::messageToFlatArray(builder.message));
2267+
return copyToNodeBuffer(capnp::messageToFlatArray(builder.message));
22692268
}
22702269
});
22712270
}

0 commit comments

Comments
 (0)