Skip to content

Commit

Permalink
Add Electron cross-compilation support
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisameling authored and jim-signal committed May 12, 2021
1 parent 98663ba commit 142cbdc
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 48 deletions.
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"
;;
*"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

0 comments on commit 142cbdc

Please sign in to comment.