diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f4a215413..3001fc4f4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,15 @@ if (Daemon_OUT) endif() include(Yokai/All) -include(DaemonNaclHost) + +if (NOT YOKAI_TARGET_SYSTEM_NACL) + include(DaemonNaclArchitecture) + + daemon_detect_nacl_arch("${YOKAI_TARGET_ARCH_NAME}") + + # Add printable strings to the executable. + yokai_add_buildinfo("char*" "DAEMON_NACL_ARCH_STRING" "\"${DAEMON_NACL_ARCH_NAME}\"") +endif() ################################################################################ # Configuration options @@ -141,7 +149,6 @@ set(DEFAULT_NACL_VM_INHERITED_OPTIONS BUILD_CGAME BUILD_SGAME CMAKE_BUILD_TYPE - DAEMON_CBSE_PYTHON_PATH USE_ARCH_INTRINSICS USE_COMPILER_CUSTOMIZATION USE_COMPILER_INTRINSICS @@ -190,7 +197,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 +227,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) @@ -291,6 +288,7 @@ endif() # meaning we have to detect useless engine compiler to set # useless engine flags when only building vms. include(DaemonFlags) +include(DaemonNaclFlags) # FIXME: Once engine flags would be only set when building the engine # this would be likely unused by vms as they are built by DaemonGame. @@ -462,7 +460,6 @@ endif() # LIBS_BASE, LIBS_ENGINE_BASE LIBS_ENGINE, LIBS_BASECLIENT, LIBS_CLIENT # Native client -include(DaemonNacl) if (YOKAI_TARGET_SYSTEM_NACL) add_library(srclibs-nacl-module EXCLUDE_FROM_ALL ${NACLLIST_MODULE}) set(LIBS_BASE ${LIBS_BASE} srclibs-nacl-module) @@ -483,16 +480,6 @@ elseif (YOKAI_TARGET_SYSTEM_NACL) find_library(NACL_EXCEPTION nacl_exception) find_library(NACL_MINIDUMP minidump_generator) - # HACK: To be removed when Saigo is repackaged properly. - if (NOT NACL_MINIDUMP - # NACL_TARGET is specific to Saigo, PNaCl target is le32 and doesn't set NACL_TARGET. - AND "${NACL_TARGET}" STREQUAL "i686" - # x86_64-nacl/lib32 is specific to Google build, other builds may provide i686-nacl/lib instead. - AND EXISTS "${DEPS_DIR}/saigo_newlib/x86_64-nacl/lib32") - set(NACL_EXCEPTION "${DEPS_DIR}/saigo_newlib/x86_64-nacl/lib32/libnacl_exception.a") - set(NACL_MINIDUMP "${DEPS_DIR}/saigo_newlib/x86_64-nacl/lib32/libminidump_generator.a") - endif() - set(LIBS_BASE ${LIBS_BASE} ${NACL_MINIDUMP} ${NACL_EXCEPTION}) else() find_library(LIBM m) @@ -970,56 +957,58 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER add_custom_target(runtime_deps) set_target_properties(runtime_deps PROPERTIES FOLDER "CMakePlumbing") - # 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} - ) + foreach(arch_name IN LISTS DAEMON_NACL_ARCH_NAME_LIST) + # 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-${arch_name}${CMAKE_EXECUTABLE_SUFFIX} + ${FULL_OUTPUT_DIR}/nacl_loader-${arch_name}${CMAKE_EXECUTABLE_SUFFIX} + ) - add_custom_command(TARGET runtime_deps PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/irt_core-${DAEMON_NACL_ARCH_NAME}.nexe - ${FULL_OUTPUT_DIR}/irt_core-${DAEMON_NACL_ARCH_NAME}.nexe - ) + add_custom_command(TARGET runtime_deps PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${DEPS_DIR}/irt_core-${arch_name}.nexe + ${FULL_OUTPUT_DIR}/irt_core-${arch_name}.nexe + ) + endforeach() # 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) + if (DAEMON_NACL_MULTIARCH) + add_executable(nacl_multiarch-${DAEMON_NACL_ARCH_NAME} + tools/nacl_multiarch/nacl_multiarch.cpp + ${BUILDINFOLIST} + ) + add_dependencies(runtime_deps nacl_multiarch-${DAEMON_NACL_ARCH_NAME}) + + add_custom_command(TARGET runtime_deps PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${DEPS_DIR}/libs-linux-armhf + ${FULL_OUTPUT_DIR}/libs-linux-armhf + ) + endif() + foreach(arch_name IN LISTS DAEMON_NACL_ARCH_NAME_LIST) add_custom_command(TARGET runtime_deps PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory - ${FULL_OUTPUT_DIR}/lib-armhf + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${DEPS_DIR}/nacl_helper_bootstrap-${arch_name} + ${FULL_OUTPUT_DIR}/nacl_helper_bootstrap-${arch_name} + ) + endforeach() + + if (DAEMON_NACL_BOX64_EMULATION) + add_custom_command(TARGET runtime_deps PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${DEPS_DIR}/box64 + ${FULL_OUTPUT_DIR}/box64 ) add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory - ${DEPS_DIR}/lib-armhf - ${FULL_OUTPUT_DIR}/lib-armhf + ${DEPS_DIR}/libs-linux-amd64 + ${FULL_OUTPUT_DIR}/libs-linux-amd64 ) endif() - - 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 - ) - endif() - - # Win32 requires nacl_loader_amd64.exe in order to run on Win64 - if (YOKAI_TARGET_SYSTEM_WINDOWS AND YOKAI_TARGET_ARCH_I686) - add_custom_command(TARGET runtime_deps PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/nacl_loader-amd64${CMAKE_EXECUTABLE_SUFFIX} - ${FULL_OUTPUT_DIR}/nacl_loader-amd64${CMAKE_EXECUTABLE_SUFFIX} - ) - add_custom_command(TARGET runtime_deps PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/irt_core-amd64.nexe - ${FULL_OUTPUT_DIR}/irt_core-amd64.nexe - ) endif() # Mac requires some libraries from external_deps 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/DaemonCBSE.cmake b/cmake/DaemonCBSE.cmake deleted file mode 100644 index 63019ace38..0000000000 --- a/cmake/DaemonCBSE.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# Daemon BSD Source Code -# Copyright (c) 2013-2016, Daemon Developers -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the Daemon developers nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Allow overriding the python path with a cached variable. -set(DAEMON_CBSE_PYTHON_PATH "NOTFOUND" CACHE FILEPATH "Python executable for CBSE code generation") -if (NOT DAEMON_CBSE_PYTHON_PATH OR NOT EXISTS ${DAEMON_CBSE_PYTHON_PATH}) - find_package(Python REQUIRED) - set(DAEMON_CBSE_PYTHON_PATH "${Python_EXECUTABLE}" CACHE FILEPATH "Python executable for CBSE code generation" FORCE) -endif() -message(STATUS "Using CBSE Python executable: ${DAEMON_CBSE_PYTHON_PATH}") - -function(maybe_add_dep target dep) - if (TARGET ${target}) - add_dependencies(${target} ${dep}) - endif() -endfunction() - -function(CBSE target definition output) - # Check if python has all the dependencies - # TODO: Execute pip directly here and install them - execute_process( - COMMAND ${DAEMON_CBSE_PYTHON_PATH} -c "import jinja2, yaml, collections, argparse, sys, os.path, re" - RESULT_VARIABLE RET) - if (NOT RET EQUAL 0) - message(FATAL_ERROR "Missing dependences for CBSE generation. Please ensure you have python with python-yaml and python-jinja installed. - Use pip install -r src/utils/cbse/requirements.txt to install") - endif() - set(GENERATED_CBSE ${output}/backend/CBSEBackend.cpp - ${output}/backend/CBSEBackend.h - ${output}/backend/CBSEComponents.h - ${output}/backend/CBSEEntities.h) - add_custom_command( - OUTPUT ${GENERATED_CBSE} - COMMENT "Generating CBSE entities for ${definition}" - DEPENDS ${definition} - ${CMAKE_SOURCE_DIR}/src/utils/cbse/CBSE.py - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Backend.cpp - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Backend.h - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Component.cpp - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Component.h - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Components.h - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Entities.h - ${CMAKE_SOURCE_DIR}/src/utils/cbse/templates/Helper.h - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/utils/cbse - COMMAND - ${DAEMON_CBSE_PYTHON_PATH} - ${CMAKE_SOURCE_DIR}/src/utils/cbse/CBSE.py - -s -o - "${output}" - "${definition}" - ) - string(REPLACE ${CMAKE_SOURCE_DIR}/ "" rel_path ${definition}) - string(REPLACE "/" "-" new_target ${rel_path}) - add_custom_target(${new_target} ALL - DEPENDS ${GENERATED_CBSE} - ) - set(${target}_GENERATED_CBSE ${GENERATED_CBSE} PARENT_SCOPE) -endfunction() diff --git a/cmake/DaemonFlags.cmake b/cmake/DaemonFlags.cmake index 96d142f47e..74009547ac 100644 --- a/cmake/DaemonFlags.cmake +++ b/cmake/DaemonFlags.cmake @@ -260,10 +260,14 @@ if (USE_FLOAT_EXCEPTIONS) add_definitions(-DDAEMON_USE_FLOAT_EXCEPTIONS) endif() -if (NOT NACL AND BUILD_CLIENT) +if (NOT YOKAI_TARGET_SYSTEM_NACL AND BUILD_CLIENT) option(USE_OPENMP "Use OpenMP to parallelize some tasks" OFF) endif() +if (NOT YOKAI_TARGET_SYSTEM_NACL AND BUILD_CLIENT AND USE_OPENMP) + set(ENABLE_OPENMP ON) +endif() + if (YOKAI_CXX_COMPILER_MSVC_COMPATIBILITY) if (YOKAI_CXX_COMPILER_MSVC) # /MP doesn't do anything and prints a warning in the Clang clone. @@ -275,7 +279,7 @@ if (YOKAI_CXX_COMPILER_MSVC_COMPATIBILITY) set_cxx_flag("/std:c++23preview") endif() - if (NOT NACL AND BUILD_CLIENT AND USE_OPENMP) + if (ENABLE_OPENMP) # Flag checks doen't work with MSVC so we assume it's there. set(OPENMP_COMPILE_FLAG "/openmp") endif() @@ -375,7 +379,7 @@ else() endif() endif() - if (NOT NACL AND BUILD_CLIENT AND USE_OPENMP) + if (ENABLE_OPENMP) check_CXX_compiler_flag("-fopenmp" FLAG_FOPENMP) if (FLAG_FOPENMP) @@ -386,7 +390,7 @@ else() endif() endif() - if (YOKAI_TARGET_SYSTEM_NACL AND USE_NACL_SAIGO AND DAEMON_NACL_ARCH_ARMHF) + if (YOKAI_TARGET_SYSTEM_NACL AND YOKAI_CXX_COMPILER_SAIGO AND YOKAI_TARGET_ARCH_ARMHF) # Saigo produces broken arm builds when optimizing them. # See: https://github.com/Unvanquished/Unvanquished/issues/3297 # When setting this clang-specific option, we don't have to care @@ -435,7 +439,7 @@ else() try_flag(WARNINGS "-Werror") endif() - if (YOKAI_TARGET_SYSTEM_NACL AND NOT USE_NACL_SAIGO) + if (YOKAI_TARGET_SYSTEM_NACL AND YOKAI_CXX_COMPILER_PNACL) # PNaCl only supports libc++ as standard library. set_c_cxx_flag("-stdlib=libc++") set_c_cxx_flag("--pnacl-allow-exceptions") @@ -498,7 +502,7 @@ else() # Don't set _FORTIFY_SOURCE in debug builds. endif() - if (NOT NACL) + if (NOT YOKAI_TARGET_SYSTEM_NACL) # Saigo reports weird errors when building some cgame and sgame arm nexe with PIC: # > error: Cannot represent a difference across sections # > error: expected relocatable expression @@ -742,7 +746,7 @@ if (YOKAI_TARGET_SYSTEM_MACOS) endif() # Glibc-specific definitions -if (LINUX) +if (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY) # QUIRK: It does nothing when it is not needed on non-glibc Linux # systems so it's harmless to always set it. add_definitions(-D_FILE_OFFSET_BITS=64) diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index f6adde3c7c..b253603682 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -44,9 +44,9 @@ include(Yokai/All) # Do not report unused native compiler if native vms are not built. # If only NACL vms are built, this will be reported in chainloaded build. -if (BUILD_GAME_NATIVE_DLL OR BUILD_GAME_NATIVE_EXE OR NACL) - include(DaemonNacl) +if (BUILD_GAME_NATIVE_DLL OR BUILD_GAME_NATIVE_EXE OR GAME_BUILD_SUBINVOCATION) include(DaemonFlags) + include(DaemonNaclFlags) endif() # Source lists for src/shared @@ -68,39 +68,59 @@ set(SHAREDLIST_sgame # Function to setup all the Sgame/Cgame libraries include(CMakeParseArguments) -# The NaCl SDK only runs on amd64 or i686. -if (NOT FORK EQUAL 2) - if (CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME +list(APPEND NACL_ALL_TARGETS "amd64" "i686" "armhf") + +if (NOT GAME_BUILD_SUBINVOCATION) + option(USE_NACL_SAIGO "Use the Saigo toolchain to build NaCl executables" ON) + + if (USE_NACL_SAIGO) + set(HAS_NACL_SDK ON) + elseif (CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME AND (YOKAI_TARGET_ARCH_AMD64 OR YOKAI_TARGET_ARCH_I686)) + # The PNaCl SDK only runs on amd64 or i686. + set(HAS_NACL_SDK ON) + endif() + + if (HAS_NACL_SDK) + include(DaemonNaclArchitecture) + # can be loaded by daemon with vm.[sc]game.type 0 or 1 option(BUILD_GAME_NACL "Build the NaCl \"pexe\" and \"nexe\" gamelogic modules for enabled architecture targets, required to host mods." OFF) - set(NACL_ALL_TARGETS "amd64;i686;armhf") - set(BUILD_GAME_NACL_TARGETS "all" CACHE STRING "Enabled NaCl \"nexe\" architecture targets, values: ${NACL_ALL_TARGETS}, all, native, none.") + set(BUILD_GAME_NACL_TARGETS "all" CACHE STRING "Enabled NaCl \"nexe\" architecture targets, values: ${NACL_ALL_TARGETS};all;native;none") mark_as_advanced(BUILD_GAME_NACL_TARGETS) - if (BUILD_GAME_NACL_TARGETS STREQUAL "all") - set(NACL_TARGETS "${NACL_ALL_TARGETS}") - elseif (BUILD_GAME_NACL_TARGETS STREQUAL "native") - set(NACL_TARGETS "${YOKAI_TARGET_ARCH_NAME}") - elseif (BUILD_GAME_NACL_TARGETS STREQUAL "none") - set(NACL_TARGETS "") - else() - set(NACL_TARGETS "${BUILD_GAME_NACL_TARGETS}") - endif() + if (BUILD_GAME_NACL) + foreach(nacl_target ${BUILD_GAME_NACL_TARGETS}) + if (BUILD_GAME_NACL_TARGETS STREQUAL "all") + list(APPEND nacl_target_list ${NACL_ALL_TARGETS}) + elseif (BUILD_GAME_NACL_TARGETS STREQUAL "native") + list(APPEND nacl_target_list "${YOKAI_TARGET_ARCH_NAME}") + elseif (BUILD_GAME_NACL_TARGETS STREQUAL "none") + set(nacl_target_list "") + else() + list(APPEND nacl_target_list "${nacl_target}") + endif() + endforeach() + + foreach(nacl_target IN LISTS nacl_target_list) + daemon_detect_nacl_arch("${nacl_target}") + + foreach(detected_target IN LISTS ${DAEMON_NACL_ARCH_NAME_LIST}) + if (NOT "${detected_target}" IN_LIST NACL_TARGETS) + list(APPEND NACL_TARGETS ${detected_target}) + endif() + endforeach() + endforeach() - foreach(NACL_TARGET ${NACL_TARGETS}) - set(IS_NACL_VALID_TARGET OFF) - foreach(NACL_VALID_TARGET ${NACL_ALL_TARGETS}) - if(NACL_TARGET STREQUAL NACL_VALID_TARGET) - set(IS_NACL_VALID_TARGET ON) + foreach(nacl_target IN LISTS NACL_TARGETS) + if (NOT nacl_target IN_LIST NACL_ALL_TARGETS) + message(FATAL_ERROR "Invalid NaCl target ${nacl_target}, must be one of ${NACL_ALL_TARGETS}") endif() endforeach() - if (NOT IS_NACL_VALID_TARGET) - message(FATAL_ERROR "Invalid NaCl target ${NACL_TARGET}, must be one of ${NACL_ALL_TARGETS}") - endif() - endforeach() + message(STATUS "Building NaCl targets: ${NACL_TARGETS}") + endif() else() set(BUILD_GAME_NACL OFF) set(NACL_TARGETS "") @@ -134,7 +154,7 @@ function(buildGameModule module_slug) if (module_slug STREQUAL "nacl") set_target_properties(${module_target} PROPERTIES OUTPUT_NAME "${GAMEMODULE_NAME}" - SUFFIX "${PLATFORM_EXE_SUFFIX}") + SUFFIX "${NACL_EXECUTABLE_SUFFIX}") target_link_libraries(${module_target} ${GAMEMODULE_LIBS} ${LIBS_BASE}) else() @@ -150,13 +170,13 @@ function(gameSubProject) BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NACL_VMS_PROJECT} CMAKE_GENERATOR ${VM_GENERATOR} CMAKE_ARGS - -DFORK=2 - -DDAEMON_DIR=${Daemon_SOURCE_DIR} - -DDEPS_DIR=${DEPS_DIR} + "-DDAEMON_DIR=${Daemon_SOURCE_DIR}" + "-DDEPS_DIR=${DEPS_DIR}" -DBUILD_CLIENT=OFF -DBUILD_TTY_CLIENT=OFF -DBUILD_SERVER=OFF - -DBUILD_DUMMY_GAMELOGIC=${BUILD_DUMMY_GAMELOGIC} + "-DBUILD_DUMMY_GAMELOGIC=${BUILD_DUMMY_GAMELOGIC}" + -DGAME_BUILD_SUBINVOCATION=ON ${ARGV} ${INHERITED_OPTION_ARGS} INSTALL_COMMAND "" @@ -186,8 +206,9 @@ function(GAMEMODULE) buildGameModule("native-exe") endif() - if (NOT FORK) # create the nacl-vms target only the first time that GAMEMODULE is called - set(FORK 1 PARENT_SCOPE) + if (NOT NACL_VMS_TARGET_CREATED AND NOT GAME_BUILD_SUBINVOCATION) + # Create the nacl-vms target only the first time that GAMEMODULE is called. + set(NACL_VMS_TARGET_CREATED ON PARENT_SCOPE) if (CMAKE_GENERATOR MATCHES "Visual Studio") set(VM_GENERATOR "NMake Makefiles") @@ -197,39 +218,33 @@ function(GAMEMODULE) set(INHERITED_OPTION_ARGS) - foreach(inherited_option ${NACL_VM_INHERITED_OPTIONS}) - set(INHERITED_OPTION_ARGS ${INHERITED_OPTION_ARGS} + foreach(inherited_option IN LISTS NACL_VM_INHERITED_OPTIONS GAME_NACL_VM_INHERITED_OPTIONS) + list(APPEND INHERITED_OPTION_ARGS "-D${inherited_option}=${${inherited_option}}") endforeach(inherited_option) - if (BUILD_GAME_NACL) + if (BUILD_GAME_NACL AND NOT YOKAI_TARGET_SYSTEM_NACL) if (USE_NACL_SAIGO) add_custom_target(nacl-vms ALL) unset(NACL_VMS_PROJECTS) - foreach(NACL_TARGET ${NACL_TARGETS}) - if (NACL_TARGET STREQUAL "i686") - set(SAIGO_ARCH "i686") - elseif (NACL_TARGET STREQUAL "amd64") - set(SAIGO_ARCH "x86_64") - elseif (NACL_TARGET STREQUAL "armhf") - set(SAIGO_ARCH "arm") - else() + foreach(nacl_target IN LISTS NACL_TARGETS) + if (NOT nacl_target IN_LIST NACL_ALL_TARGETS) message(FATAL_ERROR "Unknown NaCl architecture ${NACL_TARGET}") endif() - set(NACL_VMS_PROJECT nacl-vms-${NACL_TARGET}) + set(NACL_VMS_PROJECT nacl-vms-${nacl_target}) list(APPEND NACL_VMS_PROJECTS ${NACL_VMS_PROJECT}) add_dependencies(nacl-vms ${NACL_VMS_PROJECT}) + # TODO: Remove USE_NACL_SAIGO once the game uses YOKAI_TARGET_SYSTEM_NACL. gameSubProject( - -DCMAKE_TOOLCHAIN_FILE=${Daemon_SOURCE_DIR}/cmake/toolchain-saigo.cmake + "-DCMAKE_TOOLCHAIN_FILE=${Daemon_SOURCE_DIR}/cmake/cross-toolchain-saigo-${nacl_target}.cmake" + "-DPREFIX_SAIGO=${DEPS_DIR}/saigo_newlib" -DBUILD_GAME_NACL=ON -DBUILD_GAME_NATIVE_DLL=OFF -DBUILD_GAME_NATIVE_EXE=OFF -DUSE_NACL_SAIGO=ON - -DSAIGO_ARCH=${SAIGO_ARCH} - -DNACL_TARGET=${NACL_TARGET} ) endforeach() else() @@ -240,19 +255,20 @@ function(GAMEMODULE) string(REPLACE ";" "," NACL_TARGETS_STRING "${NACL_TARGETS}") gameSubProject( - -DCMAKE_TOOLCHAIN_FILE=${Daemon_SOURCE_DIR}/cmake/toolchain-pnacl.cmake + "-DCMAKE_TOOLCHAIN_FILE=${Daemon_SOURCE_DIR}/cmake/cross-toolchain-pnacl.cmake" + "-DPREFIX_PNACL=${DEPS_DIR}/pnacl" -DBUILD_GAME_NACL=ON -DBUILD_GAME_NATIVE_DLL=OFF -DBUILD_GAME_NATIVE_EXE=OFF - -DNACL_TARGETS_STRING=${NACL_TARGETS_STRING} + "-DNACL_TARGETS_STRING=${NACL_TARGETS_STRING}" ) endif() endif() set(NACL_VMS_PROJECTS ${NACL_VMS_PROJECTS} PARENT_SCOPE) - elseif (FORK EQUAL 2) # we are in the CMake sub-invocation for NaCl + elseif (GAME_BUILD_SUBINVOCATION) if (BUILD_GAME_NACL) - if (USE_NACL_SAIGO) + if (YOKAI_CXX_COMPILER_SAIGO) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) else() # Put the .nexe and .pexe files in the same directory as the engine. @@ -261,16 +277,28 @@ function(GAMEMODULE) buildGameModule("nacl") - if (USE_NACL_SAIGO) + if (YOKAI_CXX_COMPILER_SAIGO) + include(DaemonSaigoFinalize) + # Finalize NaCl executables for supported architectures. - saigo_finalize(${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/.. ${GAMEMODULE_NAME} ${NACL_TARGET}) + saigo_finalize( + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + "${GAMEMODULE_NAME}" + "${YOKAI_TARGET_ARCH_NAME}" + ) else() + include(DaemonPNaClFinalize) + # Revert a workaround for a bug where CMake ExternalProject lists-as-args are cut on first “;” string(REPLACE "," ";" NACL_TARGETS "${NACL_TARGETS_STRING}") # Generate NaCl executables for supported architectures. - foreach(NACL_TARGET ${NACL_TARGETS}) - pnacl_finalize(${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${GAMEMODULE_NAME} ${NACL_TARGET}) + foreach(nacl_target ${NACL_TARGETS}) + pnacl_finalize( + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + "${GAMEMODULE_NAME}" + "${nacl_target}" + ) endforeach() endif() endif() diff --git a/cmake/DaemonNacl.cmake b/cmake/DaemonNacl.cmake deleted file mode 100644 index e37bf06844..0000000000 --- a/cmake/DaemonNacl.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# Daemon BSD Source Code -# Copyright (c) 2013-2016, Daemon Developers -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the Daemon developers nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Native client - -option(USE_NACL_SAIGO "Use Saigo toolchain to build NaCl executables" OFF) - -if (YOKAI_TARGET_SYSTEM_NACL) - # Build nexe binary. - if(USE_NACL_SAIGO) - if (NACL_TARGET STREQUAL "amd64") - add_definitions(-DNACL_BUILD_ARCH=x86) - add_definitions(-DNACL_BUILD_SUBARCH=64) - elseif (NACL_TARGET STREQUAL "i686") - add_definitions(-DNACL_BUILD_ARCH=x86) - add_definitions(-DNACL_BUILD_SUBARCH=32) - elseif (NACL_TARGET STREQUAL "armhf") - add_definitions(-DNACL_BUILD_ARCH=arm) - else() - message(FATAL_ERROR "Unsupported architecture ${NACL_TARGET}") - endif() - else() - # Those defines looks to be meaningless to produce arch-independent pexe - # with PNaCl but they must be set to anything supported by native builds. - # This requirement looks to be a PNaCl bug. - add_definitions( -DNACL_BUILD_ARCH=x86 ) - add_definitions( -DNACL_BUILD_SUBARCH=64 ) - endif() -else() - # Build native dll or native exe. - if (YOKAI_TARGET_SYSTEM_MACOS) - add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=1 ) - elseif (YOKAI_TARGET_SYSTEM_LINUX) - add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=1 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=0 ) - elseif (YOKAI_TARGET_SYSTEM_FREEBSD) - add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=1 -DNACL_OSX=0 ) - elseif (YOKAI_TARGET_SYSTEM_WINDOWS) - add_definitions( -DNACL_WINDOWS=1 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=0 ) - endif() - - if (YOKAI_TARGET_ARCH_AMD64) - add_definitions( -DNACL_BUILD_ARCH=x86 ) - add_definitions( -DNACL_BUILD_SUBARCH=64 ) - elseif (YOKAI_TARGET_ARCH_I686) - add_definitions( -DNACL_BUILD_ARCH=x86 ) - add_definitions( -DNACL_BUILD_SUBARCH=32 ) - elseif (YOKAI_TARGET_ARCH_ARMHF) - add_definitions( -DNACL_BUILD_ARCH=arm ) - else() - # NaCl does not support this architecture natively, but these defines must - # be set because nacl_config.h is included unconditionally. Use dummy x86 - # values as PNaCl does for architecture-independent builds. - add_definitions( -DNACL_BUILD_ARCH=x86 ) - add_definitions( -DNACL_BUILD_SUBARCH=64 ) - endif() -endif() - -include_directories( ${LIB_DIR}/nacl ) diff --git a/cmake/DaemonNaclHost.cmake b/cmake/DaemonNaclArchitecture.cmake similarity index 67% rename from cmake/DaemonNaclHost.cmake rename to cmake/DaemonNaclArchitecture.cmake index 7172e71d55..59711c6357 100644 --- a/cmake/DaemonNaclHost.cmake +++ b/cmake/DaemonNaclArchitecture.cmake @@ -24,60 +24,74 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -function(daemon_detect_nacl_arch) - set(target_arch "${YOKAI_TARGET_ARCH_NAME}") - set(nacl_arch "${target_arch}") +function(daemon_detect_nacl_arch target_arch) + macro(add_nacl_arch arch_name) + list(APPEND nacl_arch_list "${arch_name}") + endmacro() + + # NaCl runtime is only available on architectures that have a NaCl loader. + set(nacl_runtime_arch "amd64" "i686" "armhf") + + if (YOKAI_TARGET_SYSTEM_WINDOWS) + if("${target_arch}" STREQUAL "amd64") + add_nacl_arch("${target_arch}") + elseif("${target_arch}" STREQUAL "i686") + # Win32 requires nacl_loader-amd64.exe in order to run on Win64 + add_nacl_arch("${target_arch}") + add_nacl_arch("amd64") + endif() + elseif (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY OR YOKAI_TARGET_SYSTEM_XDG_COMPATIBILITY) + if ("${target_arch}" IN_LIST nacl_runtime_arch) + add_nacl_arch("${target_arch}") + endif() - if (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY OR YOKAI_TARGET_SYSTEM_XDG_COMPATIBILITY) set(armhf_usage "arm64" "armel") - set(box64_usage "ppc64el" "riscv64") + set(box64_usage "arm64" "ppc64el" "riscv64" "loong64") if ("${target_arch}" IN_LIST armhf_usage) + set(DAEMON_NACL_MULTIARCH ON) + # 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) + add_nacl_arch("armhf") + endif() + + if ("${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. # Box64 must be installed and available in PATH at runtime. - set(nacl_arch "amd64") + add_nacl_arch("amd64") add_definitions(-DDAEMON_NACL_BOX64_EMULATION) endif() endif() elseif (YOKAI_TARGET_SYSTEM_MACOS) - if ("${target_arch}" STREQUAL "arm64") + if ("${target_arch}" STREQUAL "amd64") + add_nacl_arch("${target_arch}") + elseif ("${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") + add_nacl_arch("amd64") endif() endif() - string(TOUPPER "${nacl_arch}" nacl_arch_upper) + if (nacl_arch_list) + message(STATUS "Available NaCl architectures: ${nacl_arch_list}") - # NaCl runtime is only available on architectures that have a NaCl loader. - set(nacl_runtime_arch "amd64" "i686" "armhf") - if ("${nacl_arch}" IN_LIST nacl_runtime_arch) - message(STATUS "Detected NaCl architecture: ${nacl_arch}") + list(GET nacl_arch_list 0 nacl_arch) + + message(STATUS "Primary NaCl architecture: ${nacl_arch}") add_definitions(-DDAEMON_NACL_RUNTIME_ENABLED) else() set(nacl_arch "unknown") - message(STATUS "No NaCl architecture detected") + message(STATUS "No known NaCl architecture") 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) + # Those names are used to copy the loader and the IRT binaries. + set(DAEMON_NACL_ARCH_NAME_LIST "${nacl_arch_list}" PARENT_SCOPE) endfunction() - -daemon_detect_nacl_arch() - -# Makes possible to do that in CMake code: -# > if (DAEMON_NACL_ARCH_ARMHF) -set("DAEMON_NACL_ARCH_${DAEMON_NACL_ARCH_NAME_UPPER}" ON) - -# Add printable strings to the executable. -yokai_add_buildinfo("char*" "DAEMON_NACL_ARCH_STRING" "\"${DAEMON_NACL_ARCH_NAME}\"") diff --git a/cmake/DaemonNaclFlags.cmake b/cmake/DaemonNaclFlags.cmake new file mode 100644 index 0000000000..cbdc4b5a3f --- /dev/null +++ b/cmake/DaemonNaclFlags.cmake @@ -0,0 +1,75 @@ +# Daemon BSD Source Code +# Copyright (c) 2013-2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Native Client build configuration. + +if (YOKAI_TARGET_SYSTEM_NACL) + # Build nexe binary. + + if (YOKAI_CXX_COMPILER_SAIGO) + if (YOKAI_TARGET_ARCH_AMD64) + add_definitions(-DNACL_BUILD_ARCH=x86 -DNACL_BUILD_SUBARCH=64) + elseif (YOKAI_TARGET_ARCH_I686) + add_definitions(-DNACL_BUILD_ARCH=x86 -DNACL_BUILD_SUBARCH=32) + elseif (YOKAI_TARGET_ARCH_ARMHF) + add_definitions(-DNACL_BUILD_ARCH=arm) + else() + message(FATAL_ERROR "Unsupported architecture ${NACL_TARGET}") + endif() + else() + # Those defines looks to be meaningless to produce arch-independent pexe + # with PNaCl but they must be set to anything supported by native builds. + # This requirement looks to be a PNaCl bug. + add_definitions(-DNACL_BUILD_ARCH=x86 -DNACL_BUILD_SUBARCH=64) + endif() +else() + # Build native dll or native exe. + + if (YOKAI_TARGET_SYSTEM_MACOS) + add_definitions(-DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=1) + elseif (YOKAI_TARGET_SYSTEM_LINUX) + add_definitions(-DNACL_WINDOWS=0 -DNACL_LINUX=1 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=0) + elseif (YOKAI_TARGET_SYSTEM_FREEBSD) + add_definitions(-DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=1 -DNACL_OSX=0) + elseif (YOKAI_TARGET_SYSTEM_WINDOWS) + add_definitions(-DNACL_WINDOWS=1 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=0) + endif() + + if (YOKAI_TARGET_ARCH_AMD64) + add_definitions(-DNACL_BUILD_ARCH=x86 -DNACL_BUILD_SUBARCH=64) + elseif (YOKAI_TARGET_ARCH_I686) + add_definitions(-DNACL_BUILD_ARCH=x86 -DNACL_BUILD_SUBARCH=32) + elseif (YOKAI_TARGET_ARCH_ARMHF) + add_definitions(-DNACL_BUILD_ARCH=arm) + else() + # NaCl does not support this architecture natively, but these defines must + # be set because nacl_config.h is included unconditionally. Use dummy x86 + # values as PNaCl does for architecture-independent builds. + add_definitions(-DNACL_BUILD_ARCH=x86 -DNACL_BUILD_SUBARCH=64) + endif() +endif() + +include_directories(${LIB_DIR}/nacl) diff --git a/cmake/DaemonPNaClFinalize.cmake b/cmake/DaemonPNaClFinalize.cmake new file mode 100644 index 0000000000..2130490030 --- /dev/null +++ b/cmake/DaemonPNaClFinalize.cmake @@ -0,0 +1,79 @@ +# Daemon BSD Source Code +# Copyright (c) 2013-2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function(pnacl_finalize dir module arch) + include(DaemonBuildTypeGeneratorExpression) + + set(PNACL_TRANSLATE_OPTIONS + --allow-llvm-bitcode-input # FIXME: finalize as part of the build process + --pnacl-allow-exceptions + $<${RELEASE_GENEXP_COND}:-O3> + $<${DEBUG_GENEXP_COND}:-O0> + $<${RELWITHDEBINFO_GENEXP_COND}:-O2> + $<${MINSIZEREL_GENEXP_COND}:-O2> + ) + set(PEXE "${dir}/${module}${NACL_EXECUTABLE_SUFFIX}") + set(NEXE "${dir}/${module}-${arch}${NACL_TRANSLATED_EXECUTABLE_SUFFIX}") + set(STRIPPED_NEXE "${dir}/${module}-${arch}-stripped${NACL_TRANSLATED_EXECUTABLE_SUFFIX}") + + if (arch STREQUAL "i686") + set(PNACL_ARCH "i686") + elseif (arch STREQUAL "amd64") + set(PNACL_ARCH "x86-64") + elseif (arch STREQUAL "armhf") + set(PNACL_ARCH "arm") + else() + message(FATAL_ERROR "Unknown NaCl architecture ${arch}") + endif() + + add_custom_command( + OUTPUT ${NEXE} + COMMENT "Translating ${module} (${arch})" + DEPENDS ${PEXE} + COMMAND + ${PNACLPYTHON_PREFIX2} + "${PNACL_TRANSLATE}" + ${PNACL_TRANSLATE_OPTIONS} + -arch "${PNACL_ARCH}" + "${PEXE}" + -o "${NEXE}" + ) + + add_custom_command( + OUTPUT "${STRIPPED_NEXE}" + COMMENT "Stripping ${module} (${arch})" + DEPENDS "${NEXE}" + COMMAND + ${PNACLPYTHON_PREFIX2} + "${CMAKE_STRIP}" + -s + "${NEXE}" + -o "${STRIPPED_NEXE}" + ) + + add_custom_target("${module}-${arch}" ALL DEPENDS "${STRIPPED_NEXE}") + add_dependencies("${module}-${arch}" "${module}-nacl") +endfunction() diff --git a/cmake/DaemonSaigoFinalize.cmake b/cmake/DaemonSaigoFinalize.cmake new file mode 100644 index 0000000000..01f1cf1da5 --- /dev/null +++ b/cmake/DaemonSaigoFinalize.cmake @@ -0,0 +1,56 @@ +# Daemon BSD Source Code +# Copyright (c) 2023-2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function(saigo_finalize dir module arch) + set(SUBPROJECT_NEXE "${dir}/${module}${NACL_EXECUTABLE_SUFFIX}") + set(NEXE "${dir}/../${module}-${arch}${NACL_EXECUTABLE_SUFFIX}") + set(STRIPPED_NEXE "${dir}/../${module}-${arch}-stripped${NACL_EXECUTABLE_SUFFIX}") + + add_custom_command( + OUTPUT "${NEXE}" + COMMENT "Copying ${module} (${arch})" + DEPENDS "${SUBPROJECT_NEXE}" + COMMAND + ${CMAKE_COMMAND} + -E copy + "${SUBPROJECT_NEXE}" + "${NEXE}" + ) + + add_custom_command( + OUTPUT "${STRIPPED_NEXE}" + COMMENT "Stripping ${module} (${arch})" + DEPENDS "${NEXE}" + COMMAND + "${CMAKE_STRIP}" + -s + "${NEXE}" + -o "${STRIPPED_NEXE}" + ) + + add_custom_target("${module}-${arch}" ALL DEPENDS "${STRIPPED_NEXE}") + add_dependencies("${module}-${arch}" "${module}-nacl") +endfunction() diff --git a/cmake/cross-toolchain-pnacl.cmake b/cmake/cross-toolchain-pnacl.cmake new file mode 100644 index 0000000000..a3e3e5a84c --- /dev/null +++ b/cmake/cross-toolchain-pnacl.cmake @@ -0,0 +1,106 @@ +# Daemon BSD Source Code +# Copyright (c) 2013-2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# We can't use CMAKE_EXECUTABLE_SUFFIX because the Generic Platform will reset it +# and creating a Platform module for setting CMAKE_EXECUTABLE_SUFFIX is overkill. +set(NACL_EXECUTABLE_SUFFIX ".pexe") +set(NACL_TRANSLATED_EXECUTABLE_SUFFIX ".nexe") + +if (CMAKE_HOST_WIN32) + set(PNACL_EXECUTABLE_SUFFIX ".bat") +else() + set(PNACL_EXECUTABLE_SUFFIX "") +endif() + +set(PNACL_TRIPLET "pnacl") + +if (NOT DEFINED PREFIX_PNACL) + find_program(PATH_PNACL_CLANG NAMES "${PNACL_TRIPLET}-clang${PNACL_EXECUTABLE_SUFFIX}") + get_filename_component(PREFIX_PNACL ${PATH_PNACL_CLANG} DIRECTORY) +endif() + +list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PREFIX_PNACL) + +set(CMAKE_SYSTEM_NAME "Generic") + +set(CMAKE_C_COMPILER "${PREFIX_PNACL}/bin/${PNACL_TRIPLET}-clang${PNACL_EXECUTABLE_SUFFIX}") +set(CMAKE_CXX_COMPILER "${PREFIX_PNACL}/bin/${PNACL_TRIPLET}-clang++${PNACL_EXECUTABLE_SUFFIX}") +set(CMAKE_AR "${PREFIX_PNACL}/bin/${PNACL_TRIPLET}-ar${PNACL_EXECUTABLE_SUFFIX}" CACHE FILEPATH "Archiver" FORCE) +set(CMAKE_RANLIB "${PREFIX_PNACL}/bin/${PNACL_TRIPLET}-ranlib${PNACL_EXECUTABLE_SUFFIX}") +set(PNACL_TRANSLATE "${PREFIX_PNACL}/bin/${PNACL_TRIPLET}-translate${PNACL_EXECUTABLE_SUFFIX}") +set(CMAKE_STRIP "${PREFIX_PNACL}/bin/${PNACL_TRIPLET}-strip${PNACL_EXECUTABLE_SUFFIX}") +set(CMAKE_FIND_ROOT_PATH "${PREFIX_PNACL}/le32-nacl") + +set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1) +set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 1) +set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) +set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1) +set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1) +set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1) +set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@") +set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@") + +set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") +set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") +set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG") +set(CMAKE_C_FLAGS_DEBUG_INIT "-g") + +set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT}") +set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}") +set(CMAKE_CXX_FLAGS_DEBUG_INIT "${CMAKE_C_FLAGS_DEBUG_INIT}") + +if (NOT CMAKE_HOST_WIN32) + find_package(Python) + + if (Python_Interpreter_FOUND) + set(PNACLPYTHON_PREFIX "env PNACLPYTHON=${Python_EXECUTABLE} ") + set(PNACLPYTHON_PREFIX2 env "PNACLPYTHON=${Python_EXECUTABLE} ") + message(STATUS "Using PNACL Python executable: ${Python_EXECUTABLE}") + else() + message(FATAL_ERROR "Please install python (and run in a python virtualenv if that's not enough).") + endif() +endif() + +# These commands can fail on windows if there is a space at the beginning +set(CMAKE_C_CREATE_STATIC_LIBRARY "${PNACLPYTHON_PREFIX} rc ") +set(CMAKE_CXX_CREATE_STATIC_LIBRARY "${PNACLPYTHON_PREFIX} rc ") + +set(CMAKE_C_COMPILE_OBJECT "${PNACLPYTHON_PREFIX} -o -c ") +set(CMAKE_CXX_COMPILE_OBJECT "${PNACLPYTHON_PREFIX} -o -c ") + +set(CMAKE_C_LINK_EXECUTABLE "${PNACLPYTHON_PREFIX} -o ") +set(CMAKE_CXX_LINK_EXECUTABLE "${PNACLPYTHON_PREFIX} -o ") + +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + +set(NACL ON) + +set(CMAKE_C_FLAGS "") +set(CMAKE_CXX_FLAGS "") diff --git a/cmake/cross-toolchain-saigo-amd64.cmake b/cmake/cross-toolchain-saigo-amd64.cmake new file mode 100644 index 0000000000..c755d9b2b1 --- /dev/null +++ b/cmake/cross-toolchain-saigo-amd64.cmake @@ -0,0 +1,28 @@ +# Daemon BSD Source Code +# Copyright (c) 2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(SAIGO_ARCH "x86_64") +include("${CMAKE_CURRENT_LIST_DIR}/cross-toolchain-saigo-common.cmake") diff --git a/cmake/cross-toolchain-saigo-armhf.cmake b/cmake/cross-toolchain-saigo-armhf.cmake new file mode 100644 index 0000000000..7197c47049 --- /dev/null +++ b/cmake/cross-toolchain-saigo-armhf.cmake @@ -0,0 +1,28 @@ +# Daemon BSD Source Code +# Copyright (c) 2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(SAIGO_ARCH "arm") +include("${CMAKE_CURRENT_LIST_DIR}/cross-toolchain-saigo-common.cmake") diff --git a/cmake/cross-toolchain-saigo-common.cmake b/cmake/cross-toolchain-saigo-common.cmake new file mode 100644 index 0000000000..5aa286a139 --- /dev/null +++ b/cmake/cross-toolchain-saigo-common.cmake @@ -0,0 +1,79 @@ +# Daemon BSD Source Code +# Copyright (c) 2023-2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# We can't use CMAKE_EXECUTABLE_SUFFIX because the Generic Platform will reset it +# and creating a Platform module for setting CMAKE_EXECUTABLE_SUFFIX is overkill. +set(NACL_EXECUTABLE_SUFFIX ".nexe") + +set(SAIGO_TRIPLET "${SAIGO_ARCH}-nacl") + +if (NOT DEFINED PREFIX_SAIGO) + find_program(PATH_SAIGO_CLANG NAMES "${SAIGO_TRIPLET}-clang") + get_filename_component(PREFIX_SAIGO ${PATH_SAIGO_CLANG} DIRECTORY) +endif() + +list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES PREFIX_SAIGO) + +set(CMAKE_SYSTEM_NAME "Generic") + +set(CMAKE_C_COMPILER "${PREFIX_SAIGO}/bin/${SAIGO_TRIPLET}-clang") +set(CMAKE_CXX_COMPILER "${PREFIX_SAIGO}/bin/${SAIGO_TRIPLET}-clang++") +set(CMAKE_AR "${PREFIX_SAIGO}/bin/${SAIGO_TRIPLET}-ar" CACHE FILEPATH "Archiver" FORCE) +set(CMAKE_RANLIB "${PREFIX_SAIGO}/bin/${SAIGO_TRIPLET}-ranlib") +set(CMAKE_STRIP "${PREFIX_SAIGO}/bin/${SAIGO_TRIPLET}-strip") +set(CMAKE_FIND_ROOT_PATH "${PREFIX_SAIGO}/${SAIGO_TRIPLET}") + +# Copy-pasted from the PNaCl toolchain, it's not sure we need it. +set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1) +set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 1) +set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) +set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1) +set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1) +set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1) +set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@") +set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@") + +# Copy-pasted from the PNaCl toolchain, it's not sure we need it. +# These commands can fail on windows if there is a space at the beginning +set(CMAKE_C_CREATE_STATIC_LIBRARY " rc ") +set(CMAKE_CXX_CREATE_STATIC_LIBRARY " rc ") + +set(CMAKE_C_COMPILE_OBJECT " -o -c ") +set(CMAKE_CXX_COMPILE_OBJECT " -o -c ") + +set(CMAKE_C_LINK_EXECUTABLE " -o ") +set(CMAKE_CXX_LINK_EXECUTABLE " -o ") + +# Copy-pasted from the PNaCl toolchain, it's not sure we need it. +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + +set(NACL ON) + +set(CMAKE_C_FLAGS "") +set(CMAKE_CXX_FLAGS "") diff --git a/cmake/cross-toolchain-saigo-i686.cmake b/cmake/cross-toolchain-saigo-i686.cmake new file mode 100644 index 0000000000..717ebae97d --- /dev/null +++ b/cmake/cross-toolchain-saigo-i686.cmake @@ -0,0 +1,32 @@ +# Daemon BSD Source Code +# Copyright (c) 2026, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Daemon developers nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(SAIGO_ARCH "i686") +include("${CMAKE_CURRENT_LIST_DIR}/cross-toolchain-saigo-common.cmake") + +if (EXISTS "${PREFIX_SAIGO}/x86_64-nacl/lib32") + list(APPEND CMAKE_LIBRARY_PATH "${PREFIX_SAIGO}/x86_64-nacl/lib32") +endif() diff --git a/cmake/toolchain-pnacl.cmake b/cmake/toolchain-pnacl.cmake deleted file mode 100644 index b19f61e8ec..0000000000 --- a/cmake/toolchain-pnacl.cmake +++ /dev/null @@ -1,151 +0,0 @@ -# Daemon BSD Source Code -# Copyright (c) 2013-2016, Daemon Developers -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the Daemon developers nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -set(PLATFORM_PREFIX ${DEPS_DIR}/pnacl/bin) -set(PLATFORM_TRIPLET "pnacl") - -if (WIN32) - set(PNACL_BIN_EXT ".bat") -else() - set(PNACL_BIN_EXT "") -endif() - -set(PLATFORM_EXE_SUFFIX ".pexe") - -set(CMAKE_SYSTEM_NAME "Generic") - -set(CMAKE_C_COMPILER "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-clang${PNACL_BIN_EXT}") -set(CMAKE_CXX_COMPILER "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-clang++${PNACL_BIN_EXT}") -set(CMAKE_AR "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-ar${PNACL_BIN_EXT}" CACHE FILEPATH "Archiver" FORCE) -set(CMAKE_RANLIB "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-ranlib${PNACL_BIN_EXT}") -set(PNACL_TRANSLATE "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-translate${PNACL_BIN_EXT}") -set(PNACL_STRIP "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-strip${PNACL_BIN_EXT}") -set(CMAKE_FIND_ROOT_PATH "${PLATFORM_PREFIX}/../le32-nacl") - -set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1) -set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 1) -set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) -set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1) -set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1) -set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1) -set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@") -set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@") - -set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") -set(CMAKE_C_FLAGS_RELEASE_INIT "-O3 -DNDEBUG") -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g -DNDEBUG") -set(CMAKE_C_FLAGS_DEBUG_INIT "-g") - -set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${CMAKE_C_FLAGS_DEBUG_INIT}") - -if (NOT CMAKE_HOST_WIN32) - find_package(Python) - - if (Python_Interpreter_FOUND) - set(PNACLPYTHON_PREFIX "env PNACLPYTHON=${Python_EXECUTABLE} ") - set(PNACLPYTHON_PREFIX2 env "PNACLPYTHON=${Python_EXECUTABLE} ") - message(STATUS "Using PNACL Python executable: ${Python_EXECUTABLE}") - else() - message(FATAL_ERROR "Please install python (and run in a python virtualenv if that's not enough).") - endif() -endif() - -# These commands can fail on windows if there is a space at the beginning -set(CMAKE_C_CREATE_STATIC_LIBRARY "${PNACLPYTHON_PREFIX} rc ") -set(CMAKE_CXX_CREATE_STATIC_LIBRARY "${PNACLPYTHON_PREFIX} rc ") - -set(CMAKE_C_COMPILE_OBJECT "${PNACLPYTHON_PREFIX} -o -c ") -set(CMAKE_CXX_COMPILE_OBJECT "${PNACLPYTHON_PREFIX} -o -c ") - -set(CMAKE_C_LINK_EXECUTABLE "${PNACLPYTHON_PREFIX} -o ") -set(CMAKE_CXX_LINK_EXECUTABLE "${PNACLPYTHON_PREFIX} -o ") - -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) - -set(NACL ON) - -set(CMAKE_C_FLAGS "") -set(CMAKE_CXX_FLAGS "") - -function(pnacl_finalize dir module arch) - include(DaemonBuildTypeGeneratorExpression) - - set(PNACL_TRANSLATE_OPTIONS - --allow-llvm-bitcode-input # FIXME: finalize as part of the build process - --pnacl-allow-exceptions - $<${RELEASE_GENEXP_COND}:-O3> - $<${DEBUG_GENEXP_COND}:-O0> - $<${RELWITHDEBINFO_GENEXP_COND}:-O2> - $<${MINSIZEREL_GENEXP_COND}:-O2> - ) - set(PEXE ${dir}/${module}.pexe) - set(NEXE ${dir}/${module}-${arch}.nexe) - set(STRIPPED_NEXE ${dir}/${module}-${arch}-stripped.nexe) - - if (arch STREQUAL "i686") - set(PNACL_ARCH "i686") - elseif (arch STREQUAL "amd64") - set(PNACL_ARCH "x86-64") - elseif (arch STREQUAL "armhf") - set(PNACL_ARCH "arm") - else() - message(FATAL_ERROR "Unknown NaCl architecture ${arch}") - endif() - - add_custom_command( - OUTPUT ${NEXE} - COMMENT "Translating ${module} (${arch})" - DEPENDS ${PEXE} - COMMAND - ${PNACLPYTHON_PREFIX2} - "${PNACL_TRANSLATE}" - ${PNACL_TRANSLATE_OPTIONS} - -arch ${PNACL_ARCH} - ${PEXE} - -o ${NEXE} - ) - - add_custom_command( - OUTPUT ${STRIPPED_NEXE} - COMMENT "Stripping ${module} (${arch})" - DEPENDS ${NEXE} - COMMAND - ${PNACLPYTHON_PREFIX2} - "${PNACL_STRIP}" - -s - ${NEXE} - -o ${STRIPPED_NEXE} - ) - - add_custom_target(${module}-${arch} ALL DEPENDS ${STRIPPED_NEXE}) - add_dependencies(${module}-${arch} ${module}-nacl) -endfunction() diff --git a/cmake/toolchain-saigo.cmake b/cmake/toolchain-saigo.cmake deleted file mode 100644 index 75374527b3..0000000000 --- a/cmake/toolchain-saigo.cmake +++ /dev/null @@ -1,75 +0,0 @@ -set(PLATFORM_PREFIX "${DEPS_DIR}/saigo_newlib/bin") -set(PLATFORM_TRIPLET "${SAIGO_ARCH}-nacl") -set(PLATFORM_EXE_SUFFIX ".nexe") - -set(CMAKE_SYSTEM_NAME "Generic") - -set(CMAKE_C_COMPILER "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-clang") -set(CMAKE_CXX_COMPILER "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-clang++") -set(CMAKE_AR "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-ar" CACHE FILEPATH "Archiver" FORCE) -set(CMAKE_RANLIB "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-ranlib") -set(SAIGO_STRIP "${PLATFORM_PREFIX}/${PLATFORM_TRIPLET}-strip") -set(CMAKE_FIND_ROOT_PATH "${PLATFORM_PREFIX}/../${PLATFORM_TRIPLET}") - -# Copy-pasted from the PNaCl toolchain, it's not sure we need it. -set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 1) -set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES 1) -set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) -set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1) -set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1) -set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1) -set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@") -set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@") - -# Copy-pasted from the PNaCl toolchain, it's not sure we need it. -# These commands can fail on windows if there is a space at the beginning -set(CMAKE_C_CREATE_STATIC_LIBRARY " rc ") -set(CMAKE_CXX_CREATE_STATIC_LIBRARY " rc ") - -set(CMAKE_C_COMPILE_OBJECT " -o -c ") -set(CMAKE_CXX_COMPILE_OBJECT " -o -c ") - -set(CMAKE_C_LINK_EXECUTABLE " -o ") -set(CMAKE_CXX_LINK_EXECUTABLE " -o ") - -# Copy-pasted from the PNaCl toolchain, it's not sure we need it. -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) - -set(NACL ON) - -set(CMAKE_C_FLAGS "") -set(CMAKE_CXX_FLAGS "") - -function(saigo_finalize dir module arch) - set(SUBPROJECT_NEXE ${dir}/nacl-vms-${arch}/${module}.nexe) - set(NEXE ${dir}/${module}-${arch}.nexe) - set(STRIPPED_NEXE ${dir}/${module}-${arch}-stripped.nexe) - - add_custom_command( - OUTPUT ${NEXE} - COMMENT "Copying ${module} (${arch})" - DEPENDS ${SUBPROJECT_NEXE} - COMMAND - ${CMAKE_COMMAND} - -E copy - ${SUBPROJECT_NEXE} - ${NEXE} - ) - - add_custom_command( - OUTPUT ${STRIPPED_NEXE} - COMMENT "Stripping ${module} (${arch})" - DEPENDS ${NEXE} - COMMAND - "${SAIGO_STRIP}" - -s - ${NEXE} - -o ${STRIPPED_NEXE} - ) - - add_custom_target(${module}-${arch} ALL DEPENDS ${STRIPPED_NEXE}) - add_dependencies(${module}-${arch} ${module}-nacl) -endfunction() diff --git a/external_deps/build.sh b/external_deps/build.sh index e5e77cf91a..3f49f26e5f 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,8 @@ 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' +BOX64_BASEURL='https://api.github.com/repos/ptitSeb/box64/zipball' +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,47 +45,42 @@ 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 +BOX64_REVISION='b1d094f9bd37cd69865c56d72a94747b22c16dd6' +SAIGOSDK_VERSION='21.0-20260707' NACLSDK_VERSION=44.0.2403.155 -NACLRUNTIME_REVISION=2aea5fcfce504862a825920fcaea1a8426afbd6f +NACLRUNTIME_REVISION='6db3cdbecd872f9e7318a5d42c5ebfa60fd704e1' 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' +case "$(uname -s)" in + 'FreeBSD') + # The builtin make isn't compatible enough. + MAKE='gmake' + ;; + *) + MAKE='make' + ;; +esac log() { level="${1}"; shift @@ -90,6 +88,28 @@ log() { [ "${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 +142,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 +196,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,13 +229,10 @@ configure_build() { fi ./configure \ - --host="${HOST}" \ - --prefix="${PREFIX}" \ - --libdir="${PREFIX}/lib" \ "${configure_args[@]}" - make - make install + "${MAKE}" + "${MAKE}" install } get_compiler_name() { @@ -223,25 +252,51 @@ get_compiler_arg1() { cmake_build() { local cmake_args=() - 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})") - cmake_args+=(-DCMAKE_CXX_COMPILER_ARG1="$(get_compiler_arg1 ${CXX})") + 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 + + if [ -n "${COMPILER_LAUNCHER}" ] + then + cmake_args+=(-DCMAKE_C_COMPILER_LAUNCHER="${COMPILER_LAUNCHER}") + cmake_args+=(-DCMAKE_CXX_COMPILER_LAUNCHER="${COMPILER_LAUNCHER}") + fi + + cmake_args+=(-DCMAKE_C_COMPILER="${C_COMPILER}") + cmake_args+=(-DCMAKE_CXX_COMPILER="${CXX_COMPILER}") cmake_args+=(-DCMAKE_C_FLAGS="${CFLAGS}") 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 +304,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. + ( + setup_platform 'native' CFLAGS='-Wno-error=int-conversion' \ - LDFLAGS='' \ - HOST='' \ 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 +348,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 + smart_copy "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 @@ -309,8 +394,8 @@ build_zlib() { case "${PLATFORM}" in windows-*-*) - LOC="${CFLAGS}" make -f win32/Makefile.gcc PREFIX="${HOST}-" - make -f win32/Makefile.gcc install BINARY_PATH="${PREFIX}/bin" LIBRARY_PATH="${PREFIX}/lib" INCLUDE_PATH="${PREFIX}/include" SHARED_MODE=1 + LOC="${CFLAGS}" "${MAKE}" -f win32/Makefile.gcc PREFIX="${HOST}-" + "${MAKE}" -f win32/Makefile.gcc install BINARY_PATH="${PREFIX}/bin" LIBRARY_PATH="${PREFIX}/lib" INCLUDE_PATH="${PREFIX}/include" SHARED_MODE=1 ;; *) CFLAGS="${CFLAGS} -DZLIB_CONST" \ @@ -455,16 +540,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 +566,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 } @@ -524,6 +613,11 @@ build_glew() { glew_env+=(CFLAGS.EXTRA="${CFLAGS}") glew_options+=(LIBDIR="${PREFIX}/lib" LD="${CC}") ;; + freebsd-*-*) + glew_env+=(CFLAGS.EXTRA="${CFLAGS}") + sed -e 's/ -soname / -Wl,-soname=/' config/Makefile.freebsd > config/Makefile.freebsd-fix + glew_options+=(SYSTEM=freebsd-fix LD="${CC}") + ;; *) log ERROR 'Unsupported platform for GLEW' ;; @@ -537,12 +631,12 @@ build_glew() { # manually re-add the required flags there. case "${PLATFORM}" in macos-*-*) - make "${glew_env[@]}" "${glew_options[@]}" - make install "${glew_env[@]}" "${glew_options[@]}" + "${MAKE}" "${glew_env[@]}" "${glew_options[@]}" + "${MAKE}" install "${glew_env[@]}" "${glew_options[@]}" ;; *) - env "${glew_env[@]}" make "${glew_options[@]}" - env "${glew_env[@]}" make install "${glew_options[@]}" + env "${glew_env[@]}" "${MAKE}" "${glew_options[@]}" + env "${glew_env[@]}" "${MAKE}" install "${glew_options[@]}" ;; esac @@ -550,7 +644,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" @@ -595,6 +689,9 @@ build_jpeg() { linux-*-*) local SYSTEM_NAME='Linux' ;; + freebsd-*-*) + local SYSTEM_NAME='FreeBSD' + ;; *) # Other platforms can build but we need to explicitly # set CMAKE_SYSTEM_NAME for CMAKE_CROSSCOMPILING to be set @@ -603,29 +700,43 @@ build_jpeg() { ;; esac - local jpeg_cmake_args=(-DREQUIRE_SIMD=ON) + local jpeg_cmake_args=() + + # When there is no platform code implemented in libjpeg yet, + # we can build it without SIMD code. + # This string will then only be used for warnings like that: + # > SIMD extensions not available for this CPU (riscv64). Performance will suffer. + local SYSTEM_PROCESSOR="${PLATFORM_ARCH}" + + local jpeg_require_simd='OFF' case "${PLATFORM}" in *-amd64-*) - local SYSTEM_PROCESSOR='x86_64' + SYSTEM_PROCESSOR='x86_64' + jpeg_require_simd='ON' # Ensure NASM is available nasm --help >/dev/null ;; *-i686-*) - local SYSTEM_PROCESSOR='i386' + SYSTEM_PROCESSOR='i386' + jpeg_require_simd='ON' # Ensure NASM is available nasm --help >/dev/null ;; *-arm64-*) - local SYSTEM_PROCESSOR='aarch64' + SYSTEM_PROCESSOR='aarch64' + jpeg_require_simd='ON' jpeg_cmake_args+=(-DNEON_INTRINSICS=ON) ;; *-armhf-*) - local SYSTEM_PROCESSOR='arm' + SYSTEM_PROCESSOR='arm' + jpeg_require_simd='ON' jpeg_cmake_args+=(-DNEON_INTRINSICS=ON) ;; - *) - log ERROR 'Unsupported platform for JPEG' + *-armel-*) + SYSTEM_PROCESSOR='arm' + jpeg_require_simd='OFF' + jpeg_cmake_args+=(-DNEON_INTRINSICS=OFF) ;; esac @@ -639,7 +750,7 @@ build_jpeg() { jpeg_cmake_args+=(-DUNIX=True) ;; esac - + cd "${dir_name}" # -DHAVE_THREAD_LOCAL=0 overrides the compiler test to avoid the silly thread_local variable, @@ -650,6 +761,7 @@ build_jpeg() { -DENABLE_STATIC="${LIBS_STATIC}" \ -DCMAKE_SYSTEM_NAME="${SYSTEM_NAME}" \ -DCMAKE_SYSTEM_PROCESSOR="${SYSTEM_PROCESSOR}" \ + -DREQUIRE_SIMD=${jpeg_require_simd} \ -DWITH_JPEG8=1 \ -DWITH_TURBOJPEG=0 \ "${jpeg_cmake_args[@]}" @@ -736,6 +848,9 @@ build_openal() { *-armhf-*|*-arm64-*) openal_cmake_args+=(-DALSOFT_CPUEXT_NEON=ON -DALSOFT_REQUIRE_NEON=ON) ;; + *-armel-*) + openal_cmake_args+=(-DALSOFT_CPUEXT_NEON=ON -DALSOFT_REQUIRE_NEON=OFF) + ;; esac case "${PLATFORM}" in @@ -762,9 +877,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}" @@ -856,6 +971,9 @@ build_opus() { *-armhf-*|*-arm64-*) opus_cmake_args+=(-DOPUS_MAY_HAVE_NEON=OFF -DOPUS_PRESUME_NEON=ON) ;; + *-armel-*) + opus_cmake_args+=(-DOPUS_MAY_HAVE_NEON=ON -DOPUS_PRESUME_NEON=OFF) + ;; esac cd "${dir_name}" @@ -879,6 +997,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 +1017,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 +1027,42 @@ build_ncurses() { --with-default-terminfo-dir=/usr/share/terminfo } +# Build box64 +build_box64() { + local dir_name="ptitSeb-box64-${BOX64_REVISION:0:7}" + local archive_name="box64-${BOX64_REVISION}.zip" + + download_extract box64 "${archive_name}" \ + "${BOX64_BASEURL}/${BOX64_REVISION}" + + "${download_only}" && return + + cd "${dir_name}" + + cmake_build + + smart_copy 'build/box64' "${PREFIX}/box64" + + mkdir -p "${PREFIX}/libs-linux-amd64" + smart_copy -L \ + '/usr/lib/x86_64-linux-gnu/libgcc_s.so.1' \ + "${PREFIX}/libs-linux-amd64/" +} + +# "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 +1093,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 +1134,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,33 +1143,34 @@ 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-*-*) + linux-*-*|freebsd-*-*) local NACLSDK_PLATFORM=linux - local EXE= local TAR_EXT=tar ;; esac + case "${PLATFORM}" in *-i686-*) local NACLSDK_ARCH=x86_32 local DAEMON_ARCH=i686 ;; - *-amd64-*) + *-amd64-*|macos-arm64-*|linux-riscv64-*|linux-ppc64el-*|linux-loong64-*) local NACLSDK_ARCH=x86_64 local DAEMON_ARCH=amd64 ;; - *-armhf-*|linux-arm64-*) + linux-armhf-*|linux-armel-*|linux-arm64-*) local NACLSDK_ARCH=arm local DAEMON_ARCH=armhf ;; + *) + log ERROR 'Unsupported platform for NaCl SDK' + ;; esac local archive_name="naclsdk_${NACLSDK_PLATFORM}-${NACLSDK_VERSION}.${TAR_EXT}.bz2" @@ -1022,24 +1180,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" @@ -1049,47 +1201,69 @@ build_naclsdk() { rm -rf "${PREFIX}/pnacl/x86_64-nacl" rm -rf "${PREFIX}/pnacl/x86_64_bc-nacl" 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" - ;; - linux-amd64-*) - # Fix permissions on a few files which deny access to non-owner - chmod 644 "${PREFIX}/irt_core-${DAEMON_ARCH}.nexe" + windows-i686-*|linux-arm64-*) + smart_copy pepper_*"/tools/irt_core_x86_64.nexe" "${PREFIX}/irt_core-amd64.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" + esac + + case "${PLATFORM}" in + linux-*-*|freebsd-*-*) # 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/." - # 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" + chmod 644 "${PREFIX}/irt_core-amd64.nexe" ;; 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') + nacl_arch_list+=('amd64') + ;; + linux-armhf-*) + nacl_arch_list+=('armhf') + ;; + linux-armel-*) + nacl_arch_list+=('armhf') + ;; + linux-riscv64-*) + nacl_arch_list+=('amd64') + ;; + linux-ppc64el-*) + nacl_arch_list+=('amd64') + ;; + linux-loong64-*) + nacl_arch_list+=('amd64') + ;; + macos-amd64-*) + nacl_arch_list+=('amd64') + ;; + macos-arm64-*) + nacl_arch_list+=('amd64') ;; *) log ERROR 'Unsupported platform for naclruntime' @@ -1100,14 +1274,51 @@ 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) + local libdir_path='libs-linux-armhf' + + mkdir -p "${PREFIX}/${libdir_path}" + + smart_copy -L \ + '/lib/arm-linux-gnueabihf/ld-linux-armhf.so.3' \ + '/lib/arm-linux-gnueabihf/libstdc++.so.6' \ + '/lib/arm-linux-gnueabihf/libc.so.6' \ + '/lib/arm-linux-gnueabihf/libm.so.6' \ + '/lib/arm-linux-gnueabihf/libgcc_s.so.1' \ + '/lib/arm-linux-gnueabihf/librt.so.1' \ + '/lib/arm-linux-gnueabihf/libpthread.so.0' \ + "${PREFIX}/${libdir_path}/" + + patchelf --set-interpreter "${libdir_path}/ld-linux-armhf.so.3" "${PREFIX}/nacl_loader-armhf" + ;; + esac + ;; + esac + done } # Check for DLL dependencies on MinGW stuff. For MSVC platforms this is bad because it should work @@ -1235,7 +1446,7 @@ build_install() { # Fix import lib paths to use MSVC-style instead of MinGW ones (see 'genlib' target) find "${PKG_PREFIX}/lib/cmake" -name '*.cmake' -execdir sed -i -E 's@[.]dll[.]a\b@.lib@g' {} \; ;; - linux-*-*) + linux-*-*|freebsd-*-*) find "${PKG_PREFIX}/lib" -name '*.so' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*.so.*' -execdir rm -f -- {} \; find "${PKG_PREFIX}/lib" -name '*_g.a' -execdir rm -f -- {} \; @@ -1274,17 +1485,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 +1519,57 @@ 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" + if command -v ccmake >/dev/null 2>&1 + then + export COMPILER_LAUNCHER='ccache' + export CCACHE_CPP2='true' + export CCACHE_HASHDIR='true' + fi + + if [ -n "${COMPILER_LAUNCHER}" ] + then + export CC="${COMPILER_LAUNCHER} ${C_COMPILER}" + export CXX="${COMPILER_LAUNCHER} ${CXX_COMPILER}" + else + export CC="${C_COMPILER}" + export CXX="${CXX_COMPILER}" + fi - 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 LD AR RANLIB STRIP + export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS } common_setup_arch() { @@ -1334,6 +1590,18 @@ common_setup_arch() { CFLAGS+=' -march=armv7-a -mfpu=neon' CXXFLAGS+=' -march=armv7-a -mfpu=neon' ;; + *-armel-*) + CFLAGS+=' -mfpu=vfp -mfloat-abi=softfp' + CXXFLAGS+=' -mfpu=vfp -mfloat-abi=softfp' + ;; + *-riscv64-*) + ;; + *-ppc64el-*) + ;; + *-loong64-*) + ;; + *-native-*) + ;; *) log ERROR 'Unsupported platform' ;; @@ -1355,44 +1623,102 @@ 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() { LIBS_SHARED='ON' LIBS_STATIC='OFF' + C_COMPILER="${HOST}-gcc" + CXX_COMPILER="${HOST}-g++" # Libtool bug prevents -static-libgcc from being set in LDFLAGS - CC="${HOST}-gcc -static-libgcc" - CXX="${HOST}-g++ -static-libgcc" + CFLAGS+=' -static-libgcc' + CXXFLAGS+=' -static-libgcc' common_setup_windows } common_setup_mingw() { - CC="${HOST}-gcc" - CXX="${HOST}-g++" + C_COMPILER="${HOST}-gcc" + CXX_COMPILER="${HOST}-g++" common_setup_windows } common_setup_macos() { - CC='clang' - CXX='clang++' + C_COMPILER='clang' + CXX_COMPILER='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() { - CC="${HOST/-unknown-/-}-gcc" - CXX="${HOST/-unknown-/-}-g++" + C_COMPILER="${HOST/-unknown-/-}-gcc" + CXX_COMPILER="${HOST/-unknown-/-}-g++" STRIP="${HOST/-unknown-/-}-strip" CROSS_PKG_CONFIG_PATH="/usr/lib/${HOST/-unknown-/-}/pkgconfig" CFLAGS+=' -fPIC' CXXFLAGS+=' -fPIC' } +common_setup_freebsd() { + C_COMPILER='clang' + CXX_COMPILER='clang++' + STRIP='strip' + CFLAGS+=" -target ${HOST}" + CXXFLAGS+=" -target ${HOST}" + LDFLAGS+=" -target ${HOST}" +} + +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' + + export C_COMPILER='false' + export CXX_COMPILER='false' + + export COMPILER_LAUNCHER='' + + # 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,81 +1727,191 @@ 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 +# Set up environment for 32-bit little-endian hard-float arm Linux +setup_linux-armel-default() { + setup_default + common_setup linux arm-unknown-linux-gnueabi +} + +# Set up environment for 32-bit little-endian hard-float arm Linux setup_linux-armhf-default() { + setup_default common_setup linux arm-unknown-linux-gnueabihf } -# Set up environment for 64-bit arm Linux +# Set up environment for 64-bit little-endian 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 64-bit little-endian riscv Linux +setup_linux-riscv64-default() { + setup_default + common_setup linux riscv64-unknown-linux-gnu +} -base_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" -all_windows_i686_msvc_packages="${base_windows_amd64_msvc_packages}" +# Set up environment for 64-bit little-endian ppc Linux +setup_linux-ppc64el-default() { + setup_default + common_setup linux powerpc64le-unknown-linux-gnu +} + +# Set up environment for 64-bit loongarch Linux +setup_linux-loong64-default() { + setup_default + common_setup linux loongarch64-linux-gnu +} + +# Set up environment for 32-bit i686 FreeBSD +setup_freebsd-i686-default() { + setup_default + common_setup freebsd i386-unknown-freebsd +} + +# Set up environment for 64-bit amd64 FreeBSD +setup_freebsd-amd64-default() { + setup_default + common_setup freebsd x86_64-unknown-freebsd +} + +# Set up environment for native host tools +setup_native() { + setup_default + C_COMPILER='cc' + CXX_COMPILER='c++' + common_setup native native +} -base_windows_amd64_mingw_packages='zlib gmp nettle curl sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk depcheck' +setup_platform() { + case "${1}" in + native) + export PLATFORM='native-native-native' + setup_native + ;; + *) + export PLATFORM="${1}" + "setup_${PLATFORM}" + ;; + esac +} + +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_i686_default_packages="${base_linux_amd64_default_packages}" +all_linux_i686_default_packages="${all_linux_amd64_default_packages}" + +base_linux_armhf_default_packages="${base_linux_amd64_default_packages}" +all_linux_armhf_default_packages="${all_linux_amd64_default_packages}" + +base_linux_armel_default_packages="${base_linux_armhf_default_packages}" +all_linux_armel_default_packages="${all_linux_armhf_default_packages}" + +base_linux_arm64_default_packages="${base_linux_amd64_default_packages} box64" +all_linux_arm64_default_packages="${all_linux_amd64_default_packages} box64" + +base_linux_riscv64_default_packages="${base_linux_arm64_default_packages}" +all_linux_riscv64_default_packages="${all_linux_arm64_default_packages}" + +base_linux_ppc64el_default_packages="${base_linux_arm64_default_packages}" +all_linux_ppc64el_default_packages="${all_linux_arm64_default_packages}" -base_linux_amd64_default_packages="${base_linux_i686_default_packages} naclruntime" -all_linux_amd64_default_packages="${all_linux_i686_default_packages} naclruntime" +base_linux_loong64_default_packages="${base_linux_arm64_default_packages}" +all_linux_loong64_default_packages="${all_linux_arm64_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' +# FIXME: The naclruntime will fail to build, we need to download a prebuilt one. +base_freebsd_amd64_default_packages='sdl3 naclsdk saigosdk' +all_freebsd_amd64_default_packages='gmp nettle sdl3 glew png jpeg webp openal ogg vorbis opus opusfile naclsdk saigosdk' -base_linux_armhf_default_packages="${base_linux_arm64_default_packages}" -all_linux_armhf_default_packages="${all_linux_arm64_default_packages}" +base_freebsd_i686_default_packages="${base_freebsd_amd64_default_packages}" +all_freebsd_i686_default_packages="${all_freebsd_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_platforms="${all_linux_platforms} ${all_windows_platforms} ${all_macos_platforms}" +supported_linux_platforms='linux-amd64-default linux-arm64-default linux-armhf-default linux-i686-default' +supported_windows_platforms='windows-amd64-mingw windows-amd64-msvc windows-i686-mingw windows-i686-msvc' +supported_macos_platforms='macos-amd64-default macos-arm64-default' + +extra_linux_platforms='linux-armel-default linux-riscv64-default linux-ppc64el-default linux-loong64-default' +extra_freebsd_platforms='freebsd-amd64-default freebsd-i686-default' + +supported_platforms="${supported_linux_platforms} ${supported_windows_platforms} ${supported_macos_platforms}" + +all_linux_platforms="${supported_linux_platforms} ${extra_linux_platforms}" +all_windows_platforms="${supported_windows_platforms}" +all_macos_platforms="${supported_macos_platforms}" + +all_platforms="${all_linux_platforms} ${all_windows_platforms} ${all_macos_platforms} ${extra_freebsd_platforms}" printHelp() { # Please align to 4-space tabs. @@ -1492,13 +1928,18 @@ printHelp() { ${all_platforms} Virtual platforms: - linux ${all_linux_platforms} - windows ${all_windows_platforms} - macos ${all_macos_platforms} - all linux windows macos + supported-linux ${supported_linux_platforms} + supported-windows ${supported_windows_platforms} + supported-macos ${supported_macos_platforms} + supported supported-linux supported-windows supported-macos + extra-linux ${extra_linux_platforms} + extra-freebsd ${extra_freebsd_platforms} + extra extra-linux extra-freebsd + all-linux linux extra-linux + all supported extra 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 box64 Virtual packages: base build packages for pre-built binaries to be downloaded when building the game @@ -1523,21 +1964,31 @@ printHelp() { base ${base_macos_amd64_default_packages} all same + macos-arm64-default: + base ${base_macos_arm64_default_packages} + all same + linux-amd64-default: + linux-i686-default: + linux-armhf-default: + linux-armel-default: base ${base_linux_amd64_default_packages} all ${all_linux_amd64_default_packages} - linux-i686-default: - base ${base_linux_i686_default_packages} - all ${all_linux_i686_default_packages} - linux-arm64-default: - linux-armhf-default: + linux-riscv64-default: + linux-ppc64el-default: + linux-loong64-default: base ${base_linux_arm64_default_packages} all ${all_linux_arm64_default_packages} + freebsd-amd64-default: + freebsd-i686-default: + base ${base_freebsd_amd64_default_packages} + all ${all_freebsd_amd64_default_packages} + EOF - + exit } @@ -1553,24 +2004,24 @@ require_theirs='false' while [ -n "${1:-}" ] do case "${1-}" in - '--download-only') + --download-only) download_only='true' shift - ;; - '--prefer-ours') + ;; + --prefer-ours) prefer_ours='true' shift - ;; - '--require-theirs') + ;; + --require-theirs) require_theirs='true' shift - ;; - '-h'|'--help') + ;; + -h|--help) printHelp - ;; - '-'*) + ;; + -*) syntaxError 'Unknown option' - ;; + ;; *) break esac @@ -1600,18 +2051,36 @@ platform="${1}"; shift platform_list='' case "${platform}" in -'all') +all) platform_list="${all_platforms}" -;; -'linux') + ;; +supported) + platform_list="${supported_platforms}" + ;; +all-linux) platform_list="${all_linux_platforms}" + ;; +supported-linux) + platform_list="${supported_linux_platforms}" ;; -'windows') +extra-linux) + platform_list="${extra_linux_platforms}" + ;; +extra-freebsd) + platform_list="${extra_freebsd_platforms}" + ;; +all-windows) platform_list="${all_windows_platforms}" -;; -'macos') + ;; +supported-windows) + platform_list="${supported_windows_platforms}" + ;; +all-macos) platform_list="${all_macos_platforms}" -;; + ;; +supported-macos) + platform_list="${supported_macos_platforms}" + ;; *) for known_platform in ${all_platforms} do @@ -1625,11 +2094,11 @@ case "${platform}" in then syntaxError 'Unknown platform' fi -;; + ;; esac for PLATFORM in ${platform_list} do ( - "setup_${PLATFORM}" + setup_platform "${PLATFORM}" build "${@}" ) done diff --git a/src/common/IPC/Primitives.h b/src/common/IPC/Primitives.h index e5c2bcf02d..36d489da81 100644 --- a/src/common/IPC/Primitives.h +++ b/src/common/IPC/Primitives.h @@ -62,6 +62,9 @@ namespace IPC { static FileHandle FromDesc(const FileDesc& desc); int GetHandle() const { + // Do not complain about mode being unused. + Q_UNUSED(mode); + return handle; } diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index df2739b9f3..bcbeb99c03 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -75,6 +75,15 @@ 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_RUNTIME_ENABLED) +// Many BSDs have a Linuxulator, for now we only tested one. +#if defined(__linux__) || defined(__FreeBSD__) +#define DAEMON_NACL_RUNTIME_LINUX +#define DAEMON_NACL_BOOSTRAP_ENABLED +#endif // defined(__linux__) || defined(DAEMON_LINUXULATOR) +#endif // defined(DAEMON_NACL_RUNTIME_ENABLED) + +#if defined(DAEMON_NACL_RUNTIME_ENABLED) #if defined(DAEMON_NACL_BOX64_EMULATION) static Cvar::Cvar workaround_box64_disableQualification( "workaround.box64.disableQualification", @@ -88,14 +97,41 @@ static Cvar::Cvar workaround_box64_disableBootstrap( static Cvar::Cvar vm_box64_path( "vm.box64.path", - "Path to the box64 binary for NaCl emulation (empty = search PATH)", + "Path to the box64 binary for NaCl emulation (empty = use provided one or search PATH if missing)", Cvar::NONE, ""); -// Resolve box64 binary path by searching PATH if not explicitly set. -static std::string ResolveBox64Path() { - std::string path = vm_box64_path.Get(); - if (!path.empty()) { - return path; +// Resolve box64 binary path by looking for a provided one or searching PATH if not explicitly set. +static std::string ResolveBox64Path(std::string naclPath) { + std::string requestedPath = vm_box64_path.Get(); + + if (requestedPath.empty()) { + std::string providedPath = FS::Path::Build(naclPath, "box64"); + + if (FS::RawPath::FileExists(providedPath)) { + const std::string libs_linux_amd64 = "libs-linux-amd64"; + const std::string libgcc_linux_amd64 = "libgcc_s.so.1"; + + std::string libsDirPath = FS::Path::Build(naclPath, libs_linux_amd64); + std::string libGccPath = FS::Path::Build(libsDirPath, libgcc_linux_amd64); + + if (FS::RawPath::FileExists(libGccPath)) { + Sys::SetEnv("BOX64_LD_LIBRARY_PATH", libsDirPath.c_str()); + } + else { + Log::Warn("Using provided Box64 executable but the libraries are missing."); + } + + return providedPath; + } + + Log::Warn("Box64 emulation is enabled but the executable is not provided with the engine: %s", providedPath); + } + + if (!FS::RawPath::FileExists(requestedPath)) { + Sys::Error("Box64 emulation is enabled but the requested executable is missing: %s", requestedPath); + } + else { + return requestedPath; } const char* envPath = getenv("PATH"); @@ -121,34 +157,47 @@ static std::string ResolveBox64Path() { "Install Box64 or set vm.box64.path to the full path of the box64 binary."); return ""; // unreachable } -#endif +#endif // DAEMON_NACL_BOX64_EMULATION +#endif // DAEMON_NACL_RUNTIME_ENABLED + +#if defined(DAEMON_NACL_RUNTIME_ENABLED) +static constexpr bool vmAvailable = true; +#else // !defined(DAEMON_NACL_RUNTIME_ENABLED) +static constexpr bool vmAvailable = false; +#endif // !defined(DAEMON_NACL_RUNTIME_ENABLED) + +static Cvar::Cvar vm_nacl_available( + "vm.nacl.available", + "Whether NaCl runtime is available on this platform", + Cvar::ROM, vmAvailable); + +#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); +#endif // defined(DAEMON_NACL_RUNTIME_ENABLED) +#if defined(DAEMON_NACL_RUNTIME_ENABLED) +#if defined(DAEMON_NACL_RUNTIME_LINUX) && defined(YOKAI_ARCH_ARM64) +static Cvar::Cvar vm_nacl_multiarch( + "vm.nacl.multiarch", + "Use multiarch to run the NaCl loader when needed and available", + Cvar::INIT, true); +#endif // defined(DAEMON_NACL_RUNTIME_LINUX) && defined(YOKAI_ARCH_ARM64) +#endif // defined(DAEMON_NACL_RUNTIME_ENABLED) + +#if defined(DAEMON_NACL_BOOSTRAP_ENABLED) 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); - -#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 -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_BOOSTRAP_ENABLED) namespace VM { @@ -300,57 +349,229 @@ static std::pair InternalLoadModule(std::pair(probe.data()), + nullptr, + }; + + execve(probe.data(), argv, environ); + + switch (errno) + { + case ENOEXEC: + // Kernel cannot execute the probe. + _exit(100); + + case ENOENT: + case EACCES: + // Missing or inaccessible probe. + _exit(101); + + default: + _exit(102); + } + } + + int status; + if (waitpid(pid, &status, 0) < 0) { + return ArmhfSupport::Unknown; + } + + if (!WIFEXITED(status)) { + return ArmhfSupport::Unknown; + } + + switch (WEXITSTATUS(status)) + { + case 100: + return ArmhfSupport::Unsupported; + + case 101: + case 102: + return ArmhfSupport::Unknown; + + default: + // The execve() call succeeded, so the probe has been executed properly. + return ArmhfSupport::Supported; + } +} +#endif // defined(DAEMON_NACL_RUNTIME_LINUX) && defined(NACL_ARCH_ARM64) + +#if defined(DAEMON_NACL_RUNTIME_ENABLED) static 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 - const char* naclPath = DAEMON_NACL_RUNTIME_PATH_STRING; -#else - const std::string& naclPath = libPath; -#endif std::vector args; char rootSocketRedir[32]; - std::string module, nacl_loader, irt, bootstrap, modulePath, verbosity; FS::File stderrRedirect; -#if defined(DAEMON_NACL_BOX64_EMULATION) - std::string box64Path; - bool usingBox64 = false; -#endif + bool inheritEnvironment = false; + +#if defined(DAEMON_NACL_RUNTIME_PATH) + const char* naclPath = DAEMON_NACL_RUNTIME_PATH_STRING; +#else // !defined(DAEMON_NACL_RUNTIME_PATH) + const std::string& naclPath = libPath; +#endif // !defined(DAEMON_NACL_RUNTIME_PATH) + #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; + constexpr bool i686ForceAmd64 = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64; +#endif // !( !defined(_WIN32) || defined(_WIN64) ) + + std::string multiarchPath; + +#if defined(DAEMON_NACL_RUNTIME_LINUX) && defined(YOKAI_ARCH_ARM64) + bool hasMultiarch = vm_nacl_multiarch.Get(); +#else + constexpr bool hasMultiarch = false; + Q_UNUSED(multiarchPath); #endif + std::string bootstrapPath; + +#if defined(DAEMON_NACL_BOOSTRAP_ENABLED) + bool hasBootstrap = vm_nacl_bootstrap.Get(); +#else // !defined(DAEMON_NACL_BOOSTRAP_ENABLED) + constexpr bool hasBootstrap = false; + Q_UNUSED(bootstrapPath); +#endif // !defined(DAEMON_NACL_BOOSTRAP_ENABLED) + + std::string box64Path; + +#if defined(DAEMON_NACL_BOX64_EMULATION) + constexpr bool hasBox64 = true; +#else // !defined(DAEMON_NACL_BOX64_EMULATION) + constexpr bool hasBox64 = false; + Q_UNUSED(box64Path); +#endif // !defined(DAEMON_NACL_BOX64_EMULATION) + +#if defined(DAEMON_NACL_RUNTIME_LINUX) && defined(YOKAI_ARCH_ARM64) + /* We later turn this boolean off when we detect armhf support is not + provided on arm64. */ + bool hasArmhf = true; +#endif // !defined(YOKAI_ARCH_ARMHF) + + bool useMultiarch = hasMultiarch; + bool useBox64 = hasBox64; + +#if defined(DAEMON_NACL_RUNTIME_LINUX) && defined(YOKAI_ARCH_ARM64) + const std::string libs_linux_armhf = "libs-linux-armhf"; + const std::string libld_linux_armhf = "ld-linux-armhf.so.3"; + + std::string libsDirPath = FS::Path::Build(libPath, libs_linux_armhf); + std::string libLoaderPath = FS::Path::Build(libsDirPath, libld_linux_armhf); + + switch (CheckArmhfSupport(libLoaderPath)) + { + case ArmhfSupport::Supported: + Log::Notice("Working multiarch support."); + break; + + case ArmhfSupport::Unsupported: + Log::Notice("Unsupported multiarch."); + hasArmhf = false; + break; + + case ArmhfSupport::Unknown: + Log::Warn("Cannot determine multiarch support."); + hasArmhf = false; + break; + } + + if (!hasArmhf) { + useMultiarch = false; + } +#endif // defined(DAEMON_NACL_RUNTIME_LINUX) && defined(YOKAI_ARCH_ARM64) + + if (useMultiarch && useBox64) { + Log::Notice("Preferring multiarch over Box64 emulation."); + useBox64 = false; + } + + bool useBootstrap = hasBootstrap; + +#if defined(DAEMON_NACL_BOX64_EMULATION) + if (useBootstrap) { + /* 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 (useBox64 + && workaround_box64_disableBootstrap.Get()) { + useBootstrap = false; + } + } +#endif // defined(DAEMON_NACL_BOX64_EMULATION) + + std::string arch = (useBox64 || i686ForceAmd64) ? "amd64" : DAEMON_NACL_ARCH_STRING; + + std::string moduleName = Str::Format("%s-%s.nexe", name, arch); + std::string irt = FS::Path::Build(naclPath, Str::Format("irt_core-%s.nexe", arch)); + std::string nacl_loader = FS::Path::Build(naclPath, Str::Format("nacl_loader-%s%s", arch, EXE_EXT)); + + if (useMultiarch) { + multiarchPath = FS::Path::Build(naclPath, Str::Format("nacl_multiarch-%s", arch)); + } + + if (useBootstrap) { + bootstrapPath = FS::Path::Build(naclPath, Str::Format("nacl_helper_bootstrap-%s", arch)); + } + + std::string modulePath; + // 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); - if (const FS::LoadedPakInfo* pak = FS::PakPath::LocateFile(module)) - Log::Notice("Extracting VM module %s from %s...", module.c_str(), pak->path.c_str()); - FS::PakPath::CopyFile(module, out); + FS::File out = FS::HomePath::OpenWrite(moduleName); + if (const FS::LoadedPakInfo* pak = FS::PakPath::LocateFile(moduleName)) + Log::Notice("Extracting VM module %s from %s...", moduleName.c_str(), pak->path.c_str()); + FS::PakPath::CopyFile(moduleName, out); out.Close(); } catch (std::system_error& err) { - Sys::Drop("VM: Failed to extract VM module %s: %s", module, err.what()); + Sys::Drop("VM: Failed to extract VM module %s: %s", moduleName, err.what()); } - modulePath = FS::Path::Build(FS::GetHomePath(), module); + modulePath = FS::Path::Build(FS::GetHomePath(), moduleName); } else { - modulePath = FS::Path::Build(libPath, module); + modulePath = FS::Path::Build(libPath, moduleName); } // Generate command line Q_snprintf(rootSocketRedir, sizeof(rootSocketRedir), "%d:%d", ROOT_SOCKET_FD, (int)(intptr_t)pair.second.GetHandle()); - irt = FS::Path::Build(naclPath, win32Force64Bit - ? "irt_core-amd64.nexe" - : Str::Format("irt_core-%s.nexe", DAEMON_NACL_ARCH_STRING)); - nacl_loader = FS::Path::Build(naclPath, win32Force64Bit ? "nacl_loader-amd64" EXE_EXT : "nacl_loader" EXE_EXT); if (!FS::RawPath::FileExists(modulePath)) { Sys::Error("VM module file not found: %s", modulePath); @@ -364,99 +585,105 @@ static std::pair CreateNaClVM(std::pair Error while loading "sgame-armhf.nexe": CPU model is not supported + > Error while loading "sgame-armhf.nexe": CPU model is not supported - From nacl_loader --help we can read: + From nacl_loader --help we can read: - > -Q disable platform qualification (dangerous!) + > -Q disable platform qualification (dangerous!) - When this option is enabled, nacl_loader will print: + When this option is enabled, nacl_loader will print: - > PLATFORM QUALIFICATION DISABLED BY -Q - Native Client's sandbox will be unreliable! + > PLATFORM QUALIFICATION DISABLED BY -Q - Native Client's sandbox will be unreliable! - But the nexe will load and run. */ + But the nexe will load and run. */ - if (onArm64) { - Log::Warn("Disabling NaCL platform qualification on arm64 kernel architecture."); - enableQualification = false; - } + if (onArm64) { + Log::Warn("Disabling NaCl platform qualification on arm64 kernel architecture."); + enableQualification = false; } -#endif + } +#endif // defined(__linux__) && (defined(YOKAI_ARCH_ARM64) || defined(YOKAI_ARCH_ARMHF)) + +#if defined(DAEMON_NACL_BOX64_EMULATION) + if (enableQualification + && useBox64 + && workaround_box64_disableQualification.Get()) { + /* When running the amd64 NaCl loader under Box64, the loader's + platform qualification will fail because the CPU is not actually x86_64. + Disabling qualification allows the emulated loader to proceed. */ + + Log::Warn("Disabling NaCl platform qualification for Box64 emulation."); + enableQualification = false; + } +#endif // defined(DAEMON_NACL_BOX64_EMULATION) #if defined(__FreeBSD__) + if (enableQualification + && workaround_naclSystem_freebsd_disableQualification.Get()) { /* While it is possible to build a native FreeBSD engine, the only available NaCl loader is the Linux one, which can run on Linuxulator (the FreeBSD Linux compatibility layer). @@ -466,26 +693,10 @@ static 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 +832,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_multiarch/nacl_multiarch.cpp similarity index 84% rename from tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp rename to tools/nacl_multiarch/nacl_multiarch.cpp index ec16447482..10dd88671d 100644 --- a/tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp +++ b/tools/nacl_multiarch/nacl_multiarch.cpp @@ -35,7 +35,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include "YokaiBuildInfo/DaemonEngine.h" + int main(int argc, char *argv[]) { + if (argc < 2) { + printf("nacl_multiarch-%s: missing command line\n", DAEMON_NACL_ARCH_STRING); + return 1; + } + char *directory = dirname(strdup(argv[0])); int err = chdir(directory); @@ -44,19 +51,18 @@ int main(int argc, char *argv[]) { return err; } - err = putenv(strdup("LD_LIBRARY_PATH=lib-armhf")); + char env[100]; + sprintf(env, "LD_LIBRARY_PATH=libs-linux-%s", DAEMON_NACL_ARCH_STRING); + + err = putenv(strdup(env)); if (err != 0) { return err; } - char *helper = strdup("./nacl_helper_bootstrap"); - argv[0] = helper; - - execv(helper, argv); + execv(argv[1], &argv[1]); // The execv() function returns only if an error has occurred. - printf("nacl_helper_bootstrap-armhf: %s\n", strerror(errno)); - + printf("nacl_ld_bootstrap-%s: %s\n", DAEMON_NACL_ARCH_STRING, strerror(errno)); return 1; }