fix wasm build after merger

This commit is contained in:
Brendan Duncan 2025-09-20 19:49:52 -06:00
parent 1aa2788d33
commit 56f2dc8e8b
30 changed files with 199 additions and 70 deletions

View File

@ -4,6 +4,14 @@ if (NOT VCPKG_LIBRARY_LINKAGE)
set(VCPKG_LIBRARY_LINKAGE static)
endif()
get_filename_component(toolchainFile "${CMAKE_TOOLCHAIN_FILE}" NAME)
if(toolchainFile STREQUAL "Emscripten.cmake")
set(CESIUM_TARGET_WASM ON)
# Include the toolchain directly as ezvcpkg will overwrite the
# toolchain before it's loaded
include(${CMAKE_TOOLCHAIN_FILE})
endif()
# By default, Use ezvcpkg to install dependencies. But don't use
# ezvcpkg if it appears that this configuration is using vcpkg
# manifest mode already, either by building cesium-native directly,
@ -24,6 +32,12 @@ endif()
option(CESIUM_USE_EZVCPKG "use ezvcpkg helper" ${CESIUM_USE_EZVCPKG_DEFAULT})
option(CESIUM_DISABLE_CURL "Disable cesium-native's use of libcurl" OFF)
option(CESIUM_WASM64 "Enable 64-bit WebAssembly target" OFF)
if (CESIUM_TARGET_WASM)
# Make sure curl is disabled on wasm builds, as it is not supported.
set(CESIUM_DISABLE_CURL ON)
endif()
if(CESIUM_USE_EZVCPKG)
# Keep vcpkg from running in manifset mode. It will try to because
@ -95,8 +109,8 @@ set(PACKAGES_PRIVATE
earcut-hpp cpp-httplib[core] libmorton zstd
)
# asmjit needed by blend2d on non-iOS platforms (iOS doesn't support JIT)
if(NOT IOS AND NOT VCPKG_CMAKE_SYSTEM_NAME MATCHES "iOS")
# asmjit needed by blend2d on non-iOS platforms (iOS and Wasm don't support JIT)
if(NOT CESIUM_TARGET_WASM AND NOT IOS AND NOT VCPKG_CMAKE_SYSTEM_NAME MATCHES "iOS")
list(APPEND PACKAGES_PRIVATE blend2d asmjit)
else()
# Use [core] feature to disable default jit feature.
@ -110,6 +124,24 @@ endif()
# Packages only used for testing
set(PACKAGES_TEST doctest)
if(CESIUM_TARGET_WASM)
# vcpkg will attempt to second-guess our CMAKE_C_COMPILER setting, choosing to go with the value of CC instead.
# While normally this is the correct value to go with, for wasm we need to be using emcc and em++.
# So we set CC and CXX to emcc and em++ here so vcpkg will pick them up properly.
# Does this make sense? No. Does it work? Somehow. ¯\_()_/¯
set(ENV{CC} ${CMAKE_C_COMPILER})
set(ENV{CXX} ${CMAKE_CXX_COMPILER})
# Make sure all files are compiled with -pthread and other required flags.
if(CESIUM_WASM64)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -sMEMORY64=1 -fwasm-exceptions -mbulk-memory -mnontrapping-fptoint -sSUPPORT_LONGJMP=wasm -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -sMEMORY64=1 -fwasm-exceptions -mbulk-memory -mnontrapping-fptoint -sSUPPORT_LONGJMP=wasm -pthread")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fwasm-exceptions -mbulk-memory -mnontrapping-fptoint -sSUPPORT_LONGJMP=wasm -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fwasm-exceptions -mbulk-memory -mnontrapping-fptoint -sSUPPORT_LONGJMP=wasm -pthread")
endif()
endif()
if(CESIUM_USE_EZVCPKG)
set(PACKAGES_ALL ${PACKAGES_PUBLIC})
list(APPEND PACKAGES_ALL ${PACKAGES_PRIVATE})
@ -125,6 +157,15 @@ if(CESIUM_USE_EZVCPKG)
# Force the installation of each package one at a time, or the Travis CI build will time out waiting for output
SERIALIZE
)
if(CESIUM_TARGET_WASM)
# vcpkg will attempt to make this wasm32-emscripten if we don't declare it
if(CESIUM_WASM64)
set(VCPKG_TARGET_TRIPLET wasm64-emscripten)
else()
set(VCPKG_TARGET_TRIPLET wasm32-emscripten)
endif()
endif()
endif()
if (NOT CMAKE_TOOLCHAIN_FILE)
@ -141,6 +182,16 @@ project(cesium-native
LANGUAGES CXX C
)
if(CESIUM_TARGET_WASM)
if(CESIUM_WASM64)
set(CMAKE_SIZEOF_VOID_P 8)
else()
set(CMAKE_SIZEOF_VOID_P 4)
endif()
# Tells emscripten to output an HTML harness for the generated WASM
set(CMAKE_EXECUTABLE_SUFFIX ".html")
endif()
include(GNUInstallDirs)
include(CMakeDependentOption)
@ -321,16 +372,11 @@ find_package(tinyxml2 CONFIG REQUIRED)
find_package(unofficial-sqlite3 CONFIG REQUIRED)
find_package(WebP CONFIG REQUIRED)
find_package(blend2d CONFIG REQUIRED)
# asmjit should not be included with iOS builds as iOS doesn't support JIT compilation.
if(NOT IOS AND NOT VCPKG_CMAKE_SYSTEM_NAME MATCHES "iOS")
# asmjit should not be included with iOS or Wasm builds as they don't support JIT compilation.
if(NOT CESIUM_TARGET_WASM AND NOT IOS AND NOT VCPKG_CMAKE_SYSTEM_NAME MATCHES "iOS")
find_package(asmjit CONFIG REQUIRED)
endif()
if(NOT CESIUM_DISABLE_CURL)
find_package(CURL REQUIRED)
endif()
if(NOT CESIUM_DISABLE_CURL)
find_package(CURL REQUIRED)
endif()

View File

@ -234,7 +234,7 @@ public:
bool isContentAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
uint64_t contentId) const noexcept;
size_t contentId) const noexcept;
/**
* @brief Determines if content for a given tile in the octree is available.
@ -247,7 +247,7 @@ public:
bool isContentAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
uint64_t contentId) const noexcept;
size_t contentId) const noexcept;
/**
* @brief Determines if content for a given tile in the subtree is available.
@ -262,7 +262,7 @@ public:
bool isContentAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
uint64_t contentId) const noexcept;
size_t contentId) const noexcept;
/**
* @brief Sets the availability state of the content for a given tile in the
@ -276,7 +276,7 @@ public:
void setContentAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
uint64_t contentId,
size_t contentId,
bool isAvailable) noexcept;
/**
@ -291,7 +291,7 @@ public:
void setContentAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
uint64_t contentId,
size_t contentId,
bool isAvailable) noexcept;
/**
@ -309,7 +309,7 @@ public:
void setContentAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
uint64_t contentId,
size_t contentId,
bool isAvailable) noexcept;
/**

View File

@ -1014,7 +1014,7 @@ void copyStringsToBuffers(
for (const auto& str : arrayMember.GetArray()) {
OffsetType byteLength = static_cast<OffsetType>(
str.GetStringLength() * sizeof(rapidjson::Value::Ch));
std::memcpy(valueBuffer.data() + offset, str.GetString(), byteLength);
std::memcpy(valueBuffer.data() + offset, str.GetString(), (size_t)byteLength);
std::memcpy(
offsetBuffer.data() + offsetIndex * sizeof(OffsetType),
&offset,
@ -1075,7 +1075,7 @@ void updateStringArrayProperty(
++it;
}
const uint64_t totalByteLength =
const size_t totalByteLength =
totalCharCount * sizeof(rapidjson::Value::Ch);
std::vector<std::byte> valueBuffer;
std::vector<std::byte> stringOffsetBuffer;

View File

@ -823,7 +823,7 @@ void decodeDracoMetadata(
const std::unique_ptr<draco::PointCloud>& pPointCloud,
rapidjson::Document& batchTableJson,
PntsContent& parsedContent) {
const uint64_t pointsLength = parsedContent.pointsLength;
const size_t pointsLength = parsedContent.pointsLength;
std::vector<std::byte>& data = parsedContent.dracoBatchTableBinary;
const auto& dracoMetadataSemantics = parsedContent.dracoMetadataSemantics;

View File

@ -281,7 +281,7 @@ void SubtreeAvailability::setTileAvailable(
bool SubtreeAvailability::isContentAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
uint64_t contentId) const noexcept {
size_t contentId) const noexcept {
uint64_t relativeTileMortonIdx =
ImplicitTilingUtilities::computeRelativeMortonIndex(subtreeId, tileId);
return this->isContentAvailable(
@ -293,7 +293,7 @@ bool SubtreeAvailability::isContentAvailable(
bool SubtreeAvailability::isContentAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
uint64_t contentId) const noexcept {
size_t contentId) const noexcept {
uint64_t relativeTileMortonIdx =
ImplicitTilingUtilities::computeRelativeMortonIndex(subtreeId, tileId);
return this->isContentAvailable(
@ -305,7 +305,7 @@ bool SubtreeAvailability::isContentAvailable(
bool SubtreeAvailability::isContentAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
uint64_t contentId) const noexcept {
size_t contentId) const noexcept {
if (contentId >= this->_contentAvailability.size())
return false;
return isAvailable(
@ -317,7 +317,7 @@ bool SubtreeAvailability::isContentAvailable(
void SubtreeAvailability::setContentAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
uint64_t contentId,
size_t contentId,
bool isAvailable) noexcept {
uint64_t relativeTileMortonIdx =
ImplicitTilingUtilities::computeRelativeMortonIndex(subtreeId, tileId);
@ -331,7 +331,7 @@ void SubtreeAvailability::setContentAvailable(
void SubtreeAvailability::setContentAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
uint64_t contentId,
size_t contentId,
bool isAvailable) noexcept {
uint64_t relativeTileMortonIdx =
ImplicitTilingUtilities::computeRelativeMortonIndex(subtreeId, tileId);
@ -345,7 +345,7 @@ void SubtreeAvailability::setContentAvailable(
void SubtreeAvailability::setContentAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
uint64_t contentId,
size_t contentId,
bool isAvailable) noexcept {
if (contentId < this->_contentAvailability.size()) {
this->setAvailable(
@ -518,7 +518,7 @@ bool SubtreeAvailability::isAvailableUsingBufferView(
const SubtreeBufferViewAvailability* bufferViewAvailability =
std::get_if<SubtreeBufferViewAvailability>(&availabilityView);
const uint64_t byteIndex = availabilityBitIndex / 8;
const size_t byteIndex = static_cast<size_t>(availabilityBitIndex / 8);
if (byteIndex >= bufferViewAvailability->view.size()) {
return false;
}
@ -541,7 +541,7 @@ void SubtreeAvailability::setAvailableUsingBufferView(
const SubtreeBufferViewAvailability* pBufferViewAvailability =
std::get_if<SubtreeBufferViewAvailability>(&availabilityView);
const uint64_t byteIndex = availabilityBitIndex / 8;
const size_t byteIndex = static_cast<size_t>(availabilityBitIndex / 8);
if (byteIndex >= pBufferViewAvailability->view.size()) {
// Attempting to set an invalid tile. Assert, but otherwise ignore it.
CESIUM_ASSERT(false);

View File

@ -165,12 +165,12 @@ Future<ReadJsonResult<Subtree>> SubtreeFileReader::loadBinary(
}
ReadJsonResult<Subtree> result = this->_reader.readFromJson(
data.subspan(sizeof(SubtreeHeader), header->jsonByteLength));
data.subspan(sizeof(SubtreeHeader), (size_t)header->jsonByteLength));
if (result.value) {
std::span<const std::byte> binaryChunk = data.subspan(
sizeof(SubtreeHeader) + header->jsonByteLength,
header->binaryByteLength);
sizeof(SubtreeHeader) + (size_t)header->jsonByteLength,
(size_t)header->binaryByteLength);
if (binaryChunk.size() > 0) {
if (result.value->buffers.empty()) {
@ -207,7 +207,7 @@ Future<ReadJsonResult<Subtree>> SubtreeFileReader::loadBinary(
buffer.cesium.data = std::vector<std::byte>(
binaryChunk.begin(),
binaryChunk.begin() + buffer.byteLength);
binaryChunk.begin() + (ptrdiff_t)buffer.byteLength);
}
}

View File

@ -52,7 +52,7 @@ target_link_libraries(Cesium3DTilesSelection
CesiumQuantizedMeshTerrain
CesiumRasterOverlays
CesiumUtility
spdlog::spdlog spdlog::spdlog_header_only
spdlog::spdlog_header_only
# PRIVATE
libmorton::libmorton
draco::draco

View File

@ -220,7 +220,7 @@ void RasterOverlayCollection::remove(
return;
}
int64_t index = it - list.overlays.begin();
ptrdiff_t index = it - list.overlays.begin();
list.overlays.erase(list.overlays.begin() + index);
list.tileProviders.erase(list.tileProviders.begin() + index);
list.placeholders.erase(list.placeholders.begin() + index);

View File

@ -40,7 +40,7 @@ cesium_target_include_directories(
target_link_libraries(CesiumAsync
PUBLIC
CesiumUtility
spdlog::spdlog spdlog::spdlog_header_only
spdlog::spdlog_header_only
Async++
PRIVATE
unofficial::sqlite3::sqlite3

View File

@ -72,7 +72,7 @@ std::string encodeBase64(const std::vector<uint8_t>& bytes) {
// in [RFC7636 Appendix A](https://tools.ietf.org/html/rfc7636#appendix-A)
const size_t firstPaddingIndex = result.find('=');
if (firstPaddingIndex != std::string::npos) {
result.erase(result.begin() + int64_t(firstPaddingIndex), result.end());
result.erase(result.begin() + ptrdiff_t(firstPaddingIndex), result.end());
}
std::replace(result.begin(), result.end(), '+', '-');
std::replace(result.begin(), result.end(), '/', '_');

View File

@ -408,7 +408,7 @@ ErrorList Model::merge(Model&& rhs) {
std::copy(
pRhsDefaultScene->nodes.begin(),
pRhsDefaultScene->nodes.end(),
newScene.nodes.begin() + int64_t(originalNodeCount));
newScene.nodes.begin() + ptrdiff_t(originalNodeCount));
// No need to update indices because they've already been updated when
// we copied them from rhs to this.

View File

@ -28,7 +28,7 @@ template <typename T>
PropertyViewStatusType checkOffsetsBuffer(
const std::span<const std::byte>& offsetBuffer,
size_t valueBufferSize,
size_t instanceCount,
uint64_t instanceCount,
bool checkBitSize,
PropertyViewStatusType offsetsNotSortedError,
PropertyViewStatusType offsetOutOfBoundsError) noexcept {

View File

@ -1188,8 +1188,8 @@ void deleteBufferRange(
// Actually remove the bytes from the buffer.
pBuffer->byteLength -= bytesToRemove;
pBuffer->cesium.data.erase(
pBuffer->cesium.data.begin() + start,
pBuffer->cesium.data.begin() + end);
pBuffer->cesium.data.begin() + (ptrdiff_t)start,
pBuffer->cesium.data.begin() + (ptrdiff_t)end);
}
} // namespace

View File

@ -244,7 +244,7 @@ GltfReaderResult readBinaryGltf(
buffer.cesium.data = std::vector<std::byte>(
binaryChunk.begin(),
binaryChunk.begin() + buffer.byteLength);
binaryChunk.begin() + (ptrdiff_t)buffer.byteLength);
}
return result;

View File

@ -287,6 +287,7 @@ ImageReaderResult ImageDecoder::readImage(
}
{
#ifndef __EMSCRIPTEN__ // Conflict between turbojpeg and Unity
tjhandle tjInstance = tjInitDecompress();
int inSubsamp, inColorspace;
if (!tjDecompressHeader3(
@ -316,7 +317,9 @@ ImageReaderResult ImageDecoder::readImage(
result.errors.emplace_back("Unable to decode JPEG");
result.pImage = nullptr;
}
} else {
} else
#endif // __EMSCRIPTEN__
{
CESIUM_TRACE("Decode PNG");
image.bytesPerChannel = 1;
image.channels = 4;
@ -349,7 +352,9 @@ ImageReaderResult ImageDecoder::readImage(
result.errors.emplace_back(stbi_failure_reason());
}
}
#ifndef __EMSCRIPTEN__
tjDestroy(tjInstance);
#endif // __EMSCRIPTEN__
}
return result;
}

View File

@ -76,7 +76,7 @@ std::unique_ptr<draco::Mesh> decodeBufferViewToDracoMesh(
const std::span<const std::byte> data(
buffer.cesium.data.data() + bufferView.byteOffset,
static_cast<uint64_t>(bufferView.byteLength));
static_cast<size_t>(bufferView.byteLength));
draco::DecoderBuffer decodeBuffer;
decodeBuffer.Init(reinterpret_cast<const char*>(data.data()), data.size());

View File

@ -75,6 +75,33 @@ foreach(target ${cesium_native_targets})
endif()
endforeach()
if(CESIUM_TARGET_WASM)
file(GLOB directories_list LIST_DIRECTORIES true "${CMAKE_SOURCE_DIR}/Cesium*")
foreach(dir ${directories_list})
if(IS_DIRECTORY ${dir}/test/data)
list(APPEND CESIUM_TEST_DATA_DIRS --embed)
list(APPEND CESIUM_TEST_DATA_DIRS "${dir}/test/data")
endif()
endforeach()
list(APPEND CESIUM_TEST_DATA_DIRS --embed)
list(APPEND CESIUM_TEST_DATA_DIRS "${CMAKE_SOURCE_DIR}/data")
message("${CESIUM_TEST_DATA_DIRS}")
set(CESIUM_NATIVE_TESTS_DATA_OBJ ${CMAKE_CURRENT_BINARY_DIR}/cesium-native-tests-data.o)
add_custom_target(
cesium-native-tests-data
COMMAND ${EMSCRIPTEN_ROOT_PATH}/tools/file_packager none.data ${CESIUM_TEST_DATA_DIRS} --obj-output=${CESIUM_NATIVE_TESTS_DATA_OBJ})
add_library(cesium-native-tests-data-lib OBJECT IMPORTED)
add_dependencies(cesium-native-tests-data-lib cesium-native-tests-data)
set_property(TARGET cesium-native-tests-data-lib PROPERTY IMPORTED_OBJECTS
"${CESIUM_NATIVE_TESTS_DATA_OBJ}")
list(APPEND cesium_native_targets cesium-native-tests-data-lib)
endif()
target_sources(
cesium-native-tests
PRIVATE
@ -99,9 +126,12 @@ PRIVATE
target_compile_definitions(cesium-native-tests
PRIVATE
CESIUM_NATIVE_DATA_DIR=\"${CMAKE_CURRENT_LIST_DIR}/../data\"
CESIUM_NATIVE_DATA_DIR=\"${CMAKE_SOURCE_DIR}/data\"
)
include(CTest)
include(doctest)
doctest_discover_tests(cesium-native-tests)
if(NOT CESIUM_TARGET_WASM)
# doctest_discover_tests can't handle the target being an html file, so we just avoid it on a wasm build
doctest_discover_tests(cesium-native-tests)
endif()

View File

@ -506,7 +506,7 @@ void addSkirts(
westEdgeIndices.begin(),
westEdgeIndices.end(),
sortEdgeIndices.begin(),
sortEdgeIndices.begin() + westVertexCount,
sortEdgeIndices.begin() + (ptrdiff_t)westVertexCount,
[&uvsAndHeights](auto lhs, auto rhs) noexcept {
return uvsAndHeights[lhs].y < uvsAndHeights[rhs].y;
});
@ -539,7 +539,7 @@ void addSkirts(
southEdgeIndices.begin(),
southEdgeIndices.end(),
sortEdgeIndices.begin(),
sortEdgeIndices.begin() + southVertexCount,
sortEdgeIndices.begin() + (ptrdiff_t)southVertexCount,
[&uvsAndHeights](auto lhs, auto rhs) noexcept {
return uvsAndHeights[lhs].x > uvsAndHeights[rhs].x;
});
@ -572,7 +572,7 @@ void addSkirts(
eastEdgeIndices.begin(),
eastEdgeIndices.end(),
sortEdgeIndices.begin(),
sortEdgeIndices.begin() + eastVertexCount,
sortEdgeIndices.begin() + (ptrdiff_t)eastVertexCount,
[&uvsAndHeights](auto lhs, auto rhs) noexcept {
return uvsAndHeights[lhs].y > uvsAndHeights[rhs].y;
});
@ -605,7 +605,7 @@ void addSkirts(
northEdgeIndices.begin(),
northEdgeIndices.end(),
sortEdgeIndices.begin(),
sortEdgeIndices.begin() + northVertexCount,
sortEdgeIndices.begin() + (ptrdiff_t)northVertexCount,
[&uvsAndHeights](auto lhs, auto rhs) noexcept {
return uvsAndHeights[lhs].x < uvsAndHeights[rhs].x;
});
@ -754,7 +754,7 @@ QuantizedMeshMetadataResult processMetadata(
// decode position without skirt, but preallocate position buffer to include
// skirt as well
std::vector<std::byte> outputPositionsBuffer(
static_cast<uint64_t>((vertexCount + skirtVertexCount) * 3) *
static_cast<size_t>((vertexCount + skirtVertexCount) * 3) *
sizeof(float));
std::span<float> outputPositions(
reinterpret_cast<float*>(outputPositionsBuffer.data()),

View File

@ -49,6 +49,7 @@ target_link_libraries(CesiumRasterOverlays
CesiumUtility
CesiumVectorData
nonstd::expected-lite
spdlog::spdlog_header_only
PRIVATE
tinyxml2::tinyxml2
)

View File

@ -591,7 +591,7 @@ RasterOverlayUtilities::upsampleGltfForRasterOverlays(
// We're assuming here that nothing references primitives by index, so we
// can remove them without any drama.
if (!keep) {
mesh.primitives.erase(mesh.primitives.begin() + int64_t(i));
mesh.primitives.erase(mesh.primitives.begin() + ptrdiff_t(i));
--i;
}
containsPrimitives |= !mesh.primitives.empty();

View File

@ -38,11 +38,24 @@ cesium_target_include_directories(
${CMAKE_CURRENT_LIST_DIR}/src
)
target_link_libraries(
CesiumUtility
PUBLIC
zlib-ng::zlib-ng
spdlog::spdlog
glm::glm
ada::ada
)
# for some reason, spdlog_header_only causes non-wasm builds to fail
if (CESIUM_TARGET_WASM)
target_link_libraries(
CesiumUtility
PUBLIC
zlib-ng::zlib-ng
#spdlog::spdlog
spdlog::spdlog_header_only
glm::glm
ada::ada
)
else()
target_link_libraries(
CesiumUtility
PUBLIC
zlib-ng::zlib-ng
spdlog::spdlog
glm::glm
ada::ada
)
endif()

View File

@ -1,6 +1,7 @@
#pragma once
#include <cstddef>
#include <cstdint>
namespace CesiumUtility {
@ -17,7 +18,7 @@ struct Hash {
* @param second The second hash value.
* @return A new hash value which is a combination of the two.
*/
static std::size_t combine(std::size_t first, std::size_t second);
static size_t combine(uint64_t first, uint64_t second);
};
} // namespace CesiumUtility

View File

@ -59,8 +59,8 @@ namespace CesiumUtility {
// (https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html)
namespace {
inline std::size_t mix(std::size_t x) {
std::size_t const m = 0xe9846af9b1a615d;
inline uint64_t mix(uint64_t x) {
uint64_t const m = 0xe9846af9b1a615d;
x ^= x >> 32;
x *= m;
@ -74,8 +74,9 @@ inline std::size_t mix(std::size_t x) {
} // namespace
// This function is adapted from Boost's `hash_combine`.
std::size_t Hash::combine(std::size_t first, std::size_t second) {
return mix(first + 0x9e3779b9 + second);
std::size_t Hash::combine(uint64_t first, uint64_t second) {
// This will truncate bits on 32-bit builds.
return static_cast<std::size_t>(mix(first + 0x9e3779b9 + second));
}
} // namespace CesiumUtility

View File

@ -44,7 +44,7 @@ cesium_target_include_directories(
${CMAKE_CURRENT_LIST_DIR}/src
)
if(NOT IOS AND NOT VCPKG_CMAKE_SYSTEM_NAME MATCHES "iOS")
if(NOT CESIUM_TARGET_WASM AND NOT IOS AND NOT VCPKG_CMAKE_SYSTEM_NAME MATCHES "iOS")
set(CESIUM_VECTOR_DATA_ASMJIT_DEPENDENCY asmjit::asmjit)
endif()

View File

@ -93,7 +93,7 @@ VectorRasterizer::VectorRasterizer(
imageHeight,
BL_FORMAT_PRGB32,
reinterpret_cast<void*>(pData),
(int64_t)imageWidth * (int64_t)this->_imageAsset->channels);
(intptr_t)(imageWidth * this->_imageAsset->channels));
this->_context.begin(this->_image);
// Initialize the image as all transparent.

View File

@ -3,3 +3,10 @@
# else()
# add_compile_options(-Werror -Wall -Wextra -Wconversion -Wpedantic -Wshadow -Wsign-conversion)
# endif()
if(CESIUM_TARGET_WASM)
add_compile_options(-pthread -msimd128 -mnontrapping-fptoint -fwasm-exceptions -sSUPPORT_LONGJMP=wasm -DHAS_FUTIME=0)
add_link_options(-pthread -sALLOW_MEMORY_GROWTH=1 -sPTHREAD_POOL_SIZE=4 -sMAXIMUM_MEMORY=4294967296 -sMIN_NODE_VERSION=200000 -sINITIAL_MEMORY=268435456 -sSTACK_SIZE=1048576 -fwasm-exceptions -mbulk-memory -mnontrapping-fptoint -msse4.2 -sMALLOC=mimalloc -sWASM_BIGINT -sSUPPORT_LONGJMP=wasm -sFORCE_FILESYSTEM -sPROXY_TO_PTHREAD)
add_link_options($<$<CONFIG:Debug>:-gsource-map>)
endif()

View File

@ -1,4 +1,6 @@
if(ANDROID)
if(CESIUM_TARGET_WASM)
set(DETECTED_VCPKG_TRIPLET "wasm32-emscripten")
elseif(ANDROID)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(DETECTED_VCPKG_TRIPLET "x64-android")
else()

View File

@ -161,7 +161,7 @@ macro(EZVCPKG_BOOTSTRAP)
endmacro()
macro(EZVCPKG_BUILD)
set(INSTALL_COMMAND "${EZVCPKG_EXE}" --vcpkg-root "${EZVCPKG_DIR}" install --triplet ${VCPKG_TRIPLET})
set(INSTALL_COMMAND "${EZVCPKG_EXE}" --allow-unsupported --vcpkg-root "${EZVCPKG_DIR}" install --triplet ${VCPKG_TRIPLET})
if (DEFINED VCPKG_OVERLAY_PORTS)
if (CMAKE_HOST_WIN32)

View File

@ -2,7 +2,11 @@ function(configure_cesium_library targetName)
if (MSVC)
target_compile_options(${targetName} PRIVATE /W4 /WX /wd4201 /bigobj /w45038 /w44254 /w44242 /w44191 /w45220)
else()
target_compile_options(${targetName} PRIVATE -Werror -Wall -Wextra -Wconversion -Wpedantic -Wshadow -Wsign-conversion -Wno-unknown-pragmas)
if (CESIUM_TARGET_WASM)
target_compile_options(${targetName} PRIVATE -Wall -Wextra -Wconversion -Wpedantic -Wshadow -Wsign-conversion -Wno-unknown-pragmas)
else()
target_compile_options(${targetName} PRIVATE -Werror -Wall -Wextra -Wconversion -Wpedantic -Wshadow -Wsign-conversion -Wno-unknown-pragmas)
endif()
endif()
set_target_properties(${targetName} PROPERTIES
@ -32,6 +36,7 @@ function(configure_cesium_library targetName)
PUBLIC
GLM_FORCE_INTRINSICS # Force SIMD code paths
GLM_ENABLE_EXPERIMENTAL # Allow use of experimental extensions
SPDLOG_HEADER_ONLY # Use header-only spdlog implementation
)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CESIUM_CLANG_TIME_TRACE)
@ -46,6 +51,21 @@ function(configure_cesium_library targetName)
)
endif()
if(CESIUM_TARGET_WASM)
# std::format is better behaved with wasm builds than fmt::format
# Emscripten 3.1.39 doesn't like std::format
#target_compile_definitions(
#${targetName}
#PUBLIC
#SPDLOG_USE_STD_FORMAT)
# Emscripten 3.1.39 doesn't like <sys/utime.h> from tidyhtml
target_compile_definitions(
${targetName}
PUBLIC
HAS_FUTIME=0)
endif()
if (BUILD_SHARED_LIBS)
target_compile_definitions(
${targetName}

View File

@ -2,7 +2,10 @@
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
"dependencies": [
"asyncplusplus",
"curl",
{
"name": "curl",
"platform": "!wasm32"
},
"doctest",
"expected-lite",
"glm",
@ -33,13 +36,13 @@
"features": [
{
"name": "jit",
"platform": "!ios"
"platform": "!ios&!wasm32"
}
]
},
{
"name": "asmjit",
"platform": "!ios"
"platform": "!ios&!wasm32"
}
]
}