diff --git a/CMakeLists.txt b/CMakeLists.txt index 44827a97f..f20fecf58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ endif() if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(TARGET_OS "windows") -elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Emscripten") set(TARGET_OS "linux") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(TARGET_OS "mac") @@ -83,7 +83,9 @@ endif() include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) include(CheckSymbolExists) -include(CheckAtomic) +if(NOT (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")) + include(CheckAtomic) +endif() check_symbol_exists(__i386 "" TARGET_ARCH_X86_i386) if(TARGET_ARCH_X86_i386) @@ -125,6 +127,10 @@ option(VULKAN "Enable the vulkan backend" ${AUTO_VULKAN_BACKEND}) option(EXCEPTION_HANDLING "Enable exception handling (only works with Windows as of now)" OFF) +if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + include(${PROJECT_SOURCE_DIR}/cmake/toolchains/Emscripten.toolchain) +endif() + if(TEST_MYSQL) set(MYSQL ON) endif() @@ -358,6 +364,8 @@ endif() if(FAT) set(LIB_DIR "${TARGET_OS}/libfat") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + set(LIB_DIR "webasm/libwasm") elseif(TARGET_CPU_ARCHITECTURE STREQUAL "arm" OR TARGET_CPU_ARCHITECTURE STREQUAL "arm64") set(LIB_DIR "${TARGET_OS}/lib${TARGET_CPU_ARCHITECTURE}") else() @@ -384,12 +392,16 @@ function(set_extra_dirs_include VARIABLE NAME LIBRARY) set("HINTS_${VARIABLE}_INCLUDEDIR" PARENT_SCOPE) is_bundled(IS_BUNDLED "${LIBRARY}") if(IS_BUNDLED) - set("HINTS_${VARIABLE}_INCLUDEDIR" "ddnet-libs/${NAME}/include" "ddnet-libs/${NAME}/include/${TARGET_OS}" PARENT_SCOPE) + set(TMP_TARGET_OS ${TARGET_OS}) + if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + set(TMP_TARGET_OS webasm) + endif() + set("HINTS_${VARIABLE}_INCLUDEDIR" "ddnet-libs/${NAME}/include" "ddnet-libs/${NAME}/include/${TMP_TARGET_OS}" PARENT_SCOPE) endif() endfunction() if(CMAKE_CROSSCOMPILING) - if(TARGET_OS STREQUAL "android") + if(TARGET_OS STREQUAL "android" OR CMAKE_SYSTEM_NAME STREQUAL "Emscripten") # be more aggressive with android toolchain set(CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH NO_CMAKE_SYSTEM_PATH NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) else() @@ -656,6 +668,12 @@ else() endif() endif() +if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + set(PLATFORM_CLIENT_LIBS GL) + set(PLATFORM_CLIENT_INCLUDE_DIRS "") + set(CMAKE_EXECUTABLE_SUFFIX ".html") +endif() + ######################################################################## # DOWNLOAD GTEST ######################################################################## @@ -2961,6 +2979,9 @@ foreach(target ${TARGETS_OWN}) if(VERSION) target_compile_definitions(${target} PRIVATE GAME_RELEASE_VERSION="${VERSION}") endif() + if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + target_compile_definitions(${target} PRIVATE CONF_WEBASM) + endif() endforeach() foreach(target ${TARGETS_DEP}) diff --git a/README.md b/README.md index ed682068f..09df1fc8d 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,34 @@ Install MinGW cross-compilers of the form `i686-w64-mingw32-gcc` (32 bit) or Then add `-DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/mingw64.toolchain` to the **initial** CMake command line. +Cross-compiling on Linux to Web Assembler vis Emscripten +-------------------------------------------------------- + +Install Emscripten cross-compilers (e.g. `sudo apt install emscripten`) on a modern linux distro. + +Then run `emcmake cmake .. -DVIDEORECORDER=OFF -DVULKAN=OFF -DSERVER=OFF -DTOOLS=OFF -DPREFER_BUNDLED_LIBS=ON` in your build directory. + +To test the compiled code locally, just use `emrun --browser firefox DDNet.html` + +To host the compiled .html file copy all `.data`, `.html`, `.js`, `.wasm` files to the web server. (see /other/emscripten/minimal.html for a minimal html example) + +Then enable cross origin policies. Example for apache2 on debian based distros: +```bash +sudo a2enmod header + +# edit the apache2 config to allow .htaccess files +sudo nano /etc/apache2/apache2.conf + +# set AllowOverride to All for your directory +# then create a .htaccess file on the web server (where the .html is) +# and add these lines +Header add Cross-Origin-Embedder-Policy "require-corp" +Header add Cross-Origin-Opener-Policy "same-origin" + +# now restart apache2 +sudo service apache2 restart +``` + Cross-compiling on Linux to macOS --------------------------------- diff --git a/cmake/FindCrypto.cmake b/cmake/FindCrypto.cmake index 138e08996..eaa4aa14f 100644 --- a/cmake/FindCrypto.cmake +++ b/cmake/FindCrypto.cmake @@ -8,7 +8,7 @@ if(NOT PREFER_BUNDLED_LIBS) endif() endif() -if(PREFER_BUNDLED_LIBS AND TARGET_OS STREQUAL "android") +if(PREFER_BUNDLED_LIBS AND (TARGET_OS STREQUAL "android" OR CMAKE_SYSTEM_NAME STREQUAL "Emscripten")) set_extra_dirs_lib(CRYPTO openssl) find_library(CRYPTO_LIBRARY1 NAMES crypto diff --git a/cmake/FindZLIB.cmake b/cmake/FindZLIB.cmake index 87cbd89ea..35f68b201 100644 --- a/cmake/FindZLIB.cmake +++ b/cmake/FindZLIB.cmake @@ -8,6 +8,35 @@ if(NOT PREFER_BUNDLED_LIBS) endif() endif() +if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + set_extra_dirs_lib(ZLIB zlib) + find_library(ZLIB_LIBRARY + NAMES z + HINTS ${HINTS_ZLIB_LIBDIR} ${PC_ZLIB_LIBDIR} ${PC_ZLIB_LIBRARY_DIRS} + PATHS ${PATHS_ZLIB_LIBDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} + ) + set_extra_dirs_include(ZLIB zlib "${ZLIB_LIBRARY}") + find_path(ZLIB_INCLUDEDIR1 zlib.h + PATH_SUFFIXES zlib + HINTS ${HINTS_ZLIB_INCLUDEDIR} ${PC_ZLIB_INCLUDEDIR} ${PC_ZLIB_INCLUDE_DIRS} + PATHS ${PATHS_ZLIB_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} + ) + find_path(ZLIB_INCLUDEDIR2 zconf.h + PATH_SUFFIXES zlib + HINTS ${HINTS_ZLIB_INCLUDEDIR} ${PC_ZLIB_INCLUDEDIR} ${PC_ZLIB_INCLUDE_DIRS} + PATHS ${PATHS_ZLIB_INCLUDEDIR} + ${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH} + ) + + if(ZLIB_LIBRARY AND ZLIB_INCLUDEDIR1 AND ZLIB_INCLUDEDIR2) + set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDEDIR1} ${ZLIB_INCLUDEDIR2}) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) + set(ZLIB_FOUND TRUE) + endif() +endif() + if(NOT ZLIB_FOUND) set(ZLIB_BUNDLED ON) set(ZLIB_SRC_DIR src/engine/external/zlib) diff --git a/cmake/toolchains/Emscripten.toolchain b/cmake/toolchains/Emscripten.toolchain new file mode 100644 index 000000000..0ed57443b --- /dev/null +++ b/cmake/toolchains/Emscripten.toolchain @@ -0,0 +1,37 @@ +set(WASM_CXX_ENGINE_FLAGS "") +set(WASM_ENGINE_FLAGS "") +set(WASM_ENGINE_FLAGS "-s LLD_REPORT_UNDEFINED -s USE_PTHREADS=1") +# needed for loading files in a c-like style +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s FILESYSTEM=1 -s FORCE_FILESYSTEM=1") +# load data directory to the filesystem +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} --preload-file data") +# remove some annoyance for now, TODO +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} --allow-multiple-definition -Wl,--shared-memory,--no-check-features") +# TODO +#set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -lwebsocket.js -s PROXY_POSIX_SOCKETS=1") +# use Web Assmebly & a WebGL2 comptatible GLES3 implementation +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s WASM=1") +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s USE_WEBGL2=1") +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s FULL_ES3=1") +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[\"$autoResumeAudioContext, $dynCall\"]") +# this flag is the most important one. It tells SDL2 to call emscripten functions when polling event +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s ASYNCIFY=1") +# TODO, has to be fixed in SDL2, can improve responsivness of the site +#set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s PROXY_TO_PTHREAD=1") +# SDL2 is compiled by the gen_libs.sh script for easy up to date code +#set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s USE_SDL=2") +#set(WASM_CXX_ENGINE_FLAGS "${WASM_CXX_ENGINE_FLAGS} -s USE_SDL=2") +# even if slower, memory growth has the advantage of using less resources, keep it on for now (instead of a static memory pool) +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s ALLOW_MEMORY_GROWTH=1") +#set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s INITIAL_MEMORY=2000MB") +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s MAXIMUM_MEMORY=2000MB") +# not optimal but required so that threads are created on fly (instead of delayed when the next javascript calls come in) +set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -s PTHREAD_POOL_SIZE=10") +if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug")) + # will drastically reduce code size + set(WASM_ENGINE_FLAGS "${WASM_ENGINE_FLAGS} -flto") +endif() +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -D_REENTRANT -g -O3 ${WASM_CXX_ENGINE_FLAGS}") +set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -pthread -D_REENTRANT -g -O3 ${WASM_CXX_ENGINE_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread ${WASM_ENGINE_FLAGS}") +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${WASM_ENGINE_FLAGS}") diff --git a/other/emscripten/minimal.html b/other/emscripten/minimal.html new file mode 100644 index 000000000..2a5e51c57 --- /dev/null +++ b/other/emscripten/minimal.html @@ -0,0 +1,44 @@ + + + + + + + + +

+ + + + diff --git a/scripts/android/README.md b/scripts/android/README.md index 6a046cf22..985ea15fb 100644 --- a/scripts/android/README.md +++ b/scripts/android/README.md @@ -47,7 +47,7 @@ How to build: How to build the ddnet-libs for Android: ======================================== - There is a script to automatically download and build all repositories, this requires an active internet connection: - `scripts/android/gen_android_libs.sh ` + `scripts/compile_libs/gen_libs.sh android` Warning!: DO NOT CHOOSE A DIRECTORY INSIDE THE SOURCE TREE After the script finished executing it should have created a ddnet-libs directory which created all libs in the right directory format and can be merged with ddnet-libs in the source directory diff --git a/scripts/android/cmake_lib_compile.sh b/scripts/android/cmake_lib_compile.sh deleted file mode 100755 index c0c6298b7..000000000 --- a/scripts/android/cmake_lib_compile.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -ANDROID_HOME=~/Android/Sdk -ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" -echo "$ANDROID_NDK" - -export MAKEFLAGS=-j32 - -function compile_source() { - cmake \ - -H. \ - -G "Unix Makefiles" \ - -DCMAKE_BUILD_TYPE=Release \ - -DANDROID_NATIVE_API_LEVEL="android-$1" \ - -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \ - -DANDROID_ABI="${3}" \ - -DANDROID_ARM_NEON=TRUE \ - -B"$2" \ - -DBUILD_SHARED_LIBS=OFF \ - -DHIDAPI_SKIP_LIBUSB=TRUE \ - -DCURL_USE_OPENSSL=ON \ - -DSDL_HIDAPI=OFF \ - -DOP_DISABLE_HTTP=ON \ - -DOP_DISABLE_EXAMPLES=ON \ - -DOP_DISABLE_DOCS=ON \ - -DOPENSSL_ROOT_DIR="$PWD"/../openssl/"$2" \ - -DOPENSSL_CRYPTO_LIBRARY="$PWD"/../openssl/"$2"/libcrypto.a \ - -DOPENSSL_SSL_LIBRARY="$PWD"/../openssl/"$2"/libssl.a \ - -DOPENSSL_INCLUDE_DIR="${PWD}/../openssl/include;${PWD}/../openssl/${2}/include" - ( - cd "$2" || exit 1 - cmake --build . - ) -} - -compile_source "$1" build_android_arm armeabi-v7a & -compile_source "$1" build_android_arm64 arm64-v8a & -compile_source "$1" build_android_x86 x86 & -compile_source "$1" build_android_x86_64 x86_64 & - -wait diff --git a/scripts/android/gen_android_libs.sh b/scripts/android/gen_android_libs.sh deleted file mode 100755 index a01eed19d..000000000 --- a/scripts/android/gen_android_libs.sh +++ /dev/null @@ -1,179 +0,0 @@ -#!/bin/bash - -CURDIR="$PWD" -if [ -z ${1+x} ]; then - echo "Give a destination path where to run this script, please choose a path other than in the source directory" - exit 1 -fi - -mkdir -p "$1" -cd "$1" || exit 1 - -function build_cmake_lib() { - if [ ! -d "${1}" ]; then - git clone "${2}" "${1}" - fi - ( - cd "${1}" || exit 1 - cp "${CURDIR}"/scripts/android/cmake_lib_compile.sh cmake_lib_compile.sh - ./cmake_lib_compile.sh "$_ANDROID_ABI_LEVEL" - ) -} - -_ANDROID_ABI_LEVEL=24 - -mkdir -p android_libs -cd android_libs || exit 1 - -# start with openssl -( - _WAS_THERE_SSLFILE=1 - if [ ! -d "openssl" ]; then - git clone https://github.com/openssl/openssl openssl - _WAS_THERE_SSLFILE=0 - fi - ( - cd openssl || exit 1 - if [[ "$_WAS_THERE_SSLFILE" == 0 ]]; then - ./autogen.sh - fi - cp "${CURDIR}"/scripts/android/make_android_openssl.sh make_android_openssl.sh - ./make_android_openssl.sh "$_ANDROID_ABI_LEVEL" - ) -) - -build_cmake_lib curl https://github.com/curl/curl -build_cmake_lib freetype2 https://gitlab.freedesktop.org/freetype/freetype -build_cmake_lib sdl https://github.com/libsdl-org/SDL -build_cmake_lib ogg https://github.com/xiph/ogg -build_cmake_lib opus https://github.com/xiph/opus -( - _WAS_THERE_OPUSFILE=1 - if [ ! -d "opusfile" ]; then - git clone https://github.com/xiph/opusfile opusfile - _WAS_THERE_OPUSFILE=0 - fi - cd opusfile || exit 1 - if [[ "$_WAS_THERE_OPUSFILE" == 0 ]]; then - ./autogen.sh - fi - cp "${CURDIR}"/scripts/android/make_android_opusfile.sh make_android_opusfile.sh - ./make_android_opusfile.sh "$_ANDROID_ABI_LEVEL" -) - -# SQLite, just download and built by hand -if [ ! -d "sqlite3" ]; then - wget https://www.sqlite.org/2021/sqlite-amalgamation-3360000.zip - 7z e sqlite-amalgamation-3360000.zip -osqlite3 -fi - -( - cd sqlite3 || exit 1 - cp "${CURDIR}"/scripts/android/make_android_sqlite3.sh make_android_sqlite3.sh - ./make_android_sqlite3.sh "$_ANDROID_ABI_LEVEL" -) - -cd .. - -mkdir ddnet-libs -function _copy_curl() { - mkdir -p ddnet-libs/curl/android/lib"$2" - cp android_libs/curl/build_android_"$1"/lib/libcurl.a ddnet-libs/curl/android/lib"$2"/libcurl.a -} - -_copy_curl arm arm -_copy_curl arm64 arm64 -_copy_curl x86 32 -_copy_curl x86_64 64 - -mkdir ddnet-libs -function _copy_freetype2() { - mkdir -p ddnet-libs/freetype/android/lib"$2" - cp android_libs/freetype2/build_android_"$1"/libfreetype.a ddnet-libs/freetype/android/lib"$2"/libfreetype.a -} - -_copy_freetype2 arm arm -_copy_freetype2 arm64 arm64 -_copy_freetype2 x86 32 -_copy_freetype2 x86_64 64 - -mkdir ddnet-libs -function _copy_sdl() { - mkdir -p ddnet-libs/sdl/android/lib"$2" - cp android_libs/sdl/build_android_"$1"/libSDL2.a ddnet-libs/sdl/android/lib"$2"/libSDL2.a - cp android_libs/sdl/build_android_"$1"/libSDL2main.a ddnet-libs/sdl/android/lib"$2"/libSDL2main.a - if [ ! -d "ddnet-libs/sdl/include/android" ]; then - mkdir -p ddnet-libs/sdl/include/android - fi - cp -R android_libs/sdl/include/* ddnet-libs/sdl/include/android -} - -_copy_sdl arm arm -_copy_sdl arm64 arm64 -_copy_sdl x86 32 -_copy_sdl x86_64 64 - -# copy java code from SDL2 -rm -R ddnet-libs/sdl/java -mkdir -p ddnet-libs/sdl/java -cp -R android_libs/sdl/android-project/app/src/main/java/org ddnet-libs/sdl/java/ - -mkdir ddnet-libs -function _copy_ogg() { - mkdir -p ddnet-libs/opus/android/lib"$2" - cp android_libs/ogg/build_android_"$1"/libogg.a ddnet-libs/opus/android/lib"$2"/libogg.a -} - -_copy_ogg arm arm -_copy_ogg arm64 arm64 -_copy_ogg x86 32 -_copy_ogg x86_64 64 - -mkdir ddnet-libs -function _copy_opus() { - mkdir -p ddnet-libs/opus/android/lib"$2" - cp android_libs/opus/build_android_"$1"/libopus.a ddnet-libs/opus/android/lib"$2"/libopus.a -} - -_copy_opus arm arm -_copy_opus arm64 arm64 -_copy_opus x86 32 -_copy_opus x86_64 64 - -mkdir ddnet-libs -function _copy_opusfile() { - mkdir -p ddnet-libs/opus/android/lib"$2" - cp android_libs/opusfile/build_"$1"/libopusfile.a ddnet-libs/opus/android/lib"$2"/libopusfile.a -} - -_copy_opusfile arm arm -_copy_opusfile arm64 arm64 -_copy_opusfile x86 32 -_copy_opusfile x86_64 64 - -mkdir ddnet-libs -function _copy_sqlite3() { - mkdir -p ddnet-libs/sqlite3/android/lib"$2" - cp android_libs/sqlite3/build_"$1"/sqlite3.a ddnet-libs/sqlite3/android/lib"$2"/libsqlite3.a -} - -_copy_sqlite3 arm arm -_copy_sqlite3 arm64 arm64 -_copy_sqlite3 x86 32 -_copy_sqlite3 x86_64 64 - -mkdir ddnet-libs -function _copy_openssl() { - mkdir -p ddnet-libs/openssl/android/lib"$2" - mkdir -p ddnet-libs/openssl/include - mkdir -p ddnet-libs/openssl/include/android - cp android_libs/openssl/build_android_"$1"/libcrypto.a ddnet-libs/openssl/android/lib"$2"/libcrypto.a - cp android_libs/openssl/build_android_"$1"/libssl.a ddnet-libs/openssl/android/lib"$2"/libssl.a - cp -R android_libs/openssl/build_android_"$1"/include/* ddnet-libs/openssl/include/android - cp -R android_libs/openssl/include/* ddnet-libs/openssl/include -} - -_copy_openssl arm arm -_copy_openssl arm64 arm64 -_copy_openssl x86 32 -_copy_openssl x86_64 64 diff --git a/scripts/android/make_android_openssl.sh b/scripts/android/make_android_openssl.sh deleted file mode 100755 index cdbddf21b..000000000 --- a/scripts/android/make_android_openssl.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -ANDROID_HOME=~/Android/Sdk -ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" - -export MAKEFLAGS=-j32 - -export ANDROID_NDK_ROOT=$ANDROID_NDK -PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH - -function buid_openssl() { - _EXISTS_PROJECT=0 - if [ -d "$1" ]; then - _EXISTS_PROJECT=1 - else - mkdir "$1" - fi - ( - cd "$1" || exit 1 - if [[ "$_EXISTS_PROJECT" == "0" ]]; then - ../Configure "$2" no-asm no-shared - fi - make $MAKEFLAGS build_generated - make $MAKEFLAGS libcrypto.a - make $MAKEFLAGS libssl.a - cd .. - ) -} - -buid_openssl build_android_arm android-arm "$1" -buid_openssl build_android_arm64 android-arm64 "$1" -buid_openssl build_android_x86 android-x86 "$1" -buid_openssl build_android_x86_64 android-x86_64 "$1" diff --git a/scripts/android/make_android_sqlite3.sh b/scripts/android/make_android_sqlite3.sh deleted file mode 100755 index 2acc36033..000000000 --- a/scripts/android/make_android_sqlite3.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -ANDROID_HOME=~/Android/Sdk -ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" - -export MAKEFLAGS=-j32 - -export ANDROID_NDK_ROOT="$ANDROID_NDK" -PATH="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH" -_LD_LIBRARY_PATH=".:$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$LD_LIBRARY_PATH" - -function make_sqlite3() { - ( - mkdir -p "$1" - cd "$1" || exit 1 - LDFLAGS="-L./" \ - LD_LIBRARY_PATH="$_LD_LIBRARY_PATH" \ - "$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/$3$4-clang" \ - -c \ - -fPIC \ - ../sqlite3.c \ - -o sqlite3.o - - LDFLAGS="-L./" \ - LD_LIBRARY_PATH="$_LD_LIBRARY_PATH" \ - "$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" \ - rvs \ - sqlite3.a \ - sqlite3.o - ) -} - -function compile_all_sqlite3() { - make_sqlite3 build_arm build_android_arm armv7a-linux-androideabi "$1" - make_sqlite3 build_arm64 build_android_arm64 aarch64-linux-android "$1" - make_sqlite3 build_x86 build_android_x86 i686-linux-android "$1" - make_sqlite3 build_x86_64 build_android_x86_64 x86_64-linux-android "$1" -} - -compile_all_sqlite3 "$1" - diff --git a/scripts/compile_libs/cmake_lib_compile.sh b/scripts/compile_libs/cmake_lib_compile.sh new file mode 100755 index 000000000..ba11a4a19 --- /dev/null +++ b/scripts/compile_libs/cmake_lib_compile.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +ANDROID_HOME=~/Android/Sdk +ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" +echo "$ANDROID_NDK" + +export MAKEFLAGS=-j32 + +if [[ "${2}" == "webasm" ]]; then + COMPILEFLAGS="-pthread -O3 -g -s USE_PTHREADS=1" + LINKFLAGS="-pthread -O3 -g -s USE_PTHREADS=1 -s ASYNCIFY=1" +fi + +COMPILEFLAGS=$3 +LINKFLAGS=$4 + +function compile_source() { + if [[ "${4}" == "android" ]]; then + cmake \ + -H. \ + -G "Unix Makefiles" \ + -DCMAKE_BUILD_TYPE=Release \ + -DANDROID_NATIVE_API_LEVEL="android-$1" \ + -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \ + -DANDROID_ABI="${3}" \ + -DANDROID_ARM_NEON=TRUE \ + -B"$2" \ + -DBUILD_SHARED_LIBS=OFF \ + -DHIDAPI_SKIP_LIBUSB=TRUE \ + -DCURL_USE_OPENSSL=ON \ + -DSDL_HIDAPI=OFF \ + -DOP_DISABLE_HTTP=ON \ + -DOP_DISABLE_EXAMPLES=ON \ + -DOP_DISABLE_DOCS=ON \ + -DOPENSSL_ROOT_DIR="$PWD"/../openssl/"$2" \ + -DOPENSSL_CRYPTO_LIBRARY="$PWD"/../openssl/"$2"/libcrypto.a \ + -DOPENSSL_SSL_LIBRARY="$PWD"/../openssl/"$2"/libssl.a \ + -DOPENSSL_INCLUDE_DIR="${PWD}/../openssl/include;${PWD}/../openssl/${2}/include" + ( + cd "$2" || exit 1 + cmake --build . + ) + else + ${5} cmake \ + -H. \ + -DCMAKE_BUILD_TYPE=Release \ + -B"$2" \ + -DSDL_STATIC=TRUE \ + -DFT_DISABLE_HARFBUZZ=ON \ + -DFT_DISABLE_BZIP2=ON \ + -DFT_DISABLE_BROTLI=ON \ + -DFT_REQUIRE_ZLIB=TRUE \ + -DCMAKE_C_FLAGS="$COMPILEFLAGS -DGLEW_STATIC" -DCMAKE_CXX_FLAGS="$COMPILEFLAGS" -DCMAKE_CXX_FLAGS_RELEASE="$COMPILEFLAGS" -DCMAKE_C_FLAGS_RELEASE="$COMPILEFLAGS" \ + -DCMAKE_SHARED_LINKER_FLAGS="$LINKFLAGS" -DCMAKE_SHARED_LINKER_FLAGS_RELEASE="$LINKFLAGS" \ + -DSDL_PTHREADS=ON -DSDL_THREADS=ON \ + -DCURL_USE_OPENSSL=ON \ + -DOPUS_HARDENING=OFF \ + -DOPUS_STACK_PROTECTOR=OFF \ + -DOPENSSL_ROOT_DIR="$PWD"/../openssl/"$2" \ + -DOPENSSL_CRYPTO_LIBRARY="$PWD"/../openssl/"$2"/libcrypto.a \ + -DOPENSSL_SSL_LIBRARY="$PWD"/../openssl/"$2"/libssl.a \ + -DOPENSSL_INCLUDE_DIR="${PWD}/../openssl/include;${PWD}/../openssl/${2}/include" \ + -DZLIB_LIBRARY="${PWD}/../zlib/${2}/libz.a" -DZLIB_INCLUDE_DIR="${PWD}/../zlib;${PWD}/../zlib/${2}" + ( + cd "$2" || exit 1 + cmake --build . + ) + fi +} + +if [[ "${2}" == "android" ]]; then + compile_source "$1" build_"$2"_arm armeabi-v7a "$2" "" & + compile_source "$1" build_"$2"_arm64 arm64-v8a "$2" "" & + compile_source "$1" build_"$2"_x86 x86 "$2" "" & + compile_source "$1" build_"$2"_x86_64 x86_64 "$2" "" & +elif [[ "${2}" == "webasm" ]]; then + sed -i "s/include(CheckSizes)//g" CMakeLists.txt + compile_source "$1" build_"$2"_wasm wasm "$2" emcmake & +fi + +wait diff --git a/scripts/compile_libs/gen_libs.sh b/scripts/compile_libs/gen_libs.sh new file mode 100755 index 000000000..e41bdf53a --- /dev/null +++ b/scripts/compile_libs/gen_libs.sh @@ -0,0 +1,253 @@ +#!/bin/bash + +CURDIR="$PWD" +if [ -z ${1+x} ]; then + echo "Give a destination path where to run this script, please choose a path other than in the source directory" + exit 1 +fi + +if [ -z ${2+x} ]; then + echo "Specify the target system" + exit 1 +fi + +OS_NAME=$2 + +COMPILEFLAGS="-fPIC" +LINKFLAGS="-fPIC" +if [[ "${OS_NAME}" == "webasm" ]]; then + COMPILEFLAGS="-pthread -O3 -g -s USE_PTHREADS=1" + LINKFLAGS="-pthread -O3 -g -s USE_PTHREADS=1 -s ASYNCIFY=1 -s WASM=1" +fi + +if [[ "${OS_NAME}" == "android" ]]; then + OS_NAME_PATH="android" +elif [[ "${OS_NAME}" == "windows" ]]; then + OS_NAME_PATH="windows" +elif [[ "${OS_NAME}" == "linux" ]]; then + OS_NAME_PATH="linux" +elif [[ "${OS_NAME}" == "webasm" ]]; then + OS_NAME_PATH="webasm" +fi + +COMP_HAS_ARM32=0 +COMP_HAS_ARM64=0 +COMP_HAS_x86=0 +COMP_HAS_x64=0 +COMP_HAS_WEBASM=0 + +if [[ "${OS_NAME}" == "android" ]]; then + COMP_HAS_ARM32=1 + COMP_HAS_ARM64=1 + COMP_HAS_x86=1 + COMP_HAS_x64=1 +elif [[ "${OS_NAME}" == "linux" ]]; then + COMP_HAS_x64=1 +elif [[ "${OS_NAME}" == "windows" ]]; then + COMP_HAS_x86=1 + COMP_HAS_x64=1 +elif [[ "${OS_NAME}" == "webasm" ]]; then + COMP_HAS_WEBASM=1 +fi + +mkdir -p "$1" +cd "$1" || exit 1 + +function build_cmake_lib() { + if [ ! -d "${1}" ]; then + git clone "${2}" "${1}" + fi + ( + cd "${1}" || exit 1 + cp "${CURDIR}"/scripts/compile_libs/cmake_lib_compile.sh cmake_lib_compile.sh + ./cmake_lib_compile.sh "$_ANDROID_ABI_LEVEL" "$OS_NAME" "$COMPILEFLAGS" "$LINKFLAGS" + ) +} + +_ANDROID_ABI_LEVEL=24 + +mkdir -p compile_libs +cd compile_libs || exit 1 + +# start with openssl +( + _WAS_THERE_SSLFILE=1 + if [ ! -d "openssl" ]; then + git clone https://github.com/openssl/openssl openssl + _WAS_THERE_SSLFILE=0 + fi + ( + cd openssl || exit 1 + if [[ "$_WAS_THERE_SSLFILE" == 0 ]]; then + ./autogen.sh + fi + cp "${CURDIR}"/scripts/compile_libs/make_lib_openssl.sh make_lib_openssl.sh + ./make_lib_openssl.sh "$_ANDROID_ABI_LEVEL" "$OS_NAME" "$COMPILEFLAGS" "$LINKFLAGS" + ) +) + +build_cmake_lib zlib https://github.com/madler/zlib +build_cmake_lib png https://github.com/glennrp/libpng +build_cmake_lib curl https://github.com/curl/curl +build_cmake_lib freetype2 https://gitlab.freedesktop.org/freetype/freetype +build_cmake_lib sdl https://github.com/libsdl-org/SDL +build_cmake_lib ogg https://github.com/xiph/ogg +build_cmake_lib opus https://github.com/xiph/opus + +( + _WAS_THERE_OPUSFILE=1 + if [ ! -d "opusfile" ]; then + git clone https://github.com/xiph/opusfile opusfile + _WAS_THERE_OPUSFILE=0 + fi + cd opusfile || exit 1 + if [[ "$_WAS_THERE_OPUSFILE" == 0 ]]; then + ./autogen.sh + fi + cp "${CURDIR}"/scripts/compile_libs/make_lib_opusfile.sh make_lib_opusfile.sh + ./make_lib_opusfile.sh "$_ANDROID_ABI_LEVEL" "$OS_NAME" "$COMPILEFLAGS" "$LINKFLAGS" +) + +# SQLite, just download and built by hand +if [ ! -d "sqlite3" ]; then + wget https://www.sqlite.org/2021/sqlite-amalgamation-3360000.zip + 7z e sqlite-amalgamation-3360000.zip -osqlite3 +fi + +( + cd sqlite3 || exit 1 + cp "${CURDIR}"/scripts/compile_libs/make_lib_sqlite3.sh make_lib_sqlite3.sh + ./make_lib_sqlite3.sh "$_ANDROID_ABI_LEVEL" "$OS_NAME" "$COMPILEFLAGS" "$LINKFLAGS" +) + +cd .. + +function copy_arches_for_lib() { + if [[ "$COMP_HAS_ARM32" == "1" ]]; then + ${1} arm arm + fi + if [[ "$COMP_HAS_ARM64" == "1" ]]; then + ${1} arm64 arm64 + fi + if [[ "$COMP_HAS_x86" == "1" ]]; then + ${1} x86 32 + fi + if [[ "$COMP_HAS_x64" == "1" ]]; then + ${1} x86_64 64 + fi + if [[ "$COMP_HAS_WEBASM" == "1" ]]; then + ${1} wasm wasm + fi +} + +mkdir ddnet-libs +function _copy_curl() { + mkdir -p ddnet-libs/curl/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/curl/build_"$OS_NAME"_"$1"/lib/libcurl.a ddnet-libs/curl/"$OS_NAME_PATH"/lib"$2"/libcurl.a +} + +copy_arches_for_lib _copy_curl + +mkdir ddnet-libs +function _copy_freetype2() { + mkdir -p ddnet-libs/freetype/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/freetype2/build_"$OS_NAME"_"$1"/libfreetype.a ddnet-libs/freetype/"$OS_NAME_PATH"/lib"$2"/libfreetype.a +} + +copy_arches_for_lib _copy_freetype2 + +mkdir ddnet-libs +function _copy_sdl() { + mkdir -p ddnet-libs/sdl/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/sdl/build_"$OS_NAME"_"$1"/libSDL2.a ddnet-libs/sdl/"$OS_NAME_PATH"/lib"$2"/libSDL2.a + cp compile_libs/sdl/build_"$OS_NAME"_"$1"/libSDL2main.a ddnet-libs/sdl/"$OS_NAME_PATH"/lib"$2"/libSDL2main.a + if [ ! -d "ddnet-libs/sdl/include/$OS_NAME_PATH" ]; then + mkdir -p ddnet-libs/sdl/include/"$OS_NAME_PATH" + fi + cp -R compile_libs/sdl/include/* ddnet-libs/sdl/include/"$OS_NAME_PATH" +} + +copy_arches_for_lib _copy_sdl + +# copy java code from SDL2 +if [[ "$OS_NAME" == "android" ]]; then + rm -R ddnet-libs/sdl/java + mkdir -p ddnet-libs/sdl/java + cp -R compile_libs/sdl/android-project/app/src/main/java/org ddnet-libs/sdl/java/ +fi + +mkdir ddnet-libs +function _copy_ogg() { + mkdir -p ddnet-libs/opus/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/ogg/build_"$OS_NAME"_"$1"/libogg.a ddnet-libs/opus/"$OS_NAME_PATH"/lib"$2"/libogg.a +} + +copy_arches_for_lib _copy_ogg + +mkdir ddnet-libs +function _copy_opus() { + mkdir -p ddnet-libs/opus/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/opus/build_"$OS_NAME"_"$1"/libopus.a ddnet-libs/opus/"$OS_NAME_PATH"/lib"$2"/libopus.a +} + +copy_arches_for_lib _copy_opus + +mkdir ddnet-libs +function _copy_opusfile() { + mkdir -p ddnet-libs/opus/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/opusfile/build_"$OS_NAME"_"$1"/libopusfile.a ddnet-libs/opus/"$OS_NAME_PATH"/lib"$2"/libopusfile.a +} + +copy_arches_for_lib _copy_opusfile + +mkdir ddnet-libs +function _copy_sqlite3() { + mkdir -p ddnet-libs/sqlite3/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/sqlite3/build_"$OS_NAME"_"$1"/sqlite3.a ddnet-libs/sqlite3/"$OS_NAME_PATH"/lib"$2"/libsqlite3.a +} + +copy_arches_for_lib _copy_sqlite3 + +mkdir ddnet-libs +function _copy_openssl() { + mkdir -p ddnet-libs/openssl/"$OS_NAME_PATH"/lib"$2" + mkdir -p ddnet-libs/openssl/include + mkdir -p ddnet-libs/openssl/include/"$OS_NAME_PATH" + cp compile_libs/openssl/build_"$OS_NAME"_"$1"/libcrypto.a ddnet-libs/openssl/"$OS_NAME_PATH"/lib"$2"/libcrypto.a + cp compile_libs/openssl/build_"$OS_NAME"_"$1"/libssl.a ddnet-libs/openssl/"$OS_NAME_PATH"/lib"$2"/libssl.a + cp -R compile_libs/openssl/build_"$OS_NAME"_"$1"/include/* ddnet-libs/openssl/include/"$OS_NAME_PATH" + cp -R compile_libs/openssl/include/* ddnet-libs/openssl/include +} + +copy_arches_for_lib _copy_openssl + +mkdir ddnet-libs +function _copy_zlib() { + # copy headers + ( + cd compile_libs/zlib || exit 1 + find . -maxdepth 1 -iname '*.h' -print0 | while IFS= read -r -d $'\0' file; do + mkdir -p ../../ddnet-libs/zlib/include/"$(dirname "$file")" + cp "$file" ../../ddnet-libs/zlib/include/"$(dirname "$file")" + done + + cd build_"$OS_NAME"_"$1" || exit 1 + find . -maxdepth 1 -iname '*.h' -print0 | while IFS= read -r -d $'\0' file; do + mkdir -p ../../../ddnet-libs/zlib/include/"$OS_NAME_PATH"/"$(dirname "$file")" + cp "$file" ../../../ddnet-libs/zlib/include/"$OS_NAME_PATH"/"$(dirname "$file")" + done + ) + + mkdir -p ddnet-libs/zlib/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/zlib/build_"$OS_NAME"_"$1"/libz.a ddnet-libs/zlib/"$OS_NAME_PATH"/lib"$2"/libz.a +} + +copy_arches_for_lib _copy_zlib + +mkdir ddnet-libs +function _copy_png() { + mkdir -p ddnet-libs/png/"$OS_NAME_PATH"/lib"$2" + cp compile_libs/png/build_"$OS_NAME"_"$1"/libpng16.a ddnet-libs/png/"$OS_NAME_PATH"/lib"$2"/libpng16.a +} + +copy_arches_for_lib _copy_png diff --git a/scripts/compile_libs/make_lib_openssl.sh b/scripts/compile_libs/make_lib_openssl.sh new file mode 100755 index 000000000..39e803fe6 --- /dev/null +++ b/scripts/compile_libs/make_lib_openssl.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +ANDROID_HOME=~/Android/Sdk +ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" + +export MAKEFLAGS=-j32 + +export CXXFLAGS="$3" +export CFLAGS="$3" +export CPPFLAGS="$4" +export LDFLAGS="$4" + +export ANDROID_NDK_ROOT=$ANDROID_NDK +PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH + +function buid_openssl() { + _EXISTS_PROJECT=0 + if [ -d "$1" ]; then + _EXISTS_PROJECT=1 + else + mkdir "$1" + fi + ( + cd "$1" || exit 1 + if [[ "$_EXISTS_PROJECT" == "0" ]]; then + if [[ "${4}" == "webasm" ]]; then + emconfigure ../Configure "$2" -no-tests -no-asm -static -no-afalgeng -DOPENSSL_SYS_NETWARE -DSIG_DFL=0 -DSIG_IGN=0 -DHAVE_FORK=0 -DOPENSSL_NO_AFALGENG=1 --with-rand-seed=getrandom + + sed -i 's|^CROSS_COMPILE.*$|CROSS_COMPILE=|g' Makefile + else + ../Configure "$2" no-asm no-shared + fi + fi + ${5} make $MAKEFLAGS build_generated + ${5} make $MAKEFLAGS libcrypto.a + ${5} make $MAKEFLAGS libssl.a + cd .. + ) +} + +if [[ "${2}" == "android" ]]; then + buid_openssl build_"$2"_arm android-arm "$1" "$2" "" + buid_openssl build_"$2"_arm64 android-arm64 "$1" "$2" "" + buid_openssl build_"$2"_x86 android-x86 "$1" "$2" "" + buid_openssl build_"$2"_x86_64 android-x86_64 "$1" "$2" "" +elif [[ "${2}" == "webasm" ]]; then + buid_openssl build_"$2"_wasm linux-generic64 "$1" "$2" emmake +fi diff --git a/scripts/android/make_android_opusfile.sh b/scripts/compile_libs/make_lib_opusfile.sh similarity index 50% rename from scripts/android/make_android_opusfile.sh rename to scripts/compile_libs/make_lib_opusfile.sh index 6de769c96..87c62784f 100755 --- a/scripts/android/make_android_opusfile.sh +++ b/scripts/compile_libs/make_lib_opusfile.sh @@ -5,6 +5,11 @@ ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" export MAKEFLAGS=-j32 +export CXXFLAGS="$3" +export CFLAGS="$3" +export CPPFLAGS="$4" +export LDFLAGS="$4" + export ANDROID_NDK_ROOT="$ANDROID_NDK" function make_opusfile() { @@ -24,7 +29,18 @@ function make_opusfile() { cp ../../ogg/"$2"/libogg.a libogg.a cp ../../opus/"$2"/libopus.a libopus.a fi - "$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/$3$4-clang" \ + + TMP_COMPILER="" + TMP_AR="" + if [[ "${5}" == "android" ]]; then + TMP_COMPILER="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/$3$4-clang" + TMP_AR="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" + elif [[ "${5}" == "webasm" ]]; then + TMP_COMPILER="emcc" + TMP_AR="emar" + fi + + ${TMP_COMPILER} \ -c \ -fPIC \ -I"${PWD}"/../include \ @@ -32,16 +48,14 @@ function make_opusfile() { ../src/opusfile.c \ ../src/info.c \ ../src/internal.c - "$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/$3$4-clang" \ + ${TMP_COMPILER} \ -c \ -fPIC \ -I"${PWD}"/../include \ -I"${PWD}"/include \ -include stdio.h \ - -Dftello=ftell \ - -Dfseek=fseek \ ../src/stream.c - "$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" \ + ${TMP_AR} \ rvs \ libopusfile.a \ opusfile.o \ @@ -52,11 +66,15 @@ function make_opusfile() { } function compile_all_opusfile() { - make_opusfile build_arm build_android_arm armv7a-linux-androideabi "$1" - make_opusfile build_arm64 build_android_arm64 aarch64-linux-android "$1" - make_opusfile build_x86 build_android_x86 i686-linux-android "$1" - make_opusfile build_x86_64 build_android_x86_64 x86_64-linux-android "$1" + if [[ "${2}" == "android" ]]; then + make_opusfile build_"$2"_arm build_"$2"_arm armv7a-linux-androideabi "$1" "$2" + make_opusfile build_"$2"_arm64 build_"$2"_arm64 aarch64-linux-android "$1" "$2" + make_opusfile build_"$2"_x86 build_"$2"_x86 i686-linux-android "$1" "$2" + make_opusfile build_"$2"_x86_64 build_"$2"_x86_64 x86_64-linux-android "$1" "$2" + elif [[ "${2}" == "webasm" ]]; then + make_opusfile build_"$2"_wasm build_"$2"_wasm "" "$1" "$2" + fi } -compile_all_opusfile "$1" +compile_all_opusfile "$1" "$2" diff --git a/scripts/compile_libs/make_lib_sqlite3.sh b/scripts/compile_libs/make_lib_sqlite3.sh new file mode 100755 index 000000000..2e8eb75d0 --- /dev/null +++ b/scripts/compile_libs/make_lib_sqlite3.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +ANDROID_HOME=~/Android/Sdk +ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" + +export MAKEFLAGS=-j32 + +export CXXFLAGS="$3" +export CFLAGS="$3" +export CPPFLAGS="$4" +LINKER_FLAGS="$4" + +export ANDROID_NDK_ROOT="$ANDROID_NDK" +PATH="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH" +_LD_LIBRARY_PATH=".:$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$LD_LIBRARY_PATH" + +function make_sqlite3() { + ( + mkdir -p "$1" + cd "$1" || exit 1 + + TMP_COMPILER="" + TMP_AR="" + if [[ "${5}" == "android" ]]; then + TMP_COMPILER="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/$3$4-clang" + TMP_AR="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar" + elif [[ "${5}" == "webasm" ]]; then + TMP_COMPILER="emcc" + TMP_AR="emar" + fi + + LDFLAGS="${LINKER_FLAGS} -L./" \ + LD_LIBRARY_PATH="$_LD_LIBRARY_PATH" \ + ${TMP_COMPILER} \ + -c \ + -fPIC \ + -DSQLITE_ENABLE_ATOMIC_WRITE=1 \ + -DSQLITE_ENABLE_BATCH_ATOMIC_WRITE=1 \ + -DSQLITE_ENABLE_MULTITHREADED_CHECKS=1 \ + -DSQLITE_THREADSAFE=1 \ + ../sqlite3.c \ + -o sqlite3.o + + LDFLAGS="${LINKER_FLAGS} -L./" \ + LD_LIBRARY_PATH="$_LD_LIBRARY_PATH" \ + ${TMP_AR} \ + rvs \ + sqlite3.a \ + sqlite3.o + ) +} + +function compile_all_sqlite3() { + if [[ "${2}" == "android" ]]; then + make_sqlite3 build_"$2"_arm build_"$2"_arm armv7a-linux-androideabi "$1" "$2" + make_sqlite3 build_"$2"_arm64 build_"$2"_arm64 aarch64-linux-android "$1" "$2" + make_sqlite3 build_"$2"_x86 build_"$2"_x86 i686-linux-android "$1" "$2" + make_sqlite3 build_"$2"_x86_64 build_"$2"_x86_64 x86_64-linux-android "$1" "$2" + elif [[ "${2}" == "webasm" ]]; then + make_sqlite3 build_"$2"_wasm build_"$2"_wasm "" "$1" "$2" + fi +} + +compile_all_sqlite3 "$1" "$2" + diff --git a/src/base/detect.h b/src/base/detect.h index ce530c375..90eeeae78 100644 --- a/src/base/detect.h +++ b/src/base/detect.h @@ -46,12 +46,16 @@ #define PLATFORM_STRING "openbsd" #endif -#if(defined(__LINUX__) || defined(__linux__)) && !defined(__ANDROID__) +#if(defined(__LINUX__) || defined(__linux__) || defined(CONF_WEBASM)) && !defined(__ANDROID__) #define CONF_FAMILY_UNIX 1 #define CONF_FAMILY_STRING "unix" #define CONF_PLATFORM_LINUX 1 #define PLATFORM_STRING "linux" #define CONF_BACKEND_OPENGL_ES3 1 +#ifdef CONF_WEBASM +// GLES only +#define CONF_BACKEND_OPENGL_ES 1 +#endif #endif #if defined(__ANDROID__) diff --git a/src/engine/client/backend/opengl/backend_opengl3.cpp b/src/engine/client/backend/opengl/backend_opengl3.cpp index 26043783e..5ad001768 100644 --- a/src/engine/client/backend/opengl/backend_opengl3.cpp +++ b/src/engine/client/backend/opengl/backend_opengl3.cpp @@ -17,6 +17,16 @@ #include +#ifdef CONF_WEBASM +// WebGL2 defines the type of a buffer at the first bind to a buffer target +// this is different to GLES 3 (https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1) +static constexpr GLenum BUFFER_INIT_INDEX_TARGET = GL_ELEMENT_ARRAY_BUFFER; +static constexpr GLenum BUFFER_INIT_VERTEX_TARGET = GL_ARRAY_BUFFER; +#else +static constexpr GLenum BUFFER_INIT_INDEX_TARGET = GL_COPY_WRITE_BUFFER; +static constexpr GLenum BUFFER_INIT_VERTEX_TARGET = GL_COPY_WRITE_BUFFER; +#endif + // ------------ CCommandProcessorFragment_OpenGL3_3 int CCommandProcessorFragment_OpenGL3_3::TexFormatToNewOpenGLFormat(int TexFormat) { @@ -458,7 +468,7 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand glBindVertexArray(0); glGenBuffers(1, &m_QuadDrawIndexBufferID); - glBindBuffer(GL_COPY_WRITE_BUFFER, m_QuadDrawIndexBufferID); + glBindBuffer(BUFFER_INIT_INDEX_TARGET, m_QuadDrawIndexBufferID); unsigned int Indices[CCommandBuffer::MAX_VERTICES / 4 * 6]; int Primq = 0; @@ -472,7 +482,7 @@ bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand Indices[i + 5] = Primq + 3; Primq += 4; } - glBufferData(GL_COPY_WRITE_BUFFER, sizeof(unsigned int) * CCommandBuffer::MAX_VERTICES / 4 * 6, Indices, GL_STATIC_DRAW); + glBufferData(BUFFER_INIT_INDEX_TARGET, sizeof(unsigned int) * CCommandBuffer::MAX_VERTICES / 4 * 6, Indices, GL_STATIC_DRAW); m_CurrentIndicesInBuffer = CCommandBuffer::MAX_VERTICES / 4 * 6; @@ -944,12 +954,12 @@ void CCommandProcessorFragment_OpenGL3_3::AppendIndices(unsigned int NewIndicesC glBindBuffer(GL_COPY_READ_BUFFER, m_QuadDrawIndexBufferID); GLuint NewIndexBufferID; glGenBuffers(1, &NewIndexBufferID); - glBindBuffer(GL_COPY_WRITE_BUFFER, NewIndexBufferID); + glBindBuffer(BUFFER_INIT_INDEX_TARGET, NewIndexBufferID); GLsizeiptr size = sizeof(unsigned int); - glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)NewIndicesCount * size, NULL, GL_STATIC_DRAW); - glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, (GLsizeiptr)m_CurrentIndicesInBuffer * size); - glBufferSubData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)m_CurrentIndicesInBuffer * size, (GLsizeiptr)AddCount * size, Indices); - glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + glBufferData(BUFFER_INIT_INDEX_TARGET, (GLsizeiptr)NewIndicesCount * size, NULL, GL_STATIC_DRAW); + glCopyBufferSubData(GL_COPY_READ_BUFFER, BUFFER_INIT_INDEX_TARGET, 0, 0, (GLsizeiptr)m_CurrentIndicesInBuffer * size); + glBufferSubData(BUFFER_INIT_INDEX_TARGET, (GLsizeiptr)m_CurrentIndicesInBuffer * size, (GLsizeiptr)AddCount * size, Indices); + glBindBuffer(BUFFER_INIT_INDEX_TARGET, 0); glBindBuffer(GL_COPY_READ_BUFFER, 0); glDeleteBuffers(1, &m_QuadDrawIndexBufferID); @@ -982,8 +992,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_CreateBufferObject(const CCommandB GLuint VertBufferID = 0; glGenBuffers(1, &VertBufferID); - glBindBuffer(GL_COPY_WRITE_BUFFER, VertBufferID); - glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); + glBindBuffer(BUFFER_INIT_VERTEX_TARGET, VertBufferID); + glBufferData(BUFFER_INIT_VERTEX_TARGET, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); m_BufferObjectIndices[Index] = VertBufferID; @@ -996,8 +1006,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RecreateBufferObject(const CComman void *pUploadData = pCommand->m_pUploadData; int Index = pCommand->m_BufferIndex; - glBindBuffer(GL_COPY_WRITE_BUFFER, m_BufferObjectIndices[Index]); - glBufferData(GL_COPY_WRITE_BUFFER, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); + glBindBuffer(BUFFER_INIT_VERTEX_TARGET, m_BufferObjectIndices[Index]); + glBufferData(BUFFER_INIT_VERTEX_TARGET, (GLsizeiptr)(pCommand->m_DataSize), pUploadData, GL_STATIC_DRAW); if(pCommand->m_DeletePointer) free(pUploadData); @@ -1008,8 +1018,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_UpdateBufferObject(const CCommandB void *pUploadData = pCommand->m_pUploadData; int Index = pCommand->m_BufferIndex; - glBindBuffer(GL_COPY_WRITE_BUFFER, m_BufferObjectIndices[Index]); - glBufferSubData(GL_COPY_WRITE_BUFFER, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pUploadData); + glBindBuffer(BUFFER_INIT_VERTEX_TARGET, m_BufferObjectIndices[Index]); + glBufferSubData(BUFFER_INIT_VERTEX_TARGET, (GLintptr)(pCommand->m_pOffset), (GLsizeiptr)(pCommand->m_DataSize), pUploadData); if(pCommand->m_DeletePointer) free(pUploadData); diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp index e87e261a8..0168e0dd0 100644 --- a/src/engine/client/backend_sdl.cpp +++ b/src/engine/client/backend_sdl.cpp @@ -123,11 +123,16 @@ void CGraphicsBackend_Threaded::StopProcessor() void CGraphicsBackend_Threaded::RunBuffer(CCommandBuffer *pBuffer) { +#ifdef CONF_WEBASM + // run everything single threaded for now, context binding in a thread seems to not work as of now + RunBufferSingleThreadedUnsafe(pBuffer); +#else WaitForIdle(); std::unique_lock Lock(m_BufferSwapMutex); m_pBuffer = pBuffer; m_BufferInProcess.store(true, std::memory_order_relaxed); m_BufferSwapCond.notify_all(); +#endif } void CGraphicsBackend_Threaded::RunBufferSingleThreadedUnsafe(CCommandBuffer *pBuffer) @@ -668,6 +673,7 @@ bool CGraphicsBackend_SDL_GL::GetDriverVersion(EGraphicsDriverAgeType DriverAgeT if(BackendType == BACKEND_TYPE_OPENGL) { pName = "OpenGL"; +#ifndef CONF_BACKEND_OPENGL_ES if(DriverAgeType == GRAPHICS_DRIVER_AGE_TYPE_LEGACY) { Major = 1; @@ -689,6 +695,7 @@ bool CGraphicsBackend_SDL_GL::GetDriverVersion(EGraphicsDriverAgeType DriverAgeT Patch = 0; return true; } +#endif } else if(BackendType == BACKEND_TYPE_OPENGL_ES) { diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 59ed9efe6..a427753e7 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2888,6 +2888,7 @@ void CClient::Run() CVideo::Init(); #endif +#ifndef CONF_WEBASM // open socket { NETADDR BindAddr; @@ -2910,6 +2911,7 @@ void CClient::Run() } } } +#endif // init font rendering Kernel()->RequestInterface()->Init(); diff --git a/src/engine/client/notifications.cpp b/src/engine/client/notifications.cpp index b38e53353..8153815d7 100644 --- a/src/engine/client/notifications.cpp +++ b/src/engine/client/notifications.cpp @@ -4,7 +4,7 @@ #if defined(CONF_PLATFORM_MACOS) // Code is in src/macos/notification.mm. -#elif defined(CONF_FAMILY_UNIX) && !defined(CONF_PLATFORM_ANDROID) && !defined(CONF_PLATFORM_HAIKU) +#elif defined(CONF_FAMILY_UNIX) && !defined(CONF_PLATFORM_ANDROID) && !defined(CONF_PLATFORM_HAIKU) && !defined(CONF_WEBASM) #include void NotificationsInit() { diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 4647c7348..60f3edcb1 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -103,8 +103,12 @@ MACRO_CONFIG_INT(GfxDesktopWidth, gfx_desktop_width, 0, 0, 0, CFGFLAG_SAVE | CFG MACRO_CONFIG_INT(GfxDesktopHeight, gfx_desktop_height, 0, 0, 0, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Desktop resolution height for detecting display changes (not recommended to change manually)") #if !defined(CONF_PLATFORM_MACOS) MACRO_CONFIG_INT(GfxBorderless, gfx_borderless, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Borderless window (not to be used with fullscreen)") +#if !defined(CONF_WEBASM) MACRO_CONFIG_INT(GfxFullscreen, gfx_fullscreen, 1, 0, 3, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Set fullscreen mode: 0=no fullscreen, 1=pure fullscreen, 2=desktop fullscreen, 3=windowed fullscreen") #else +MACRO_CONFIG_INT(GfxFullscreen, gfx_fullscreen, 0, 0, 3, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Set fullscreen mode: 0=no fullscreen, 1=pure fullscreen, 2=desktop fullscreen, 3=windowed fullscreen") +#endif +#else MACRO_CONFIG_INT(GfxBorderless, gfx_borderless, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Borderless window (not to be used with fullscreen)") MACRO_CONFIG_INT(GfxFullscreen, gfx_fullscreen, 0, 0, 3, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Set fullscreen mode: 0=no fullscreen, 1=pure fullscreen, 2=desktop fullscreen, 3=windowed fullscreen") #endif