mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
26415d39f7
CMake reads CMakePresets.json, which is before it reads CMakeLists.txt. This causes CMake Error: Unrecognized "version" field if the version of CMake is older than support for presets, or the version field of presets. The fix is to check CMake version in ladybird.sh before trying to create the build directory. Co-Authored-By: Andrew Kaster <andrew@ladybird.org>
289 lines
8.5 KiB
Bash
Executable file
289 lines
8.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
set -e
|
|
|
|
BUILD_PRESET=${BUILD_PRESET:-default}
|
|
|
|
ARG0=$0
|
|
print_help() {
|
|
NAME=$(basename "$ARG0")
|
|
cat <<EOF
|
|
Usage: $NAME COMMAND [ARGS...]
|
|
Supported COMMANDs:
|
|
build: Compiles the target binaries, [ARGS...] are passed through to ninja
|
|
install: Installs the target binary
|
|
run: $NAME run EXECUTABLE [ARGS...]
|
|
Runs the EXECUTABLE on the build host, e.g.
|
|
'shell' or 'js', [ARGS...] are passed through to the executable
|
|
gdb: Same as run, but also starts a gdb remote session.
|
|
$NAME gdb EXECUTABLE [-ex 'any gdb command']...
|
|
Passes through '-ex' commands to gdb
|
|
vcpkg: Ensure that dependencies are available
|
|
test: $NAME test [TEST_NAME_PATTERN]
|
|
Runs the unit tests on the build host, or if TEST_NAME_PATTERN
|
|
is specified tests matching it.
|
|
delete: Removes the build environment
|
|
rebuild: Deletes and re-creates the build environment, and compiles the project
|
|
addr2line: $NAME addr2line BINARY_FILE ADDRESS
|
|
Resolves the ADDRESS in BINARY_FILE to a file:line. It will
|
|
attempt to find the BINARY_FILE in the appropriate build directory
|
|
|
|
Examples:
|
|
$NAME run ladybird
|
|
Runs the Ladybird browser
|
|
$NAME run js -A
|
|
Runs the js(1) REPL
|
|
$NAME test
|
|
Runs the unit tests on the build host
|
|
$NAME addr2line RequestServer 0x12345678
|
|
Resolves the address 0x12345678 in the RequestServer binary
|
|
EOF
|
|
}
|
|
|
|
usage() {
|
|
>&2 print_help
|
|
exit 1
|
|
}
|
|
|
|
CMD=$1
|
|
[ -n "$CMD" ] || usage
|
|
shift
|
|
if [ "$CMD" = "help" ]; then
|
|
print_help
|
|
exit 0
|
|
fi
|
|
|
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
|
|
# shellcheck source=/dev/null
|
|
. "${DIR}/shell_include.sh"
|
|
|
|
exit_if_running_as_root "Do not run ladybird.sh as root, your Build directory will become root-owned"
|
|
|
|
# shellcheck source=/dev/null
|
|
. "${DIR}/find_compiler.sh"
|
|
|
|
CMAKE_ARGS=()
|
|
CMD_ARGS=( "$@" )
|
|
|
|
if [ "$(uname -s)" = Linux ] && [ "$(uname -m)" = "aarch64" ]; then
|
|
PKGCONFIG=$(which pkg-config)
|
|
GN=$(command -v gn || echo "")
|
|
CMAKE_ARGS+=("-DPKG_CONFIG_EXECUTABLE=$PKGCONFIG")
|
|
# https://github.com/LadybirdBrowser/ladybird/issues/261
|
|
if [ "$(getconf PAGESIZE)" != "4096" ]; then
|
|
if [ -z "$GN" ]; then
|
|
die "GN not found! Please build GN from source and put it in \$PATH"
|
|
fi
|
|
fi
|
|
cat <<- EOF > Meta/CMake/vcpkg/user-variables.cmake
|
|
set(PKGCONFIG $PKGCONFIG)
|
|
set(GN $GN)
|
|
EOF
|
|
|
|
fi
|
|
|
|
get_top_dir() {
|
|
git rev-parse --show-toplevel
|
|
}
|
|
|
|
create_build_dir() {
|
|
check_program_version_at_least CMake cmake 3.25 || exit 1
|
|
cmake --preset "$BUILD_PRESET" "${CMAKE_ARGS[@]}" -S "$LADYBIRD_SOURCE_DIR" -B "$BUILD_DIR"
|
|
}
|
|
|
|
cmd_with_target() {
|
|
pick_host_compiler
|
|
CMAKE_ARGS+=("-DCMAKE_C_COMPILER=${CC}")
|
|
CMAKE_ARGS+=("-DCMAKE_CXX_COMPILER=${CXX}")
|
|
|
|
if [ ! -d "$LADYBIRD_SOURCE_DIR" ]; then
|
|
LADYBIRD_SOURCE_DIR="$(get_top_dir)"
|
|
export LADYBIRD_SOURCE_DIR
|
|
fi
|
|
|
|
# Note: Keep in sync with buildDir defaults in CMakePresets.json
|
|
case "${BUILD_PRESET}" in
|
|
"default")
|
|
BUILD_DIR="${LADYBIRD_SOURCE_DIR}/Build/ladybird"
|
|
;;
|
|
"Debug")
|
|
BUILD_DIR="${LADYBIRD_SOURCE_DIR}/Build/ladybird-debug"
|
|
;;
|
|
"Sanitizer")
|
|
BUILD_DIR="${LADYBIRD_SOURCE_DIR}/Build/ladybird-sanitizers"
|
|
;;
|
|
esac
|
|
|
|
CMAKE_ARGS+=("-DCMAKE_INSTALL_PREFIX=$LADYBIRD_SOURCE_DIR/Build/ladybird-install-${BUILD_PRESET}")
|
|
|
|
export PATH="$LADYBIRD_SOURCE_DIR/Toolchain/Local/cmake/bin:$LADYBIRD_SOURCE_DIR/Toolchain/Local/vcpkg/bin:$PATH"
|
|
export VCPKG_ROOT="$LADYBIRD_SOURCE_DIR/Toolchain/Tarballs/vcpkg"
|
|
}
|
|
|
|
ensure_target() {
|
|
[ -f "$BUILD_DIR/build.ninja" ] || create_build_dir
|
|
}
|
|
|
|
run_tests() {
|
|
local TEST_NAME="$1"
|
|
local CTEST_ARGS=("--preset" "$BUILD_PRESET" "--output-on-failure" "--test-dir" "$BUILD_DIR")
|
|
if [ -n "$TEST_NAME" ]; then
|
|
if [ "$TEST_NAME" = "WPT" ]; then
|
|
CTEST_ARGS+=("-C" "Integration")
|
|
fi
|
|
CTEST_ARGS+=("-R" "$TEST_NAME")
|
|
fi
|
|
ctest "${CTEST_ARGS[@]}"
|
|
}
|
|
|
|
build_target() {
|
|
# Get either the environment MAKEJOBS or all processors via CMake
|
|
[ -z "$MAKEJOBS" ] && MAKEJOBS=$(cmake -P "$LADYBIRD_SOURCE_DIR/Meta/CMake/processor-count.cmake")
|
|
|
|
# With zero args, we are doing a standard "build"
|
|
# With multiple args, we are doing an install/run
|
|
if [ $# -eq 0 ]; then
|
|
CMAKE_BUILD_PARALLEL_LEVEL="$MAKEJOBS" cmake --build "$BUILD_DIR"
|
|
else
|
|
ninja -j "$MAKEJOBS" -C "$BUILD_DIR" -- "$@"
|
|
fi
|
|
}
|
|
|
|
delete_target() {
|
|
[ ! -d "$BUILD_DIR" ] || rm -rf "$BUILD_DIR"
|
|
}
|
|
|
|
build_vcpkg() {
|
|
( cd "$LADYBIRD_SOURCE_DIR/Toolchain" && ./BuildVcpkg.sh )
|
|
}
|
|
|
|
ensure_toolchain() {
|
|
build_vcpkg
|
|
}
|
|
|
|
run_gdb() {
|
|
local GDB_ARGS=()
|
|
local PASS_ARG_TO_GDB=""
|
|
local LAGOM_EXECUTABLE=""
|
|
local GDB=gdb
|
|
if ! command -v "$GDB" > /dev/null 2>&1; then
|
|
GDB=lldb
|
|
if ! command -v "$GDB" > /dev/null 2>&1; then
|
|
die "Please install gdb or lldb!"
|
|
fi
|
|
fi
|
|
|
|
for arg in "${CMD_ARGS[@]}"; do
|
|
if [ "$PASS_ARG_TO_GDB" != "" ]; then
|
|
GDB_ARGS+=( "$PASS_ARG_TO_GDB" "$arg" )
|
|
|
|
PASS_ARG_TO_GDB=""
|
|
elif [ "$arg" = "-ex" ]; then
|
|
PASS_ARG_TO_GDB="$arg"
|
|
elif [[ "$arg" =~ ^-.*$ ]]; then
|
|
die "Don't know how to handle argument: $arg"
|
|
else
|
|
if [ "$LAGOM_EXECUTABLE" != "" ]; then
|
|
die "Lagom executable can't be specified more than once"
|
|
fi
|
|
LAGOM_EXECUTABLE="$arg"
|
|
fi
|
|
done
|
|
if [ "$PASS_ARG_TO_GDB" != "" ]; then
|
|
GDB_ARGS+=( "$PASS_ARG_TO_GDB" )
|
|
fi
|
|
if [ "$LAGOM_EXECUTABLE" = "ladybird" ]; then
|
|
if [ "$(uname -s)" = "Darwin" ]; then
|
|
LAGOM_EXECUTABLE="Ladybird.app"
|
|
else
|
|
LAGOM_EXECUTABLE="Ladybird"
|
|
fi
|
|
fi
|
|
"$GDB" "$BUILD_DIR/bin/$LAGOM_EXECUTABLE" "${GDB_ARGS[@]}"
|
|
}
|
|
|
|
build_and_run_lagom_target() {
|
|
local lagom_target="${CMD_ARGS[0]}"
|
|
local lagom_args=("${CMD_ARGS[@]:1}")
|
|
|
|
if [ -z "$lagom_target" ]; then
|
|
lagom_target="ladybird"
|
|
fi
|
|
|
|
# FIXME: Find some way to centralize these b/w CMakePresets.json, CI files, Documentation and here.
|
|
if [ "$BUILD_PRESET" = "Sanitizer" ]; then
|
|
export ASAN_OPTIONS=${ASAN_OPTIONS:-"strict_string_checks=1:check_initialization_order=1:strict_init_order=1:detect_stack_use_after_return=1:allocator_may_return_null=1"}
|
|
export UBSAN_OPTIONS=${UBSAN_OPTIONS:-"print_stacktrace=1:print_summary=1:halt_on_error=1"}
|
|
fi
|
|
|
|
build_target "${lagom_target}"
|
|
|
|
if [ "$lagom_target" = "ladybird" ] && [ "$(uname -s)" = "Darwin" ]; then
|
|
"$BUILD_DIR/bin/Ladybird.app/Contents/MacOS/Ladybird" "${lagom_args[@]}"
|
|
else
|
|
local lagom_bin="$lagom_target"
|
|
if [ "$lagom_bin" = "ladybird" ]; then
|
|
lagom_bin="Ladybird"
|
|
fi
|
|
"$BUILD_DIR/bin/$lagom_bin" "${lagom_args[@]}"
|
|
fi
|
|
}
|
|
|
|
if [[ "$CMD" =~ ^(build|install|run|gdb|test|rebuild|recreate|addr2line)$ ]]; then
|
|
cmd_with_target
|
|
[[ "$CMD" != "recreate" && "$CMD" != "rebuild" ]] || delete_target
|
|
ensure_toolchain
|
|
ensure_target
|
|
case "$CMD" in
|
|
build)
|
|
build_target "${CMD_ARGS[@]}"
|
|
;;
|
|
install)
|
|
build_target
|
|
build_target install
|
|
;;
|
|
run)
|
|
build_and_run_lagom_target
|
|
;;
|
|
gdb)
|
|
[ $# -ge 1 ] || usage
|
|
build_target "${CMD_ARGS[@]}"
|
|
run_gdb "${CMD_ARGS[@]}"
|
|
;;
|
|
test)
|
|
build_target
|
|
run_tests "${CMD_ARGS[0]}"
|
|
;;
|
|
rebuild)
|
|
build_target "${CMD_ARGS[@]}"
|
|
;;
|
|
recreate)
|
|
;;
|
|
addr2line)
|
|
build_target
|
|
[ $# -ge 2 ] || usage
|
|
BINARY_FILE="$1"; shift
|
|
BINARY_FILE_PATH="$BUILD_DIR/$BINARY_FILE"
|
|
command -v addr2line >/dev/null 2>&1 || die "Please install addr2line!"
|
|
ADDR2LINE=addr2line
|
|
if [ -x "$BINARY_FILE_PATH" ]; then
|
|
"$ADDR2LINE" -e "$BINARY_FILE_PATH" "$@"
|
|
else
|
|
find "$BUILD_DIR" -name "$BINARY_FILE" -executable -type f -exec "$ADDR2LINE" -e {} "$@" \;
|
|
fi
|
|
;;
|
|
*)
|
|
build_target "$CMD" "${CMD_ARGS[@]}"
|
|
;;
|
|
esac
|
|
elif [ "$CMD" = "delete" ]; then
|
|
cmd_with_target
|
|
delete_target
|
|
elif [ "$CMD" = "vcpkg" ]; then
|
|
cmd_with_target
|
|
ensure_toolchain
|
|
else
|
|
>&2 echo "Unknown command: $CMD"
|
|
usage
|
|
fi
|