#!/usr/bin/env bash set -e set -u ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary THIS_SCRIPT="$(greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null || readlink -f "${BASH_SOURCE[0]}")" . "$(dirname "$THIS_SCRIPT")/../resources/build/build-utils.sh" ## END STANDARD BUILD SCRIPT INCLUDE . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" display_usage() { echo "usage: build.sh [build options] [targets] [-- options to pass to c++ configure]" echo echo "Build options:" echo " --debug, -d Debug build" echo " --target, -t Target path (linux,macos only, default build/)" echo " --platform, -p Platform to build (wasm or native, default native)" echo echo "Targets (all except install if not specified):" echo " clean Clean target path" echo " configure Configure libraries (linux,macos only)" echo " build Build all libraries" echo " build-cpp Build c++ libraries" echo " tests Run all tests" echo " tests-cpp Run c++ tests" echo " install Install all libraries" echo " install-cpp Install c++ libraries" echo " uninstall Uninstall all libraries" echo " uninstall-cpp Uninstall c++ libraries" echo echo "C++ libraries will be in: TARGETPATH///src" echo "WASM libraries will be in: TARGETPATH/wasm//src" echo "On Windows, will be 'x86' or 'x64'; elsewhere it is 'arch'" exit 0 } get_builder_OS MESON_TARGET=release HAS_TARGET=false CLEAN=false CONFIGURE=false BUILD_CPP=false TESTS_CPP=false INSTALL_CPP=false UNINSTALL_CPP=false QUIET=false TARGET_PATH="$THIS_SCRIPT_PATH/build" ADDITIONAL_ARGS= PLATFORM=native # Parse args shopt -s nocasematch while [[ $# -gt 0 ]] ; do key="$1" case $key in --debug|-d) MESON_TARGET=debug ;; --help|-\?) display_usage ;; --target|-t) TARGET_PATH=$(readlink -f "$2") shift ;; --platform|-p) PLATFORM="$2" shift ;; configure) HAS_TARGET=true CONFIGURE=true ;; clean) HAS_TARGET=true CLEAN=true ;; build) HAS_TARGET=true BUILD_CPP=true ;; *-rust) echo "$key: Rust was removed in " ;; build-cpp) HAS_TARGET=true BUILD_CPP=true ;; tests) HAS_TARGET=true TESTS_CPP=true ;; tests-cpp) HAS_TARGET=true TESTS_CPP=true ;; install) HAS_TARGET=true INSTALL_CPP=true ;; install-cpp) HAS_TARGET=true INSTALL_CPP=true ;; uninstall) HAS_TARGET=true # ninja records the files it installs, so unless we install first we don't know # what to uninstall. Installing will overwrite the existing files, if we then # then uninstall the files get removed - unless previously we had additional files. INSTALL_CPP=true UNINSTALL_CPP=true ;; uninstall-cpp) HAS_TARGET=true INSTALL_CPP=true UNINSTALL_CPP=true ;; --) shift ADDITIONAL_ARGS=$@ break ;; *) fail "Invalid parameters. Use --help for help" esac shift done if ! $HAS_TARGET; then if [ ! -f "$TARGET_PATH" ]; then CONFIGURE=true fi BUILD_CPP=true TESTS_CPP=true fi if [[ $PLATFORM == wasm ]]; then MESON_PATH="$TARGET_PATH/wasm/$MESON_TARGET" else MESON_PATH="$TARGET_PATH/arch/$MESON_TARGET" fi displayInfo "" \ "VERSION: $VERSION" \ "TIER: $TIER" \ "PLATFORM: $PLATFORM" \ "CONFIGURE: $CONFIGURE" \ "CLEAN: $CLEAN" \ "BUILD_CPP: $BUILD_CPP" \ "TESTS_CPP: $TESTS_CPP" \ "INSTALL_CPP: $INSTALL_CPP" \ "UNINSTALL_CPP: $UNINSTALL_CPP" \ "MESON_TARGET: $MESON_TARGET" \ "TARGET_PATH: $TARGET_PATH" \ "" clean() { rm -rf "$TARGET_PATH/" } path_remove() { # Delete path by parts so we can never accidentally remove sub paths PATH=${PATH//":$1:"/":"} # delete any instances in the middle PATH=${PATH/#"$1:"/} # delete any instance at the beginning PATH=${PATH/%":$1"/} # delete any instance in the at the end } build_windows() { # Build targets for Windows # Build the meson targets, both x86 and x64 also # We need to use a batch file here so we can get # the Visual Studio build environment with vcvarsall.bat # TODO: if PATH is the only variable required, let's try and # eliminate this difference in the build process if $BUILD_CPP; then if $TESTS_CPP; then echo_heading "======= Building and Testing C++ library for Windows (x86, x64) =======" cmd //C build.bat all $MESON_TARGET build tests else echo_heading "======= Building C++ library for Windows (x86, x64) =======" cmd //C build.bat all $MESON_TARGET build fi elif $TESTS_CPP; then echo_heading "======= Testing C++ library for Windows (x86, x64) =======" cmd //C build.bat all $MESON_TARGET tests fi } build_standard() { local BUILD_PLATFORM="$1" local ARCH="$2" local RUSTARCH=${3:-} # RUSTARCH is not currently used. if [ $# -gt 3 ]; then shift 3 local STANDARD_MESON_ARGS="$*" else local STANDARD_MESON_ARGS= fi # Build meson targets if $CONFIGURE; then echo_heading "======= Configuring C++ library for $BUILD_PLATFORM =======" pushd "$THIS_SCRIPT_PATH" > /dev/null meson setup "$MESON_PATH" --werror --buildtype $MESON_TARGET $STANDARD_MESON_ARGS $ADDITIONAL_ARGS popd > /dev/null fi if $BUILD_CPP; then echo_heading "======= Building C++ library for $BUILD_PLATFORM =======" pushd "$MESON_PATH" > /dev/null ninja popd > /dev/null fi if $TESTS_CPP; then echo_heading "======= Testing C++ library for $BUILD_PLATFORM =======" pushd "$MESON_PATH" > /dev/null meson test --print-errorlogs popd > /dev/null fi if $INSTALL_CPP; then echo_heading "======= Installing C++ libraries for $BUILD_PLATFORM =======" pushd "$MESON_PATH" > /dev/null ninja install popd > /dev/null fi if $UNINSTALL_CPP; then echo_heading "======= Uninstalling C++ libraries for $BUILD_PLATFORM =======" pushd "$MESON_PATH" > /dev/null ninja uninstall popd > /dev/null fi } # # We don't want to rely on emcc being on the path, because Emscripten puts far # too many things onto the path (in particular for us, node). # # The following comment suggests that we don't need emcc on the path. # https://github.com/emscripten-core/emscripten/issues/4848#issuecomment-1097357775 # # So we try and locate emcc in common locations ourselves. The search pattern # is: # # 1. Look for $EMSCRIPTEN_BASE (our primary emscripten variable), which should # point to the folder that emcc is located in # 2. Look for $EMCC which should point to the emcc executable # 3. Look for emcc on the path # locate_emscripten() { if [[ -z ${EMSCRIPTEN_BASE+x} ]]; then if [[ -z ${EMCC+x} ]]; then local EMCC=`which emcc` [[ -z $EMCC ]] && fail "locate_emscripten: Could not locate emscripten (emcc) on the path or with \$EMCC or \$EMSCRIPTEN_BASE" fi [[ -x $EMCC ]] || fail "locate_emscripten: Variable EMCC ($EMCC) does not point to a valid executable emcc" EMSCRIPTEN_BASE="$(dirname "$EMCC")" fi [[ -x ${EMSCRIPTEN_BASE}/emcc ]] || fail "locate_emscripten: Variable EMSCRIPTEN_BASE ($EMSCRIPTEN_BASE) does not point to emcc's folder" } build_meson_cross_file_for_wasm() { if [ $os_id == win ]; then local R=$(cygpath -w $(echo $EMSCRIPTEN_BASE) | sed 's_\\_\\\\_g') else local R=$(echo $EMSCRIPTEN_BASE | sed 's_/_\\/_g') fi sed -e "s/\$EMSCRIPTEN_BASE/$R/g" wasm.build.$os_id.in > wasm.build } ### if $CLEAN; then clean fi if [[ $PLATFORM == native ]]; then case $os_id in "linux") build_standard $os_id arch ;; "mac") build_standard $os_id arch ;; "win") build_windows ;; esac else locate_emscripten build_meson_cross_file_for_wasm build_standard wasm wasm wasm32-unknown-unknown --cross-file wasm.defs.build --cross-file wasm.build --default-library static fi