diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f4a215413..78e11015ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,7 +190,7 @@ else() endif() # Dependencies version, this must match the number in external_deps/build.sh -set(DEPS_VERSION 11) +set(DEPS_VERSION 12) option(USE_EXTERNAL_DEPS "Download or reuse dependencies from EXTERNAL_DEPS_DIR (mandatory for building and running NaCl .nexe binaries)." ON) @@ -220,17 +220,7 @@ if (USE_EXTERNAL_DEPS AND NOT YOKAI_TARGET_SYSTEM_NACL) set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64 i686) elseif (YOKAI_TARGET_SYSTEM_MACOS) set(DEPS_SYSTEM macos) - set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64) - - if (YOKAI_TARGET_ARCH_ARM64) - set(DEPS_ARCH amd64) - - set_deps_dir() - - if (NOT EXISTS ${DEPS_DIR}) - set(DEFAULT_USE_EXTERNAL_DEPS_LIBS OFF) - endif() - endif() + set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64 arm64) elseif (YOKAI_TARGET_SYSTEM_LINUX) set(DEPS_SYSTEM linux) set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64 i686 arm64 armhf) @@ -973,8 +963,8 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER # The NaCl loader and IRT are required to load .nexe files add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/nacl_loader${CMAKE_EXECUTABLE_SUFFIX} - ${FULL_OUTPUT_DIR}/nacl_loader${CMAKE_EXECUTABLE_SUFFIX} + ${DEPS_DIR}/nacl_loader-${DAEMON_NACL_ARCH_NAME}${CMAKE_EXECUTABLE_SUFFIX} + ${FULL_OUTPUT_DIR}/nacl_loader-${DAEMON_NACL_ARCH_NAME}${CMAKE_EXECUTABLE_SUFFIX} ) add_custom_command(TARGET runtime_deps PRE_BUILD @@ -986,8 +976,8 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER # Linux uses a bootstrap program to reserve address space if (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY) if (YOKAI_TARGET_ARCH_ARM64) - add_executable(nacl_helper_bootstrap-armhf tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp) - add_dependencies(runtime_deps nacl_helper_bootstrap-armhf) + add_executable(nacl_helper_bootstrap-ldarmhf tools/nacl_helper_bootstrap-ldarmhf/nacl_helper_bootstrap-ldarmhf.cpp) + add_dependencies(runtime_deps nacl_helper_bootstrap-ldarmhf) add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory @@ -1003,8 +993,8 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/nacl_helper_bootstrap - ${FULL_OUTPUT_DIR}/nacl_helper_bootstrap + ${DEPS_DIR}/nacl_helper_bootstrap-${DAEMON_NACL_ARCH_NAME} + ${FULL_OUTPUT_DIR}/nacl_helper_bootstrap-${DAEMON_NACL_ARCH_NAME} ) endif() diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4140a21f14..b447db1a27 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -22,9 +22,19 @@ pr: - .gitmodules jobs: - - job: Mac + - job: macOS pool: vmImage: 'macOS-15' + strategy: + matrix: + AppleClang amd64: + MACOS_ARCH: x86_64 + MACOS_VERSION: 10.14 + TEST: true + AppleClang arm64: + MACOS_ARCH: arm64 + MACOS_VERSION: 11.7 + TEST: false steps: - bash: | set -e @@ -56,12 +66,14 @@ jobs: cmake --version export CFLAGS='-Wno-c++14-extensions' export CXXFLAGS='-Wno-c++14-extensions' - cmake -Wdev -Wdeprecated -DUSE_PRECOMPILED_HEADER=0 -DUSE_WERROR=1 -DBE_VERBOSE=1 -DCMAKE_BUILD_TYPE=Release -DBUILD_DUMMY_APP=1 -DBUILD_DUMMY_GAMELOGIC=1 -DBUILD_TESTS=1 -H. -Bbuild + cmake -Wdev -Wdeprecated -DCMAKE_OSX_ARCHITECTURES=${MACOS_ARCH} -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOS_VERSION} -DPREFER_EXTERNAL_LIBS=OFF -DUSE_PRECOMPILED_HEADER=0 -DUSE_WERROR=1 -DBE_VERBOSE=1 -DCMAKE_BUILD_TYPE=Release -DBUILD_DUMMY_APP=1 -DBUILD_DUMMY_GAMELOGIC=1 -DBUILD_TESTS=1 -H. -Bbuild cmake --build build -- -j`sysctl -n hw.logicalcpu` displayName: 'Build' - bash: | - set -e - build/test-ttyclient -pakpath pkg -set fs_basepak daemon -set vm.cgame.type 3 + if "${TEST}"; then + set -e + build/test-ttyclient -pakpath pkg -set fs_basepak daemon -set vm.cgame.type 3 + fi displayName: 'Test' - job: Linux diff --git a/cmake/DaemonNacl.cmake b/cmake/DaemonNacl.cmake index e37bf06844..cc5c5aef54 100644 --- a/cmake/DaemonNacl.cmake +++ b/cmake/DaemonNacl.cmake @@ -26,7 +26,7 @@ # Native client -option(USE_NACL_SAIGO "Use Saigo toolchain to build NaCl executables" OFF) +option(USE_NACL_SAIGO "Use the Saigo toolchain to build NaCl executables" ON) if (YOKAI_TARGET_SYSTEM_NACL) # Build nexe binary. diff --git a/cmake/DaemonNaclHost.cmake b/cmake/DaemonNaclHost.cmake index 992dae3852..7172e71d55 100644 --- a/cmake/DaemonNaclHost.cmake +++ b/cmake/DaemonNaclHost.cmake @@ -25,18 +25,18 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. function(daemon_detect_nacl_arch) - set(arch_name "${YOKAI_TARGET_ARCH_NAME}") - set(nacl_arch "${arch_name}") + set(target_arch "${YOKAI_TARGET_ARCH_NAME}") + set(nacl_arch "${target_arch}") if (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY OR YOKAI_TARGET_SYSTEM_XDG_COMPATIBILITY) - set(armhf_usage "arm64;armel") - if ("${arch_name}" IN_LIST armhf_usage) - # Load 32-bit armhf nexe on 64-bit arm64 engine on Linux with multiarch. - # The nexe is system agnostic so there should be no difference with armel. - set(nacl_arch "armhf") + set(armhf_usage "arm64" "armel") + set(box64_usage "ppc64el" "riscv64") - set(box64_usage ppc64el riscv64) - if ("${arch_name}" IN_LIST box64_usage) + if ("${target_arch}" IN_LIST armhf_usage) + # Load 32-bit armhf nexe on 64-bit arm64 engine on Linux with multiarch. + # The nexe is system agnostic so there should be no difference with armel. + set(nacl_arch "armhf") + elseif ("${target_arch}" IN_LIST box64_usage) option(DAEMON_NACL_BOX64_EMULATION "Use Box64 to emulate x86_64 NaCl loader on unsupported platforms" ON) if (DAEMON_NACL_BOX64_EMULATION) # Use Box64 to run x86_64 NaCl loader and amd64 nexe. @@ -45,27 +45,32 @@ function(daemon_detect_nacl_arch) add_definitions(-DDAEMON_NACL_BOX64_EMULATION) endif() endif() - endif() - - elseif (DAEMON_TARGET_SYSTEM_MACOS) - if ("${arch_name}" STREQUAL "arm64") + elseif (YOKAI_TARGET_SYSTEM_MACOS) + if ("${target_arch}" STREQUAL "arm64") # You can get emulated NaCl going like this: # cp external_deps/macos-amd64-default_10/{nacl_loader,irt_core-amd64.nexe} build/ set(nacl_arch "amd64") endif() endif() - string(TOUPPER "${nacl_arch_name}" nacl_arch_name_upper) - - # The DAEMON_NACL_ARCH_NAME variable contributes to the nexe file name. - set(DAEMON_NACL_ARCH_NAME "${nacl_arch}" PARENT_SCOPE) - set(DAEMON_NACL_ARCH_NAME_UPPER "${nacl_arch_upper}" PARENT_SCOPE) + string(TOUPPER "${nacl_arch}" nacl_arch_upper) # NaCl runtime is only available on architectures that have a NaCl loader. - set(nacl_runtime_arch amd64 i686 armhf) + set(nacl_runtime_arch "amd64" "i686" "armhf") if ("${nacl_arch}" IN_LIST nacl_runtime_arch) + message(STATUS "Detected NaCl architecture: ${nacl_arch}") + add_definitions(-DDAEMON_NACL_RUNTIME_ENABLED) + else() + set(nacl_arch "unknown") + + message(STATUS "No NaCl architecture detected") endif() + + # The DAEMON_NACL_ARCH_NAME variable contributes to the nexe file name. + set(DAEMON_NACL_ARCH_NAME "${nacl_arch}" PARENT_SCOPE) + + set(DAEMON_NACL_ARCH_NAME_UPPER "${nacl_arch_upper}" PARENT_SCOPE) endfunction() daemon_detect_nacl_arch() diff --git a/external_deps/build.sh b/external_deps/build.sh index e5e77cf91a..80db64f54c 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -9,11 +9,12 @@ WORK_DIR="${PWD}" # This should match the DEPS_VERSION in CMakeLists.txt. # This is mostly to ensure the path the files end up at if you build deps yourself # are the same as the ones when extracting from the downloaded packages. -DEPS_VERSION=11 +DEPS_VERSION=12 # Package download pages PKGCONFIG_BASEURL='https://pkg-config.freedesktop.org/releases' NASM_BASEURL='https://www.nasm.us/pub/nasm/releasebuilds' +JWASM_BASEURL='https://api.github.com/repos/JWasm/JWasm/zipball' ZLIB_BASEURL='https://zlib.net/fossils' GMP_BASEURL='https://gmplib.org/download/gmp' NETTLE_BASEURL='https://mirror.cyberbits.eu/gnu/nettle' @@ -31,6 +32,7 @@ OGG_BASEURL='https://downloads.xiph.org/releases/ogg' VORBIS_BASEURL='https://downloads.xiph.org/releases/vorbis' OPUS_BASEURL='https://downloads.xiph.org/releases/opus' OPUSFILE_BASEURL='https://downloads.xiph.org/releases/opus' +SAIGOSDK_BASEURL='https://github.com/DaemonEngine/saigo-release-scripts/releases' # No index. NACLSDK_BASEURL='https://storage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk' # No index. @@ -42,54 +44,60 @@ WASMTIME_BASEURL='https://github.com/bytecodealliance/wasmtime/releases' # Package versions PKGCONFIG_VERSION=0.29.2 NASM_VERSION=2.16.03 -ZLIB_VERSION=1.3.1 +JWASM_REVISION='a5c4ea03cc0545a15d81a354251b5f534bef7a1b' +ZLIB_VERSION=1.3.2 GMP_VERSION=6.3.0 -NETTLE_VERSION=3.10.2 -CURL_VERSION=8.15.0 -SDL3_VERSION=3.2.22 -GLEW_VERSION=2.2.0 -PNG_VERSION=1.6.50 -JPEG_VERSION=3.1.1 +NETTLE_VERSION=4.0 +CURL_VERSION=8.21.0 +SDL3_VERSION=3.4.10 +GLEW_VERSION=2.3.1 +PNG_VERSION=1.6.58 +JPEG_VERSION=3.1.4.1 # WebP 1.6.0 introduced AVX2 intrinsics that are not available on # the GCC 10 compiler provided by Debian Bullseye. WEBP_VERSION=1.5.0 +# OpenAL 0.25.0 requires C++20 that is not availabnle on +# the GCC 10 compiler provided by Debian Bullseye. OPENAL_VERSION=1.24.3 OGG_VERSION=1.3.6 VORBIS_VERSION=1.3.7 -OPUS_VERSION=1.5.2 +OPUS_VERSION=1.6.1 OPUSFILE_VERSION=0.12 +SAIGOSDK_VERSION='21.0-20260625' NACLSDK_VERSION=44.0.2403.155 -NACLRUNTIME_REVISION=2aea5fcfce504862a825920fcaea1a8426afbd6f +NACLRUNTIME_REVISION='ed47b7ff4f7e8b9f1a08edb7eab3875e99500131' NCURSES_VERSION=6.5 WASISDK_VERSION=16.0 WASMTIME_VERSION=2.0.2 -# Require the compiler names to be explicitly hardcoded, we should not inherit them -# from environment as we heavily cross-compile. -CC='false' -CXX='false' -# Set defaults. -LD='ld' -AR='ar' -RANLIB='ranlib' -PKG_CONFIG='pkg-config' -CROSS_PKG_CONFIG_PATH='' -LIBS_SHARED='OFF' -LIBS_STATIC='ON' -CMAKE_TOOLCHAIN='' -# Always reset flags, we heavily cross-compile and must not inherit any stray flag -# from environment. -CPPFLAGS='' -CFLAGS='-O3 -fPIC' -CXXFLAGS='-O3 -fPIC' -LDFLAGS='-O3 -fPIC' - log() { level="${1}"; shift printf '%s: %s\n' "${level}" "${@}" >&2 [ "${level}" != 'ERROR' ] } +smart_copy() { + if ! cp --reflink=auto -P "${@}" 2>/dev/null + then + cp -P "${@}" + fi +} + +dedupe_dir () +{ + if command -v jdupes >/dev/null 2>&1 + then + log STATUS 'Using jdupes for deduplication' + jdupes -r -L "${@}" + elif command -v rdfind >/dev/null 2>&1 + then + log STATUS 'Using rdfind for deduplication' + rdfind -makeresultsfile false -makehardlinks true "${@}" + else + log WARNING 'WARN: missing jdupes or rdfind, will not deduplicate' + fi +} + # Extract an archive into the given subdirectory of the build dir and cd to it # Usage: extract extract() { @@ -122,7 +130,7 @@ extract() { *.dmg) local dmg_temp_dir="$(mktemp -d)" hdiutil attach -mountpoint "${dmg_temp_dir}" "${archive_file}" - cp -R "${dmg_temp_dir}/"* "${extract_dir}/" + smart_copy -R "${dmg_temp_dir}/." "${extract_dir}/" hdiutil detach "${dmg_temp_dir}" rmdir "${dmg_temp_dir}" ;; @@ -176,6 +184,18 @@ download_extract() { configure_build() { local configure_args=() + case "${HOST}" in + native) + configure_args+=(--prefix="${NATIVE_PREFIX}") + configure_args+=(--libdir="${NATIVE_PREFIX}/lib") + ;; + *) + configure_args+=(--host="${HOST}") + configure_args+=(--prefix="${PREFIX}") + configure_args+=(--libdir="${PREFIX}/lib") + ;; + esac + if [ "${LIBS_SHARED}" = 'ON' ] then configure_args+=(--enable-shared) @@ -197,9 +217,6 @@ configure_build() { fi ./configure \ - --host="${HOST}" \ - --prefix="${PREFIX}" \ - --libdir="${PREFIX}/lib" \ "${configure_args[@]}" make @@ -223,6 +240,24 @@ get_compiler_arg1() { cmake_build() { local cmake_args=() + case "${HOST}" in + native) + cmake_args+=(-DCMAKE_PREFIX_PATH="${NATIVE_PREFIX}") + cmake_args+=(-DCMAKE_INSTALL_PREFIX="${NATIVE_PREFIX}") + ;; + *) + cmake_args+=(-DCMAKE_PREFIX_PATH="${PREFIX}") + cmake_args+=(-DCMAKE_INSTALL_PREFIX="${PREFIX}") + ;; + esac + + case "${HOST}" in + macos-*) + cmake_args+=(-DCMAKE_OSX_ARCHITECTURES="${MACOS_ARCH}") + cmake_args+=(-DCMAKE_OSX_DEPLOYMENT_TARGET="${MACOS_VERSION}") + ;; + esac + cmake_args+=(-DCMAKE_C_COMPILER="$(get_compiler_name ${CC})") cmake_args+=(-DCMAKE_CXX_COMPILER="$(get_compiler_name ${CXX})") cmake_args+=(-DCMAKE_C_COMPILER_ARG1="$(get_compiler_arg1 ${CC})") @@ -231,17 +266,21 @@ cmake_build() { cmake_args+=(-DCMAKE_CXX_FLAGS="${CXXFLAGS}") cmake_args+=(-DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}") + if [ -n "${CMAKE_TOOLCHAIN:-}" ] + then + cmake_args+=(-DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN}") + fi + # Check for ${@} not being empty to workaround a macOS bash limitation. if [ -n "${1:-}" ] then cmake_args+=("${@}") fi + rm -rf build + cmake -S . -B build \ - -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN}" \ -DCMAKE_BUILD_TYPE='Release' \ - -DCMAKE_PREFIX_PATH="${PREFIX}" \ - -DCMAKE_INSTALL_PREFIX="${PREFIX}" \ -DBUILD_SHARED_LIBS="${LIBS_SHARED}" \ "${cmake_args[@]}" @@ -249,42 +288,43 @@ cmake_build() { cmake --install build --strip } -# Build pkg-config, needed for opusfile. -# As a host-mode dependency it must be provided by the system when cross-compiling. -build_pkgconfig() { +# Build pkg-config, needed for opusfile on macos. +# It is part of the cross-compilation toolchain. +# As a host-mode native dependency it must be provided by the system when cross-compiling. +build_native-pkgconfig() { local dir_name="pkg-config-${PKGCONFIG_VERSION}" local archive_name="${dir_name}.tar.gz" - download_extract pkgconfig "${archive_name}" \ + download_extract native-pkgconfig "${archive_name}" \ "${PKGCONFIG_BASEURL}/${archive_name}" "${download_only}" && return cd "${dir_name}" - # Reset the environment variables, we don't cross-compile this, - # it is part of the cross-compilation toolchain. - # CXXFLAGS is unused. - CFLAGS='-Wno-error=int-conversion' \ - LDFLAGS='' \ - HOST='' \ - configure_build \ + ( + setup_platform 'native' + CFLAGS='-Wno-error=int-conversion' \ + configure_build \ --with-internal-glib + ) } -# Build NASM -build_nasm() { +# Build NASM, needed for jpeg on macos-amd64. +# It is part of the compilation toolchain. +# As a host-mode native dependency it must be provided by the system when compiling. +build_native-nasm() { case "${PLATFORM}" in - macos-*-*) + macos-amd64-*) local dir_name="nasm-${NASM_VERSION}" local archive_name="${dir_name}-macosx.zip" - download_extract nasm "${archive_name}" \ + download_extract native-nasm "${archive_name}" \ "${NASM_BASEURL}/${NASM_VERSION}/macosx/${archive_name}" "${download_only}" && return - cp "${dir_name}/nasm" "${PREFIX}/bin" + smart_copy "${dir_name}/nasm" "${NATIVE_PREFIX}/bin" ;; *) log ERROR 'Unsupported platform for NASM' @@ -292,6 +332,35 @@ build_nasm() { esac } +# Build JWasm, needed for naclruntime for windows. +# It is part of the compilation toolchain. +# As a host-mode native dependency it must be provided by the system when compiling. +build_native-jwasm() { + case "${PLATFORM}" in + windows-*-*) + local dir_name="JWasm-JWasm-${JWASM_REVISION:0:7}" + local archive_name="jwasm-${JWASM_REVISION}.zip" + + download_extract native-jwasm "${archive_name}" \ + "${JWASM_BASEURL}/${JWASM_REVISION}" + + "${download_only}" && return + + cd "${dir_name}" + + ( + setup_platform 'native' + cmake_build + cp -a "build/jwasm${EXE_EXT}" "${NATIVE_PREFIX}/bin/jwasm${EXE_EXT}" + ) + ;; + *) + log ERROR 'Unsupported platform for JWasm' + ;; + esac + +} + # Build zlib build_zlib() { # Only the latest zlib version is provided as tar.xz, the @@ -455,16 +524,18 @@ build_sdl3() { case "${PLATFORM}" in windows-*-mingw) cd "${dir_name}" - cp -rv "${HOST}"/* "${PREFIX}/" + smart_copy -R "${HOST}/." "${PREFIX}/" rm "${PREFIX}/lib/libSDL3_test.a" rm "${PREFIX}/lib/cmake/SDL3/SDL3testTargets"*.cmake ;; windows-*-msvc) cd "${dir_name}" - mkdir -p "${PREFIX}/SDL3/cmake" - cp "cmake/"* "${PREFIX}/SDL3/cmake" - mkdir -p "${PREFIX}/SDL3/include/SDL3" - cp "include/SDL3/"* "${PREFIX}/SDL3/include/SDL3" + mkdir -p "${PREFIX}/SDL3" + rm -rf "${PREFIX}/SDL3/cmake" + smart_copy -R "cmake/." "${PREFIX}/SDL3/cmake/" + mkdir -p "${PREFIX}/SDL3/include" + rm -rf "${PREFIX}/SDL3/include/SDL3" + smart_copy -R "include/SDL3/." "${PREFIX}/SDL3/include/SDL3/" case "${PLATFORM}" in *-i686-*) @@ -479,18 +550,20 @@ build_sdl3() { esac mkdir -p "${PREFIX}/SDL3/${sdl3_lib_dir}" - cp "${sdl3_lib_dir}/SDL3.lib" "${PREFIX}/SDL3/${sdl3_lib_dir}" - cp "${sdl3_lib_dir}/"*.dll "${PREFIX}/SDL3/${sdl3_lib_dir}" + smart_copy "${sdl3_lib_dir}/SDL3.lib" "${PREFIX}/SDL3/${sdl3_lib_dir}/" + smart_copy "${sdl3_lib_dir}/"*.dll "${PREFIX}/SDL3/${sdl3_lib_dir}/" ;; macos-*-*) - cp -R "SDL3.xcframework/macos-arm64_x86_64/SDL3.framework" "${PREFIX}/lib" + rm -rf "${PREFIX}/lib/SDL3.framework" + smart_copy -R "SDL3.xcframework/macos-arm64_x86_64/SDL3.framework/." "${PREFIX}/lib/SDL3.framework/" ;; *) cd "${dir_name}" cmake_build \ -DSDL_TEST_LIBRARY=OFF \ - -DSDL_AUDIO=OFF + -DSDL_AUDIO=OFF \ + -DSDL_GPU=OFF ;; esac } @@ -550,7 +623,7 @@ build_glew() { windows-*-*) mv "${PREFIX}/lib/glew32.dll" "${PREFIX}/bin/" rm "${PREFIX}/lib/libglew32.a" - cp lib/libglew32.dll.a "${PREFIX}/lib/" + smart_copy lib/libglew32.dll.a "${PREFIX}/lib/" ;; macos-*-*) install_name_tool -id "@rpath/libGLEW.${GLEW_VERSION}.dylib" "${PREFIX}/lib/libGLEW.${GLEW_VERSION}.dylib" @@ -762,9 +835,9 @@ build_openal() { case "${PLATFORM}" in windows-*-*) cd "${dir_name}" - cp -r "include/AL" "${PREFIX}/include" - cp "libs/${openal_win_dir}/libOpenAL32.dll.a" "${PREFIX}/lib" - cp "bin/${openal_win_dir}/soft_oal.dll" "${PREFIX}/bin/OpenAL32.dll" + smart_copy -R "include/AL" "${PREFIX}/include" + smart_copy "libs/${openal_win_dir}/libOpenAL32.dll.a" "${PREFIX}/lib" + smart_copy "bin/${openal_win_dir}/soft_oal.dll" "${PREFIX}/bin/OpenAL32.dll" ;; *) cd "${dir_name}" @@ -879,6 +952,8 @@ build_opusfile() { cd "${dir_name}" + # The old configure script doesn't recognize the arm64 prefix. + HOST="${HOST/arm64-apple/aarch64-apple}" \ configure_build \ --disable-http } @@ -897,7 +972,7 @@ build_ncurses() { cd "${dir_name}" # Brutally disable writing to database - cp /dev/null misc/run_tic.in + smart_copy /dev/null misc/run_tic.in # Configure terminfo search dirs based on the ones used in Debian. By default it will only look in (only) the install directory. configure_build \ --with-strip-program="${STRIP}" \ @@ -907,6 +982,20 @@ build_ncurses() { --with-default-terminfo-dir=/usr/share/terminfo } +# "Builds" (downloads) Saigo +build_saigosdk() { + local dir_name="saigocc-${PLATFORM_TARGET}_${SAIGOSDK_VERSION}" + local archive_name="${dir_name}.tar.xz" + + download_extract saigosdk "${archive_name}" \ + "${SAIGOSDK_BASEURL}/download/v${SAIGOSDK_VERSION}/${archive_name}" + + "${download_only}" && return + + rm -rf "${PREFIX}/saigo_newlib" + smart_copy -R "${dir_name}" "${PREFIX}/saigo_newlib" +} + # "Builds" (downloads) the WASI SDK build_wasisdk() { case "${PLATFORM}" in @@ -937,7 +1026,8 @@ build_wasisdk() { "${download_only}" && return - cp -r "${dir_name}" "${PREFIX}/wasi-sdk" + rm -rf "${PREFIX}/wasi-sdk" + smart_copy -R "${dir_name}" "${PREFIX}/wasi-sdk" } # "Builds" (downloads) wasmtime @@ -977,8 +1067,8 @@ build_wasmtime() { "${download_only}" && return cd "${dir_name}" - cp -r include/* "${PREFIX}/include" - cp -r lib/* "${PREFIX}/lib" + smart_copy -R 'include/.' "${PREFIX}/include/" + smart_copy -R 'lib/.' "${PREFIX}/lib/" } # Build the NaCl SDK @@ -986,17 +1076,14 @@ build_naclsdk() { case "${PLATFORM}" in windows-*-*) local NACLSDK_PLATFORM=win - local EXE=.exe local TAR_EXT=cygtar ;; macos-*-*) local NACLSDK_PLATFORM=mac - local EXE= local TAR_EXT=tar ;; linux-*-*) local NACLSDK_PLATFORM=linux - local EXE= local TAR_EXT=tar ;; esac @@ -1005,7 +1092,7 @@ build_naclsdk() { local NACLSDK_ARCH=x86_32 local DAEMON_ARCH=i686 ;; - *-amd64-*) + *-amd64-*|macos-arm64-*) local NACLSDK_ARCH=x86_64 local DAEMON_ARCH=amd64 ;; @@ -1022,24 +1109,18 @@ build_naclsdk() { "${download_only}" && return - cp pepper_*"/tools/irt_core_${NACLSDK_ARCH}.nexe" "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" - case "${PLATFORM}" in - linux-amd64-*) - ;; # Get sel_ldr from naclruntime package - *) - cp pepper_*"/tools/sel_ldr_${NACLSDK_ARCH}${EXE}" "${PREFIX}/nacl_loader${EXE}" - ;; - esac + smart_copy pepper_*"/tools/irt_core_${NACLSDK_ARCH}.nexe" "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" + case "${PLATFORM}" in windows-i686-*|*-amd64-*) - cp pepper_*"/toolchain/${NACLSDK_PLATFORM}_x86_newlib/bin/x86_64-nacl-gdb${EXE}" "${PREFIX}/nacl-gdb${EXE}" + smart_copy pepper_*"/toolchain/${NACLSDK_PLATFORM}_x86_newlib/bin/x86_64-nacl-gdb${EXE_EXT}" "${PREFIX}/nacl-gdb${EXE_EXT}" rm -rf "${PREFIX}/pnacl" patch -d pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl/bin/pydir" \ -p1 < "${SCRIPT_DIR}/naclsdk-pydir-python3.patch" >/dev/null - cp -a pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl" "${PREFIX}/pnacl" + smart_copy -R pepper_*"/toolchain/${NACLSDK_PLATFORM}_pnacl" "${PREFIX}/pnacl" rm -rf "${PREFIX}/pnacl/bin/"{i686,x86_64}-nacl-* rm -rf "${PREFIX}/pnacl/arm-nacl" rm -rf "${PREFIX}/pnacl/arm_bc-nacl" @@ -1051,45 +1132,53 @@ build_naclsdk() { esac case "${PLATFORM}" in windows-i686-*) - cp pepper_*"/tools/sel_ldr_x86_64.exe" "${PREFIX}/nacl_loader-amd64.exe" - cp pepper_*"/tools/irt_core_x86_64.nexe" "${PREFIX}/irt_core-amd64.nexe" + smart_copy pepper_*"/tools/irt_core_x86_64.nexe" "${PREFIX}/irt_core-amd64.nexe" ;; - linux-amd64-*) + linux-*) # Fix permissions on a few files which deny access to non-owner chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" ;; - linux-i686-*) - cp pepper_*"/tools/nacl_helper_bootstrap_${NACLSDK_ARCH}" "${PREFIX}/nacl_helper_bootstrap" - # Fix permissions on a few files which deny access to non-owner - chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" - chmod 755 "${PREFIX}/nacl_helper_bootstrap" "${PREFIX}/nacl_loader" - ;; - linux-armhf-*|linux-arm64-*) - cp pepper_*"/tools/nacl_helper_bootstrap_arm" "${PREFIX}/nacl_helper_bootstrap" - # Fix permissions on a few files which deny access to non-owner - chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" - chmod 755 "${PREFIX}/nacl_helper_bootstrap" "${PREFIX}/nacl_loader" - ;; esac case "${PLATFORM}" in linux-arm64-*) mkdir -p "${PREFIX}/lib-armhf" - cp -a pepper_*"/tools/lib/arm_trusted/lib/." "${PREFIX}/lib-armhf/." + smart_copy -R pepper_*"/tools/lib/arm_trusted/lib/." "${PREFIX}/lib-armhf/." # Copy the library loader instead of renaming it because there may still be some # references to ld-linux-armhf.so.3 in binaries. - cp "${PREFIX}/lib-armhf/ld-linux-armhf.so.3" "${PREFIX}/lib-armhf/ld-linux-armhf" - # We can't use patchelf or 'nacl_helper_bootstrap nacl_loader' will complain: - # bootstrap_helper: nacl_loader: ELF file has unreasonable e_phnum=13 - sed -e 's|/lib/ld-linux-armhf.so.3|lib-armhf/ld-linux-armhf|' -i "${PREFIX}/nacl_loader" + smart_copy "${PREFIX}/lib-armhf/ld-linux-armhf.so.3" "${PREFIX}/lib-armhf/ld-linux-armhf" ;; esac } # Only builds nacl_loader and nacl_helper_bootstrap for now, not IRT. build_naclruntime() { + local nacl_arch_list=() + case "${PLATFORM}" in + windows-amd64-*) + nacl_arch_list+=('amd64') + ;; + windows-i686-*) + nacl_arch_list+=('i686') + nacl_arch_list+=('amd64') + ;; linux-amd64-*) - local NACL_ARCH=x86-64 + nacl_arch_list+=('amd64') + ;; + linux-i686-*) + nacl_arch_list+=('i686') + ;; + linux-arm64-*) + nacl_arch_list+=('armhf') + ;; + linux-armhf-*) + nacl_arch_list+=('armhf') + ;; + macos-amd64-*) + nacl_arch_list+=('amd64') + ;; + macos-arm64-*) + nacl_arch_list+=('amd64') ;; *) log ERROR 'Unsupported platform for naclruntime' @@ -1100,14 +1189,39 @@ build_naclruntime() { local archive_name="native_client-${NACLRUNTIME_REVISION}.zip" download_extract naclruntime "${archive_name}" \ - "{$NACLRUNTIME_BASEURL}/${NACLRUNTIME_REVISION}" + "${NACLRUNTIME_BASEURL}/${NACLRUNTIME_REVISION}" "${download_only}" && return cd "${dir_name}" - env -i /usr/bin/env bash -l -c "python3 /usr/bin/scons --mode=opt-linux 'platform=${NACL_ARCH}' werror=0 sysinfo=0 sel_ldr" - cp "scons-out/opt-linux-${NACL_ARCH}/staging/nacl_helper_bootstrap" "${PREFIX}/nacl_helper_bootstrap" - cp "scons-out/opt-linux-${NACL_ARCH}/staging/sel_ldr" "${PREFIX}/nacl_loader" + + for nacl_arch in "${nacl_arch_list[@]}" + do + ( + setup_platform "${PLATFORM_SYSTEM}-${nacl_arch}-${PLATFORM_COMPILER}" + cmake_build + ) + + case "${PLATFORM}" in + linux-*) + mv "${PREFIX}/bin/nacl_helper_bootstrap" "${PREFIX}/nacl_helper_bootstrap-${nacl_arch}" + ;; + esac + + mv "${PREFIX}/bin/sel_ldr${EXE_EXT}" "${PREFIX}/nacl_loader-${nacl_arch}${EXE_EXT}" + + case "${PLATFORM}" in + linux-arm64-*) + case "${nacl_arch}" in + armhf) + # We can't use patchelf or 'nacl_helper_bootstrap nacl_loader' will complain: + # bootstrap_helper: nacl_loader: ELF file has unreasonable e_phnum=13 + sed -e 's|/lib/ld-linux-armhf.so.3|lib-armhf/ld-linux-armhf|' -i "${PREFIX}/nacl_loader-armhf" + ;; + esac + ;; + esac + done } # Check for DLL dependencies on MinGW stuff. For MSVC platforms this is bad because it should work @@ -1274,17 +1388,27 @@ build_install() { # Create a redistributable package for the dependencies build_package() { + local XZ_OPT='-9e' + cd "${WORK_DIR}" + rm -f "${PKG_BASEDIR}.tar.xz" - local XZ_OPT='-9' + case "${PLATFORM}" in windows-*-*) - tar --dereference -cvJf "${PKG_BASEDIR}.tar.xz" "${PKG_BASEDIR}" - ;; - *) - tar -cvJf "${PKG_BASEDIR}.tar.xz" "${PKG_BASEDIR}" + # Dereference symbolic links. + rm -rf "${PKG_BASEDIR}.flatten" + mv "${PKG_BASEDIR}" "${PKG_BASEDIR}.flatten" + smart_copy -RL "${PKG_BASEDIR}.flatten" "${PKG_BASEDIR}" + rm -rf "${PKG_BASEDIR}.flatten" ;; esac + + dedupe_dir "${PKG_BASEDIR}" >/dev/null + + log STATUS "Packaging ${PKG_BASEDIR}" + + tar -cvJf "${PKG_BASEDIR}.tar.xz" "${PKG_BASEDIR}" } build_wipe() { @@ -1298,22 +1422,41 @@ common_setup() { "common_setup_${1}" common_setup_arch - DOWNLOAD_DIR="${WORK_DIR}/download_cache" - PKG_BASEDIR="${PLATFORM}_${DEPS_VERSION}" - BUILD_BASEDIR="build-${PKG_BASEDIR}" - BUILD_DIR="${WORK_DIR}/${BUILD_BASEDIR}" - PREFIX="${BUILD_DIR}/prefix" - PATH="${PREFIX}/bin:${PATH}" + PLATFORM_SYSTEM="$(echo "${PLATFORM}" | cut -f1 -d-)" + PLATFORM_ARCH="$(echo "${PLATFORM}" | cut -f2 -d-)" + PLATFORM_COMPILER="$(echo "${PLATFORM}" | cut -f3 -d-)" + PLATFORM_TARGET="${PLATFORM_SYSTEM}-${PLATFORM_ARCH}" + + if "${GLOBAL_SETUP_ONCE:-true}" + then + DOWNLOAD_DIR="${WORK_DIR}/download_cache" + PKG_BASEDIR="${PLATFORM}_${DEPS_VERSION}" + BUILD_BASEDIR="build-${PKG_BASEDIR}" + BUILD_DIR="${WORK_DIR}/${BUILD_BASEDIR}" + PREFIX="${BUILD_DIR}/prefix" + NATIVE_PREFIX="${BUILD_DIR}/native-prefix" + + mkdir -p "${DOWNLOAD_DIR}" + mkdir -p "${PREFIX}/bin" + mkdir -p "${PREFIX}/include" + mkdir -p "${PREFIX}/lib" + mkdir -p "${NATIVE_PREFIX}/bin" + mkdir -p "${NATIVE_PREFIX}/include" + mkdir -p "${NATIVE_PREFIX}/lib" + + PATH="${NATIVE_PREFIX}/bin:${PATH}" + + GLOBAL_SETUP_ONCE='false' + fi + PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig:${CROSS_PKG_CONFIG_PATH}" CPPFLAGS+=" -I${PREFIX}/include" LDFLAGS+=" -L${PREFIX}/lib" - mkdir -p "${DOWNLOAD_DIR}" - mkdir -p "${PREFIX}/bin" - mkdir -p "${PREFIX}/include" - mkdir -p "${PREFIX}/lib" - - export CC CXX LD AR RANLIB STRIP PKG_CONFIG PKG_CONFIG_PATH PATH CFLAGS CXXFLAGS CPPFLAGS LDFLAGS + export PATH + export PKG_CONFIG PKG_CONFIG_PATH + export CC CXX LD AR RANLIB STRIP + export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS } common_setup_arch() { @@ -1334,6 +1477,8 @@ common_setup_arch() { CFLAGS+=' -march=armv7-a -mfpu=neon' CXXFLAGS+=' -march=armv7-a -mfpu=neon' ;; + native-native-native) + ;; *) log ERROR 'Unsupported platform' ;; @@ -1355,6 +1500,7 @@ common_setup_windows() { RANLIB="${HOST}-ranlib" CFLAGS+=' -D__USE_MINGW_ANSI_STDIO=0' CMAKE_TOOLCHAIN="${SCRIPT_DIR}/../cmake/cross-toolchain-mingw${BITNESS}.cmake" + EXE_EXT='.exe' } common_setup_msvc() { @@ -1376,10 +1522,9 @@ common_setup_macos() { CC='clang' CXX='clang++' STRIP='strip' - CFLAGS+=" -arch ${MACOS_ARCH}" - CXXFLAGS+=" -arch ${MACOS_ARCH}" - LDFLAGS+=" -arch ${MACOS_ARCH}" - export CMAKE_OSX_ARCHITECTURES="${MACOS_ARCH}" + CFLAGS+=" -arch ${MACOS_ARCH} -mmacosx-version-min=${MACOS_VERSION}" + CXXFLAGS+=" -arch ${MACOS_ARCH} -mmacosx-version-min=${MACOS_VERSION}" + LDFLAGS+=" -arch ${MACOS_ARCH} -mmacosx-version-min=${MACOS_VERSION}" } common_setup_linux() { @@ -1391,8 +1536,50 @@ common_setup_linux() { CXXFLAGS+=' -fPIC' } +common_setup_native() { + case "$(uname -s)" in + CYGWIN_NT-*|MSYS_NT-*|MINGW*_NT-*) + EXE_EXT='.exe' + ;; + esac +} + +setup_default() { + # Require the compiler names to be explicitly hardcoded, we should not inherit them + # from environment as we heavily cross-compile. + export CC='false' + export CXX='false' + + # Set defaults. + export LD='ld' + export AR='ar' + export RANLIB='ranlib' + export STRIP='strip' + export PKG_CONFIG='pkg-config' + export CROSS_PKG_CONFIG_PATH='' + + LIBS_SHARED='OFF' + LIBS_STATIC='ON' + + EXE_EXT='' + + # Always reset flags, we heavily cross-compile and must not inherit any stray flag + # from environment. + export CPPFLAGS='' + export CFLAGS='-O3 -fPIC' + export CXXFLAGS='-O3 -fPIC' + export LDFLAGS='-O3 -fPIC' + + unset BITNESS + unset MACOS_ARCH + unset MACOS_VERSION + unset MACOS_HOST + unset CMAKE_TOOLCHAIN +} + # Set up environment for 32-bit i686 Windows for Visual Studio (compile all as .dll) setup_windows-i686-msvc() { + setup_default BITNESS=32 CFLAGS+=' -mpreferred-stack-boundary=2' CXXFLAGS+=' -mpreferred-stack-boundary=2' @@ -1401,80 +1588,125 @@ setup_windows-i686-msvc() { # Set up environment for 64-bit amd64 Windows for Visual Studio (compile all as .dll) setup_windows-amd64-msvc() { + setup_default BITNESS=64 common_setup msvc x86_64-w64-mingw32 } # Set up environment for 32-bit i686 Windows for MinGW (compile all as .a) setup_windows-i686-mingw() { + setup_default BITNESS=32 common_setup mingw i686-w64-mingw32 } # Set up environment for 64-bit amd64 Windows for MinGW (compile all as .a) setup_windows-amd64-mingw() { + setup_default BITNESS=64 common_setup mingw x86_64-w64-mingw32 } +setup_macos() { + MACOS_HOST="${MACOS_ARCH}-apple-macos${MACOS_VERSION}" + common_setup macos "${MACOS_HOST}" +} + # Set up environment for 64-bit amd64 macOS setup_macos-amd64-default() { - MACOS_ARCH=x86_64 + setup_default + MACOS_ARCH='x86_64' # OpenAL requires 10.14. - export MACOSX_DEPLOYMENT_TARGET=10.14 # works with CMake - common_setup macos "x86_64-apple-macos${MACOSX_DEPLOYMENT_TARGET}" + MACOS_VERSION='10.14' + setup_macos +} + +# Set up environment for 64-bit arm64 macOS +setup_macos-arm64-default() { + setup_default + MACOS_ARCH='arm64' + MACOS_VERSION='11.7' + setup_macos } # Set up environment for 32-bit i686 Linux setup_linux-i686-default() { + setup_default common_setup linux i686-unknown-linux-gnu } # Set up environment for 64-bit amd64 Linux setup_linux-amd64-default() { + setup_default common_setup linux x86_64-unknown-linux-gnu } # Set up environment for 32-bit armhf Linux setup_linux-armhf-default() { + setup_default common_setup linux arm-unknown-linux-gnueabihf } # Set up environment for 64-bit arm Linux setup_linux-arm64-default() { + setup_default common_setup linux aarch64-unknown-linux-gnu } -base_windows_amd64_msvc_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck genlib' -all_windows_amd64_msvc_packages="${base_windows_amd64_msvc_packages}" +# Set up environment for native host tools +setup_native() { + setup_default + CC='cc' + CXX='c++' + common_setup native native +} -base_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" -all_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" +setup_platform() { + case "${1}" in + 'native') + export PLATFORM='native-native-native' + setup_native + ;; + *) + export PLATFORM="${1}" + "setup_${PLATFORM}" + ;; + esac +} -base_windows_amd64_mingw_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck' +base_windows_amd64_mingw_packages='native-jwasm zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk saigosdk naclruntime depcheck' all_windows_amd64_mingw_packages="${base_windows_amd64_mingw_packages}" base_windows_i686_mingw_packages="${base_windows_amd64_mingw_packages}" all_windows_i686_mingw_packages="${base_windows_amd64_mingw_packages}" -base_macos_amd64_default_packages='pkgconfig nasm gmp nettle sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk' +base_windows_amd64_msvc_packages="${base_windows_amd64_mingw_packages} genlib" +all_windows_amd64_msvc_packages="${base_windows_amd64_msvc_packages}" + +base_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" +all_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" + +base_macos_arm64_default_packages='native-pkgconfig gmp nettle sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk saigosdk naclruntime' +all_macos_arm64_default_packages="${base_macos_arm64_default_packages}" + +base_macos_amd64_default_packages="native-nasm ${base_macos_arm64_default_packages}" all_macos_amd64_default_packages="${base_macos_amd64_default_packages}" -base_linux_i686_default_packages='sdl3 naclsdk' -all_linux_i686_default_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' +base_linux_amd64_default_packages='sdl3 naclsdk saigosdk naclruntime' +all_linux_amd64_default_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk saigosdk naclruntime' -base_linux_amd64_default_packages="${base_linux_i686_default_packages} naclruntime" -all_linux_amd64_default_packages="${all_linux_i686_default_packages} naclruntime" +base_linux_i686_default_packages="${base_linux_amd64_default_packages}" +all_linux_i686_default_packages="${all_linux_amd64_default_packages}" -base_linux_arm64_default_packages='sdl3 naclsdk' -all_linux_arm64_default_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile ncurses naclsdk' +base_linux_arm64_default_packages="${base_linux_amd64_default_packages}" +all_linux_arm64_default_packages="${all_linux_amd64_default_packages}" -base_linux_armhf_default_packages="${base_linux_arm64_default_packages}" -all_linux_armhf_default_packages="${all_linux_arm64_default_packages}" +base_linux_armhf_default_packages="${base_linux_amd64_default_packages}" +all_linux_armhf_default_packages="${all_linux_amd64_default_packages}" all_linux_platforms='linux-amd64-default linux-arm64-default linux-armhf-default linux-i686-default' all_windows_platforms='windows-amd64-mingw windows-amd64-msvc windows-i686-mingw windows-i686-msvc' -all_macos_platforms='macos-amd64-default' +all_macos_platforms='macos-amd64-default macos-arm64-default' all_platforms="${all_linux_platforms} ${all_windows_platforms} ${all_macos_platforms}" printHelp() { @@ -1498,7 +1730,7 @@ printHelp() { all linux windows macos Packages: - pkgconfig nasm zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk wasisdk wasmtime + native-pkgconfig native-nasm native-jwasm zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk saigosdk naclruntime wasisdk wasmtime Virtual packages: base build packages for pre-built binaries to be downloaded when building the game @@ -1523,18 +1755,16 @@ printHelp() { base ${base_macos_amd64_default_packages} all same - linux-amd64-default: - base ${base_linux_amd64_default_packages} - all ${all_linux_amd64_default_packages} + macos-arm64-default: + base ${base_macos_arm64_default_packages} + all same + linux-amd64-default: linux-i686-default: - base ${base_linux_i686_default_packages} - all ${all_linux_i686_default_packages} - linux-arm64-default: linux-armhf-default: - base ${base_linux_arm64_default_packages} - all ${all_linux_arm64_default_packages} + base ${base_linux_amd64_default_packages} + all ${all_linux_amd64_default_packages} EOF @@ -1630,6 +1860,6 @@ esac for PLATFORM in ${platform_list} do ( - "setup_${PLATFORM}" + setup_platform "${PLATFORM}" build "${@}" ) done diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index df2739b9f3..f6c43ffd5c 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -75,6 +75,19 @@ static Cvar::Cvar workaround_naclSystem_freebsd_disableQualification( "Disable platform qualification when running Linux NaCl loader on FreeBSD through Linuxulator", Cvar::NONE, true); +#if defined(DAEMON_NACL_BOX64_EMULATION) +#if defined(__linux__) || defined(__FreeBSD__) +#else +#error box64 is only supported on Linux or systems with a Linux compatibility layer +#endif // defined(__linux__) || defined(__FreeBSD__) +#endif // defined(DAEMON_NACL_BOX64_EMULATION)⏎ + +// Many BSDs have a Linuxulator, for now we only tested one. +#if defined(__FreeBSD__) +#define DAEMON_LINUXULATOR +#endif + +#if defined(DAEMON_NACL_RUNTIME_ENABLED) #if defined(DAEMON_NACL_BOX64_EMULATION) static Cvar::Cvar workaround_box64_disableQualification( "workaround.box64.disableQualification", @@ -121,34 +134,43 @@ static std::string ResolveBox64Path() { "Install Box64 or set vm.box64.path to the full path of the box64 binary."); return ""; // unreachable } -#endif - -static Cvar::Cvar vm_nacl_qualification( - "vm.nacl.qualification", - "Enable NaCl loader platform qualification", - Cvar::INIT, true); - -static Cvar::Cvar vm_nacl_bootstrap( - "vm.nacl.bootstrap", - "Use NaCl bootstrap helper", - Cvar::INIT, true); - -static Cvar::Cvar vm_timeout( - "vm.timeout", - "Receive timeout in seconds", - Cvar::NONE, 2); +#endif // DAEMON_NACL_BOX64_EMULATION +#endif // DAEMON_NACL_RUNTIME_ENABLED #if defined(DAEMON_NACL_RUNTIME_ENABLED) static Cvar::Cvar vm_nacl_available( "vm.nacl.available", "Whether NaCl runtime is available on this platform", Cvar::ROM, true); -#else +#else // !defined(DAEMON_NACL_RUNTIME_ENABLED) static Cvar::Cvar vm_nacl_available( "vm.nacl.available", "Whether NaCl runtime is available on this platform", Cvar::ROM, false); -#endif +#endif // !defined(DAEMON_NACL_RUNTIME_ENABLED) + +#if defined(DAEMON_NACL_RUNTIME_ENABLED) +static Cvar::Cvar vm_timeout( + "vm.timeout", + "Receive timeout in seconds", + Cvar::NONE, 2); + +static Cvar::Cvar vm_nacl_qualification( + "vm.nacl.qualification", + "Enable NaCl loader platform qualification", + Cvar::INIT, true); + +#if defined(__linux__) || defined(DAEMON_LINUXULATOR) +#define DAEMON_NACL_BOOSTRAP_ENABLED +#endif // defined(__linux__) || defined(DAEMON_LINUXULATOR) + +#if defined(DAEMON_NACL_BOOSTRAP_ENABLED) +static Cvar::Cvar vm_nacl_bootstrap( + "vm.nacl.bootstrap", + "Use NaCl bootstrap helper", + Cvar::INIT, true); +#endif // defined(DAEMON_NACL_BOOSTRAP_ENABLED) +#endif // defined(DAEMON_NACL_RUNTIME_ENABLED) namespace VM { @@ -300,36 +322,116 @@ static std::pair InternalLoadModule(std::pair CreateNaClVM(std::pair pair, Str::StringRef name, bool debug, bool extract, int debugLoader) { CheckMinAddressSysctlTooLarge(); const std::string& libPath = FS::GetLibPath(); -#ifdef DAEMON_NACL_RUNTIME_PATH +#if defined(DAEMON_NACL_RUNTIME_PATH) const char* naclPath = DAEMON_NACL_RUNTIME_PATH_STRING; -#else +#else // !defined(DAEMON_NACL_RUNTIME_PATH) const std::string& naclPath = libPath; -#endif +#endif // !defined(DAEMON_NACL_RUNTIME_PATH) std::vector args; char rootSocketRedir[32]; - std::string module, nacl_loader, irt, bootstrap, modulePath, verbosity; + std::string module, nacl_loader, irt, arch, bootstrap, modulePath, verbosity; FS::File stderrRedirect; + + bool inheritEnvironment = false; + +#if defined(__linux__) || defined(DAEMON_LINUXULATOR) + constexpr bool hasBootstrap = true; + #if defined(DAEMON_NACL_BOX64_EMULATION) - std::string box64Path; - bool usingBox64 = false; -#endif + constexpr bool hasBox64 = true; +#else // !defined(DAEMON_NACL_BOX64_EMULATION) + constexpr bool hasBox64 = false; +#endif // !defined(DAEMON_NACL_BOX64_EMULATION) + +#if defined(YOKAI_ARCH_ARM64) + constexpr bool hasLdArmhf = true; +#else // !defined(YOKAI_ARCH_ARM64) + constexpr bool hasLdArmhf = false; +#endif // !defined(YOKAI_ARCH_ARM64) +#else // !( defined(__linux__) || defined(DAEMON_LINUXULATOR) ) + + Q_UNUSED(bootstrap); + constexpr bool hasBootstrap = false; + constexpr bool hasBox64 = false; + constexpr bool hasLdArmhf = false; +#endif // !( defined(__linux__) || defined(DAEMON_LINUXULATOR) ) + #if !defined(_WIN32) || defined(_WIN64) - constexpr bool win32Force64Bit = false; -#else + constexpr bool i686ForceAmd64 = false; +#else // !( !defined(_WIN32) || defined(_WIN64) ) // On Windows, even if we are running a 32-bit engine, we must use the // 64-bit nacl_loader if the host operating system is 64-bit. SYSTEM_INFO systemInfo; GetNativeSystemInfo(&systemInfo); - const bool win32Force64Bit = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; -#endif + constexpr bool i686ForceAmd64 = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; +#endif // !( !defined(_WIN32) || defined(_WIN64) ) + + /* When we will have implemented box64 integration for arm64, and once we + will have implemented the detection of armhf support being provided, we + will be able to turn this boolean on based on such detection. */ + bool arm64ForceBox64 = false; + + bool useBox64 = hasBox64; + bool useLdArmhf = hasLdArmhf; + + if (hasBox64 && hasLdArmhf) { + if (arm64ForceBox64) { + useLdArmhf = false; + useBox64 = true; + } + else { + useLdArmhf = true; + useBox64 = false; + } + } + + bool useBootstrap = hasBootstrap; + +#if defined(DAEMON_NACL_BOOSTRAP_ENABLED) + if (hasBootstrap) { + if (!vm_nacl_bootstrap.Get()) { + useBootstrap = false; + } + +#if defined(DAEMON_NACL_BOX64_EMULATION) + /* Use Box64 to run the x86_64 NaCl loader on non-x86 architectures. + The bootstrap helper uses a double-exec pattern that Box64 cannot handle, + so we skip it and prepend "box64" to the nacl_loader command instead. */ + if (workaround_box64_disableBootstrap.Get()) { + useBootstrap = false; + } +#endif // defined(DAEMON_NACL_BOX64_EMULATION) + } +#endif // defined(DAEMON_NACL_BOOSTRAP_ENABLED) + + if (useLdArmhf) { + arch = "armhf"; + } + else if (useBox64 || i686ForceAmd64) { + arch = "amd64"; + } + else { + arch = DAEMON_NACL_ARCH_STRING; + } + + module = Str::Format("%s-%s.nexe", name, arch); + irt = FS::Path::Build(naclPath, Str::Format("irt_core-%s.nexe", arch)); + nacl_loader = FS::Path::Build(naclPath, Str::Format("nacl_loader-%s%s", arch, EXE_EXT)); + + if (useBootstrap) { + if (useLdArmhf) { + bootstrap = FS::Path::Build(naclPath, Str::Format("nacl_helper_bootstrap-ldarmhf")); + } + else { + bootstrap = FS::Path::Build(naclPath, Str::Format("nacl_helper_bootstrap-%s", arch)); + } + } // Extract the nexe from the pak so that nacl_loader can load it - module = win32Force64Bit - ? name + "-amd64.nexe" - : Str::Format("%s-%s.nexe", name, DAEMON_NACL_ARCH_STRING); if (extract) { try { FS::File out = FS::HomePath::OpenWrite(module); @@ -347,10 +449,6 @@ static std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNativeVM(std::pair pair, Str::StringRef name, bool debug) { const std::string& libPath = FS::GetLibPath(); @@ -622,7 +693,9 @@ void VMBase::Create() } #endif if (type == TYPE_NACL || type == TYPE_NACL_LIBPATH) { +#if defined(DAEMON_NACL_RUNTIME_ENABLED) std::tie(processHandle, rootSocket) = CreateNaClVM(std::move(pair), name, params.debug.Get(), type == TYPE_NACL, params.debugLoader.Get()); +#endif // defined(DAEMON_NACL_RUNTIME_ENABLED) } else if (type == TYPE_NATIVE_EXE) { std::tie(processHandle, rootSocket) = CreateNativeVM(std::move(pair), name, params.debug.Get()); } else { diff --git a/tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp b/tools/nacl_helper_bootstrap-ldarmhf/nacl_helper_bootstrap-ldarmhf.cpp similarity index 94% rename from tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp rename to tools/nacl_helper_bootstrap-ldarmhf/nacl_helper_bootstrap-ldarmhf.cpp index ec16447482..cd1f0a4a46 100644 --- a/tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp +++ b/tools/nacl_helper_bootstrap-ldarmhf/nacl_helper_bootstrap-ldarmhf.cpp @@ -50,13 +50,13 @@ int main(int argc, char *argv[]) { return err; } - char *helper = strdup("./nacl_helper_bootstrap"); + char *helper = strdup("./nacl_helper_bootstrap-armhf"); argv[0] = helper; execv(helper, argv); // The execv() function returns only if an error has occurred. - printf("nacl_helper_bootstrap-armhf: %s\n", strerror(errno)); + printf("nacl_helper_bootstrap-ldarmhf: %s\n", strerror(errno)); return 1; }