Skip to content

Commit

Permalink
internal: add emscripten support & update vcpkg (#2114)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Aug 16, 2024
1 parent d2f7a23 commit d678acc
Show file tree
Hide file tree
Showing 32 changed files with 655 additions and 134 deletions.
45 changes: 35 additions & 10 deletions .github/actions/pr_base/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ inputs:
SKYMP5_PATCHES_PAT:
description: "PAT for skymp5-patches repository"
required: true
EMSCRIPTEN:
description: "Set to true if building for Emscripten"
required: false
default: "false"
runs:
using: composite
steps:
Expand Down Expand Up @@ -130,25 +134,46 @@ runs:
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
# Outputs profiling data in Google Trace Format, which can be parsed by the about:tracing tab of Google Chrome or using a plugin for a tool like Trace Compass.
run: |
if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') {
git clone --depth 1 https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 3.1.64
./emsdk activate 3.1.64
. .\emsdk_env.ps1
cd ..
}
$cmake_command = if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { "emcmake cmake" } else { "cmake" }
$cppcov_path_arg = if ($env:RUNNER_OS -eq 'Windows') { '-DCPPCOV_PATH="C:\Program Files\OpenCppCoverage"' } else { '-DCPPCOV_PATH=OFF' }
$vcpkg_root_arg = if ($env:RUNNER_OS -eq 'Windows') { '-DVCPKG_ROOT=C:/vcpkg' } else { '-DVCPKG_ROOT="${{github.workspace}}/vcpkg"' }
cmake -B ${{github.workspace}}/build `
$vcpkg_root_arg `
-DUNIT_DATA_DIR="skyrim_data_files" `
-DPREPARE_NEXUS_ARCHIVES=ON `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-DSKYRIM_SE=${{ inputs.SKYRIM_SE_FLAG }} `
$cppcov_path_arg `
--profiling-output cmake-profiling-output `
--profiling-format google-trace
$vcpkg_chainload_toolchain_arg = if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { '-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE="${{github.workspace}}/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"' } else { '' }
$vcpkg_triplet_arg = if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { '-DVCPKG_TARGET_TRIPLET=wasm32-emscripten' } else { '' }
$prepare_nexus_archives_arg = if ('${{ inputs.SP_NEXUS_ARTIFACT_NAME}}' -eq 'nope') { '-DPREPARE_NEXUS_ARCHIVES=OFF' } else { '-DPREPARE_NEXUS_ARCHIVES=ON' }
$cmake_command_full = "$cmake_command "
$cmake_command_full += "-B ${{github.workspace}}/build "
$cmake_command_full += "$vcpkg_chainload_toolchain_arg "
$cmake_command_full += "$vcpkg_triplet_arg "
$cmake_command_full += "$vcpkg_root_arg "
$cmake_command_full += "-DUNIT_DATA_DIR=skyrim_data_files "
$cmake_command_full += "$prepare_nexus_archives_arg "
$cmake_command_full += "-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} "
$cmake_command_full += "-DSKYRIM_SE=${{ inputs.SKYRIM_SE_FLAG }} "
$cmake_command_full += "$cppcov_path_arg "
$cmake_command_full += "--profiling-output cmake-profiling-output "
$cmake_command_full += "--profiling-format google-trace"
Invoke-Expression $cmake_command_full
shell: powershell

- name: Upload vcpkg failure logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: install-x64-linux-dbg-out.log
path: C:\vcpkg\buildtrees\spdlog\install-x64-windows-sp-dbg-out.log
#path: C:\vcpkg\buildtrees\spdlog\install-x64-windows-sp-dbg-out.log
path: /Users/runner/work/skymp/skymp/vcpkg/buildtrees/slikenet/install-wasm32-emscripten-dbg-out.log

- uses: actions/upload-artifact@v4
with:
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/pr-emscripten.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: PR Emscripten

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * *'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
VCPKG_BINARY_SOURCES: 'clear;x-gha,readwrite'
VCPKG_FEATURE_FLAGS: 'manifests'

jobs:
build:
# MacOS has powershell
runs-on: macos-12
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1
submodules: 'true'

- name: Setup Emscripten environment
uses: actions/setup-python@v4
with:
python-version: '3.x'

- uses: ./.github/actions/pr_base
with:
DESCRIPTION: 'Emscripten Build'
DIST_ARTIFACT_NAME: dist-emscripten
SERVER_DIST_ARTIFACT_NAME: server-dist-emscripten
SKYMP5_PATCHES_PAT: ${{ secrets.SKYMP5_PATCHES_PAT }}
EMSCRIPTEN: true
1 change: 1 addition & 0 deletions 1js/JsEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ChakraCore.h>
#include <cstdint>
#include <cstring>
#include <fmt/ranges.h>
#include <memory>
#include <optional>
#include <sstream>
Expand Down
21 changes: 14 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ if(POLICY 0115)
cmake_policy(SET CMP0115 NEW)
endif()

if(WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows-sp")
elseif(APPLE)
set(VCPKG_TARGET_TRIPLET "x64-osx")
else()
set(VCPKG_TARGET_TRIPLET "x64-linux")
if("${VCPKG_TARGET_TRIPLET}" STREQUAL "")
if(WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows-sp")
elseif(APPLE)
set(VCPKG_TARGET_TRIPLET "x64-osx")
else()
set(VCPKG_TARGET_TRIPLET "x64-linux")
endif()
endif()

set(VCPKG_OVERLAY_TRIPLETS "${CMAKE_CURRENT_LIST_DIR}/overlay_triplets")
Expand Down Expand Up @@ -88,6 +90,10 @@ message(STATUS INSTALL_CLIENT_DIST=${INSTALL_CLIENT_DIST})
message(STATUS BUILD_GAMEMODE=${BUILD_GAMEMODE})
message(STATUS OFFLINE_MODE=${OFFLINE_MODE})

if(PREPARE_NEXUS_ARCHIVES AND EMSCRIPTEN)
message(FATAL_ERROR "PREPARE_NEXUS_ARCHIVES is not supported on Emscripten")
endif()

# Note that SkyrimPlatform performance drops significantly with JS_ENGINE_TRACING_ENABLED set to true.

if(JS_ENGINE_TRACING_ENABLED)
Expand Down Expand Up @@ -145,7 +151,8 @@ add_subdirectory(skymp5-functions-lib)
add_subdirectory(skymp5-scripts)
add_subdirectory(skymp5-server)

if(BUILD_UNIT_TESTS)
# TODO: enable for Emscripten once stabilize
if(BUILD_UNIT_TESTS AND NOT EMSCRIPTEN)
add_subdirectory(unit)
endif()

Expand Down
20 changes: 15 additions & 5 deletions cmake/run_test_unit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,21 @@ if(temp_coverage)
file(REMOVE ${temp_coverage})
endif()

execute_process(COMMAND ${EXE_PATH}
RESULT_VARIABLE res
OUTPUT_VARIABLE out
WORKING_DIRECTORY "${UNIT_WORKING_DIRECTORY}"
)
# Emscripten support
if("${EXE_PATH}" MATCHES ".*\.js")
execute_process(COMMAND node ${EXE_PATH}
RESULT_VARIABLE res
OUTPUT_VARIABLE out
WORKING_DIRECTORY "${UNIT_WORKING_DIRECTORY}"
)
else()
execute_process(COMMAND ${EXE_PATH}
RESULT_VARIABLE res
OUTPUT_VARIABLE out
WORKING_DIRECTORY "${UNIT_WORKING_DIRECTORY}"
)
endif()

message("${out}")

if(NOT "${res}" STREQUAL "0")
Expand Down
4 changes: 0 additions & 4 deletions libespm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,4 @@ apply_default_settings(TARGETS espm)

add_library(libespm ALIAS espm)

find_path(SPARSEPP_INCLUDE_DIR NAMES spp.h PATH_SUFFIXES sparsepp)
get_filename_component(SPARSEPP_INCLUDE_DIR ${SPARSEPP_INCLUDE_DIR} DIRECTORY)
target_include_directories(espm PUBLIC ${SPARSEPP_INCLUDE_DIR})

target_link_libraries(espm PUBLIC viet)
4 changes: 2 additions & 2 deletions libespm/include/libespm/CompressedFieldsCache.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
#include <memory>
#include <sparsepp/spp.h>
#include <unordered_map>
#include <vector>

#pragma pack(push, 1)
Expand All @@ -20,7 +20,7 @@ class CompressedFieldsCache
std::shared_ptr<std::vector<uint8_t>> decompressedFieldsHolder;
};

spp::sparse_hash_map<const RecordHeader*, Entry> data;
std::unordered_map<const RecordHeader*, Entry> data;
};

}
Expand Down
8 changes: 5 additions & 3 deletions libespm/include/libespm/DataTypes.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
#pragma once
#include <cstdint>
#include <string>

namespace espm {

using RecordFlagsType = std::uint32_t;
using RecordFlagsType = uint32_t;

/// <summary>
/// A ulong used to identify a data object. May refer to a data object from a
/// mod or new object created in-game.
/// </summary>
using formId = std::uint32_t;
using formId = uint32_t;

/// <summary>
/// 'Localized string', a ulong that is used as an index to look up string data
/// information in one of the string tables. Note that the record header for
/// the TES4 record indicates if the file is localized or not. If not, all
/// lstrings are zstrings.
/// </summary>
using lstring = std::uint32_t;
using lstring = uint32_t;

/// <summary>
/// Zero terminated string
Expand Down
1 change: 1 addition & 0 deletions libespm/include/libespm/RecordHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "CompressedFieldsCache.h"
#include "DataTypes.h"
#include "Type.h"
#include <cstring> // memcmp

#pragma pack(push, 1)

Expand Down
13 changes: 7 additions & 6 deletions libespm/src/Browser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
#include "libespm/WRLD.h"
#include <cstring>
#include <optional>
#include <sparsepp/spp.h>
#include <stdexcept>
#include <unordered_map>
#include <vector>

namespace espm {
Expand All @@ -31,13 +32,13 @@ struct Browser::Impl

size_t pos = 0;
uint32_t fiDataSizeOverride = 0;
spp::sparse_hash_map<uint32_t, const RecordHeader*> recById;
spp::sparse_hash_map<uint64_t, std::vector<const RecordHeader*>> navmeshes;
spp::sparse_hash_map<uint64_t, std::vector<const RecordHeader*>>
std::unordered_map<uint32_t, const RecordHeader*> recById;
std::unordered_map<uint64_t, std::vector<const RecordHeader*>> navmeshes;
std::unordered_map<uint64_t, std::vector<const RecordHeader*>>
cellOrWorldChildren;
spp::sparse_hash_map<const GroupHeader*, const GroupDataInternal*>
std::unordered_map<const GroupHeader*, const GroupDataInternal*>
groupDataByGroupPtr;
spp::sparse_hash_map<const RecordHeader*, const GroupStack*>
std::unordered_map<const RecordHeader*, const GroupStack*>
groupStackByRecordPtr;
std::vector<const RecordHeader*> objectReferences;
std::vector<const RecordHeader*> constructibleObjects;
Expand Down
3 changes: 2 additions & 1 deletion libespm/src/CombineBrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <array>
#include <fmt/format.h>
#include <memory>
#include <unordered_set>

namespace espm {

Expand Down Expand Up @@ -91,7 +92,7 @@ std::vector<LookupResult> CombineBrowser::GetDistinctRecordsByType(
return {};
}

spp::sparse_hash_set<formId> formSet;
std::unordered_set<formId> formSet;
std::vector<LookupResult> result;
for (size_t i = pImpl->numSources - 1; i != static_cast<size_t>(-1); --i) {
const auto& records = pImpl->sources[i].br->GetRecordsByType(type);
Expand Down
1 change: 0 additions & 1 deletion libespm/src/Combiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "libespm/espm.h"
#include <array>
#include <fmt/format.h>
#include <sparsepp/spp.h>
#include <string>

namespace espm {
Expand Down
1 change: 0 additions & 1 deletion libespm/src/CompressedFieldsCache.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "libespm/CompressedFieldsCache.h"
#include "libespm/RecordHeader.h"
#include <memory>
#include <sparsepp/spp.h>
#include <vector>

namespace espm {
Expand Down
Loading

0 comments on commit d678acc

Please sign in to comment.