Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Electron multi-arch/cross-compilation support #12

Closed
Show file tree
Hide file tree
Changes from all 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
11 changes: 8 additions & 3 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,23 @@ Dynamic symbol files are also available in the `out/` directory for each framewo

To build the Node.js module suitable for including in an Electron app, run:

make electron PLATFORM=<platform>
make electron PLATFORM=<platform> NODEJS_ARCH=<arch>

where platform can be:
- `mac` or `ios` (either of these can be used the MacOS)
- `unix` or `android` (either of these can be used for Linux)
- `windows`

This will produce a release build for the host architecture (we don't support cross-compiling Electron builds at this time).
and where the (optional) `NODEJS_ARCH` can be:
- `x64`
- `ia32`
- `arm64`

If no `NODEJS_ARCH` is provided, the build script will default to `x64`. Note that architectures other than `x64` are currently only supported through cross-compilation. That is, compiling for `arm64` on a `x64` machine works, but compiling for `arm64` on an `arm64` machine is not currently supported.

When the build is complete, the library will be available here:

src/node/build/<platform>/libringrtc.node
src/node/build/<platform>/libringrtc-<arch>.node

### CLI test tool

Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ ANDROID_TARGETS := $(foreach t, $(BUILD_TYPES), \

IOS_TARGETS := ios/release

# This can be overriden on the command line, e.g. "make electron NODEJS_ARCH=ia32"
# Note: make sure to only use NodeJS architectures here, like x64, ia32, arm64, etc.
NODEJS_ARCH := x64

help:
$(Q) echo "The following build targets are supported:"
$(Q) echo " ios -- download WebRTC and build for the iOS platform"
Expand Down Expand Up @@ -74,10 +78,10 @@ electron:
fi
$(Q) if [ "$(TYPE)" = "debug" ] ; then \
echo "Electron: Debug build" ; \
./bin/build-electron -d ; \
TARGET_ARCH=$(NODEJS_ARCH) ./bin/build-electron -d ; \
else \
echo "Electron: Release build" ; \
./bin/build-electron -r ; \
TARGET_ARCH=$(NODEJS_ARCH) ./bin/build-electron -r ; \
fi
$(Q) (cd src/node && yarn install && yarn build)

Expand Down
86 changes: 54 additions & 32 deletions bin/build-electron
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ set -e
BIN_DIR="$(realpath -e $(dirname $0))"
. "${BIN_DIR}/env.sh"

# Note: make sure to only use NodeJS architectures here, like x64, ia32, arm64, etc.
TARGET_ARCH=${TARGET_ARCH:-x64}

usage()
{
echo 'usage: build-electron [-d|-r|-c]
Expand Down Expand Up @@ -56,31 +59,50 @@ while [ "$1" != "" ]; do
shift
done

get_default_platform()
{
hash rustup 2>/dev/null || { echo >&2 "Make sure you have rustup installed and properly configured! Aborting."; exit 1; }

case "$(rustup show active-toolchain)" in
*"x86_64-apple-darwin"* )
echo "darwin"
;;
*"x86_64-pc-windows"* )
echo "win32"
;;
*"x86_64-unknown-linux"* )
echo "linux"
;;
* )
echo "unknown"
esac
}

DEFAULT_PLATFORM=$(get_default_platform)
if [ "${DEFAULT_PLATFORM}" = "unknown" ]
then
echo "Unknown platform detected!\nPlease make sure you have installed a valid Rust toolchain via rustup! Aborting."
exit 1
fi
case "$TARGET_ARCH" in
"x64")
GN_ARCH=x64
CARGO_ARCH=x86_64
;;
"ia32")
GN_ARCH=x86
CARGO_ARCH=i686
;;
"arm64")
GN_ARCH=arm64
CARGO_ARCH=aarch64
;;
*)
echo "Unsupported architecture"
exit 1
;;
esac

hash rustup 2>/dev/null || { echo >&2 "Make sure you have rustup installed and properly configured! Aborting."; exit 1; }

RUSTFLAGS_WIN=

case "$(rustup show active-toolchain)" in
*"x86_64-apple-darwin"* )
DEFAULT_PLATFORM="darwin"
CARGO_TARGET="${CARGO_ARCH}-apple-darwin"
;;
*"x86_64-pc-windows"* )
DEFAULT_PLATFORM="win32"
CARGO_TARGET="${CARGO_ARCH}-pc-windows-msvc"
# Static linking to prevent build errors on Windows ia32
RUSTFLAGS_WIN="-C target-feature=+crt-static"
jim-signal marked this conversation as resolved.
Show resolved Hide resolved
;;
*"x86_64-unknown-linux"* )
DEFAULT_PLATFORM="linux"
CARGO_TARGET="${CARGO_ARCH}-unknown-linux-gnu"
;;
* )
echo "Unknown platform detected!\nPlease make sure you have installed a valid Rust toolchain via rustup! Aborting."
exit 1
esac

echo "Building for platform ${DEFAULT_PLATFORM}, TARGET_ARCH=${TARGET_ARCH}, GN_ARCH=${GN_ARCH}, CARGO_TARGET=${CARGO_TARGET}"

export MACOSX_DEPLOYMENT_TARGET="10.10"

Expand All @@ -90,10 +112,10 @@ export MACOSX_DEPLOYMENT_TARGET="10.10"

if [ "${BUILD_TYPE}" = "debug" ]
then
gn gen -C "${OUTPUT_DIR}"/debug "--args=use_custom_libcxx=false rtc_build_examples=false rtc_build_tools=false rtc_include_tests=false rtc_enable_protobuf=false rtc_use_x11=false rtc_enable_sctp=false"
gn gen -C "${OUTPUT_DIR}"/debug "--args=use_custom_libcxx=false target_cpu=\"${GN_ARCH}\" rtc_build_examples=false rtc_build_tools=false rtc_include_tests=false rtc_enable_protobuf=false rtc_use_x11=false rtc_enable_sctp=false"
ninja -C "${OUTPUT_DIR}"/debug
else
gn gen -C "${OUTPUT_DIR}"/release "--args=use_custom_libcxx=false rtc_build_examples=false rtc_build_tools=false rtc_include_tests=false rtc_enable_protobuf=false rtc_use_x11=false rtc_enable_sctp=false is_debug=false"
gn gen -C "${OUTPUT_DIR}"/release "--args=use_custom_libcxx=false target_cpu=\"${GN_ARCH}\" rtc_build_examples=false rtc_build_tools=false rtc_include_tests=false rtc_enable_protobuf=false rtc_use_x11=false rtc_enable_sctp=false is_debug=false"
ninja -C "${OUTPUT_DIR}"/release
fi
)
Expand All @@ -104,22 +126,22 @@ export MACOSX_DEPLOYMENT_TARGET="10.10"

if [ "${BUILD_TYPE}" = "debug" ]
then
npm_config_arch=x64 npm_config_target_arch=x64 npm_config_disturl=https://atom.io/download/electron npm_config_runtime=electron npm_config_target=11.2.0 npm_config_build_from_source=true npm_config_devdir=~/.electron-gyp OUTPUT_DIR="${OUTPUT_DIR}" cargo build --features electron
npm_config_arch=${TARGET_ARCH} npm_config_target_arch=${TARGET_ARCH} npm_config_disturl=https://atom.io/download/electron npm_config_runtime=electron npm_config_target=11.2.0 npm_config_build_from_source=true npm_config_devdir=~/.electron-gyp RUSTFLAGS="${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features electron
else
npm_config_arch=x64 npm_config_target_arch=x64 npm_config_disturl=https://atom.io/download/electron npm_config_runtime=electron npm_config_target=11.2.0 npm_config_build_from_source=true npm_config_devdir=~/.electron-gyp RUSTFLAGS="-C link-arg=-s" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --features electron --release
npm_config_arch=${TARGET_ARCH} npm_config_target_arch=${TARGET_ARCH} npm_config_disturl=https://atom.io/download/electron npm_config_runtime=electron npm_config_target=11.2.0 npm_config_build_from_source=true npm_config_devdir=~/.electron-gyp RUSTFLAGS="-C link-arg=-s ${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features electron --release
fi

if [ $DEFAULT_PLATFORM = "darwin" ]
then
mkdir -p ../node/build/darwin
cp -f target/${BUILD_TYPE}/libringrtc.dylib ../node/build/darwin/libringrtc.node
cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../node/build/darwin/libringrtc-${TARGET_ARCH}.node
elif [ $DEFAULT_PLATFORM = "win32" ]
then
mkdir -p ../node/build/win32
cp -f target/${BUILD_TYPE}/ringrtc.dll ../node/build/win32/libringrtc.node
cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/ringrtc.dll ../node/build/win32/libringrtc-${TARGET_ARCH}.node
elif [ $DEFAULT_PLATFORM = "linux" ]
then
mkdir -p ../node/build/linux
cp -f target/${BUILD_TYPE}/libringrtc.so ../node/build/linux/libringrtc.node
cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../node/build/linux/libringrtc-${TARGET_ARCH}.node
fi
)
5 changes: 3 additions & 2 deletions src/node/ringrtc/Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

/* tslint:disable max-classes-per-file */

const os = require('os');
import * as os from 'os';
import * as process from 'process';

// tslint:disable-next-line no-var-requires no-require-imports
const Native = require('../../build/' + os.platform() + '/libringrtc.node');
const Native = require('../../build/' + os.platform() + '/libringrtc-' + process.arch + '.node');

// tslint:disable-next-line no-unnecessary-class
class NativeCallManager {
Expand Down
16 changes: 8 additions & 8 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ simplelog = { version = "0.7", optional = true, default-features = false }
rand_chacha = { version = "0.2", optional = true }

# Optional, needed by the "electron" feature
neon = { version = "0.7.0", optional = true, default-features = false, features = ["napi-1"] }
neon = { version = "0.7.1", optional = true, default-features = false, features = ["napi-1"] }

# Optional, needed to check Android-specific code when not targeting Android
jni = { version = "0.17.0", optional = true, default-features = false }
Expand Down