Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions build-capnp.bat
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ IF NOT EXIST %BUILD_DIR% MKDIR %BUILD_DIR%

PUSHD %BUILD_DIR%

SET CAPNP_FILENAME=capnproto-c++-1.1.0.tar.gz

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

:: Build the library, making sure that the MSVC runtime library is statically linked. Note that
:: cmake won't respect that setting unless we also enable policy CMP0091.
Expand Down
6 changes: 3 additions & 3 deletions build-capnp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ here=$(cd "$(dirname "$BASH_SOURCE")"; \
# We store all of our build artefacts in a subdirectory. If that directory already exists, remove
# it so that we can cleanly restart from scratch. Preserve the capnproto source distribution if
# it's present, so that we don't need to redownload it.
capnp_filename="capnproto-c++-0.10.3.tar.gz"
capnp_filename="capnproto-c++-1.1.0.tar.gz"
build_dir="${here}/build-capnp"

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

tar --strip-components=1 -zxf "${capnp_filename}"
Expand All @@ -63,7 +63,7 @@ if [[ $1 == "linux" ]]; then
CC="clang" \
CXX="clang++" \
CFLAGS="-fPIC" \
CXXFLAGS="-std=c++17 -fPIC" \
CXXFLAGS="-std=c++20 -fPIC" \
./configure --disable-shared
make -j
make install-data DESTDIR=capnp-root
Expand Down
21 changes: 16 additions & 5 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ function buildCapnp() {

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

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

buildEnvironment.CFLAGS =
"-mmacosx-version-min=10.7 -std=c++17 " +
"-mmacosx-version-min=10.7 -std=c++20 " +
"-stdlib=libc++ -I" +
capnpIncPath;
buildEnvironment.CXXFLAGS = buildEnvironment.CFLAGS;
Expand Down Expand Up @@ -259,10 +262,18 @@ function build(buildEnvironment) {
`Executing ${command} with the following arguments:\n${commandArgs}`
);

const nodeGypResult = childProcess.spawnSync(command, commandArgs, {
const spawnSyncOptions = {
stdio: "inherit",
env: buildEnvironment,
});
};

if (process.platform === "win32") {
// shell: true is required on Windows since node v20.12.2:
// https://nodejs.org/en/blog/vulnerability/april-2024-security-releases-2
spawnSyncOptions.shell = true;
}

const nodeGypResult = childProcess.spawnSync(command, commandArgs, spawnSyncOptions);

if (nodeGypResult.error) {
throw nodeGypResult.error;
Expand Down Expand Up @@ -335,7 +346,7 @@ function moveBuildResult(builtPath, buildEnvironment) {
* @param target - The target binary to be modified
*/
function patchLibs(patchTool, patchPath, target) {
var libVersion = "0.10.3";
var libVersion = "1.1.0";
var libExt = "so";
var libs = ["libkj", "libkj-async", "libcapnp", "libcapnpc", "libcapnp-rpc"];

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@
"main": "src/node-capnp/capnp.js",
"types": "src/node-capnp/capnp.d.ts",
"scripts": {
"install": "node ./build.js --dist-url=https://electronjs.org/headers --target=20.3.3",
"install": "node ./build.js --dist-url=https://electronjs.org/headers --target=35.1.2",
"test": "electron src/node-capnp/capnp-test.js"
},
"dependencies": {
"nan": "^2.17.0",
"yargs": "^17.6.2"
},
"devDependencies": {
"electron": "^20.3.3",
"node-gyp": "^9.1.0"
"electron": "^35.1.2",
"node-gyp": "^11.2.0"
},
"repository": {
"type": "git",
Expand Down
Binary file modified prebuilt/win32-x64/capnp.node
Binary file not shown.
25 changes: 12 additions & 13 deletions src/node-capnp/capnp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1272,16 +1272,15 @@ kj::Maybe<kj::ArrayPtr<const byte>> unwrapBuffer(v8::Local<v8::Value> value) {
kj::ArrayPtr<const byte>& name = KJ_ASSERT_NONNULL(name##_maybe)

template <typename T>
void deleteArray(char*, void* hint) {
delete reinterpret_cast<kj::Array<T>*>(hint);
}

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

// =======================================================================================
Expand Down Expand Up @@ -2037,7 +2036,7 @@ v8::Local<v8::Value> valueToJs(CapnpContext& context, capnp::DynamicValue::Reade
} else {
capnp::MallocMessageBuilder message;
message.setRoot(value.as<capnp::AnyPointer>());
return scope.Escape(wrapBuffer(capnp::messageToFlatArray(message)));
return scope.Escape(copyToNodeBuffer(capnp::messageToFlatArray(message)));
}
}
}
Expand Down Expand Up @@ -2255,17 +2254,17 @@ void toBytes(const v8::FunctionCallbackInfo<v8::Value>& args) {
kj::VectorOutputStream output;
capnp::_::PackedOutputStream packer(output);
packer.write(words.asBytes().begin(), words.asBytes().size());
return wrapBuffer(kj::heapArray(output.getArray()));
return copyToNodeBuffer(kj::heapArray(output.getArray()));
} else {
return wrapBuffer(kj::mv(words));
return copyToNodeBuffer(kj::mv(words));
}
} else if (packed) {
kj::VectorOutputStream output;
capnp::writePackedMessage(output, builder.message);
auto packedMessage = heapArray(output.getArray());
return wrapBuffer(kj::mv(packedMessage));
return copyToNodeBuffer(kj::mv(packedMessage));
} else {
return wrapBuffer(capnp::messageToFlatArray(builder.message));
return copyToNodeBuffer(capnp::messageToFlatArray(builder.message));
}
});
}
Expand Down