Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ include/*
share/*
bin/*
thirdparty_build/*
thirdparty_sources/*
.vscode/*
distr/*
*.log
Expand Down Expand Up @@ -58,3 +59,4 @@ compile_commands.json
/scripts/mrbind/msys2_packages
/scripts/mrbind/msys2_pacman_install.log
/vcpkg_installed
/installed
41 changes: 16 additions & 25 deletions cmake/Modules/ConfigureEmscripten.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# reference: https://github.com/emscripten-core/emscripten/blob/main/src/settings.js
string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS
string(JOIN " " EXTRA_CXX_FLAGS
# I would use the new-style flag spelling here, but it doesn't work on the old EMSDK 3.1.38 that we
# have to support for Unity compatibility.
#"--use-port=boost_headers"
Expand All @@ -12,36 +12,22 @@ string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS
"-sUSE_ZLIB" # TODO: make optional
)

option(MR_EMSCRIPTEN_WASM2023 "Enable Unity's WebAssembly 2023 target (a set of general-purpose optimizations, including SIMD)" ON)
IF(MR_EMSCRIPTEN_WASM2023)
# Those flags come from here: https://docs.unity3d.com/6000.7/Documentation/Manual/webgl-native-plugins-with-emscripten.html
# Skipping `-fwasm-exceptions` because we don't use exceptions.
# Skipping `-sSUPPORT_LONGJMP=wasm` because that conflicts with our `-s NO_DISABLE_EXCEPTION_CATCHING=1`, and also prevents CMake from finding FreeType during configuration.
# In theory, this flag is supposed to be implemented in terms of `-fwasm-exceptions`, so I'm not sure how it works without that one, but it seems to work (other than the issues above).
# Either way, we don't use `longjmp()`, so it doesn't seem terribly useful.
string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}
"-msimd128 -mbulk-memory -mnontrapping-fptoint -msse4.2"
)
ENDIF()
string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS
string(JOIN " " EXTRA_EXE_LINKER_FLAGS
"-s ALLOW_MEMORY_GROWTH=1"
"-s LLD_REPORT_UNDEFINED=1"
"-s STACK_SIZE=1048576" # required for GDCM
)

option(MR_EMSCRIPTEN_MIMALLOC "Use mimalloc allocator (-s MALLOC=mimalloc) for Emscripten builds" ON)
IF(MR_EMSCRIPTEN_MIMALLOC)
set(MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS "${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} -s MALLOC=mimalloc")
set(EXTRA_EXE_LINKER_FLAGS "${EXTRA_EXE_LINKER_FLAGS} -s MALLOC=mimalloc")
ENDIF()

IF(MR_EMSCRIPTEN_SINGLETHREAD)
set(MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS "${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} -s ENVIRONMENT=web,node")
set(EXTRA_EXE_LINKER_FLAGS "${EXTRA_EXE_LINKER_FLAGS} -s ENVIRONMENT=web,node")
ELSE()
string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}
"-pthread"
# look https://github.com/emscripten-core/emscripten/issues/8287
"-Wno-pthreads-mem-growth"
)
# look https://github.com/emscripten-core/emscripten/issues/8287
string(JOIN " " EXTRA_CXX_FLAGS ${EXTRA_CXX_FLAGS} "-Wno-pthreads-mem-growth")

# uncomment to enable source map for debugging in browsers (slow)
#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gsource-map")
Expand All @@ -51,7 +37,7 @@ ELSE()
ELSE()
set(MAXIMUM_MEMORY 4GB)
ENDIF()
string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS}
string(JOIN " " EXTRA_EXE_LINKER_FLAGS ${EXTRA_EXE_LINKER_FLAGS}
"-s ENVIRONMENT=web,worker,node"
#"-pthread"
"-s PTHREAD_POOL_SIZE_STRICT=0"
Expand All @@ -61,21 +47,26 @@ ELSE()
ENDIF()

IF(MESHLIB_BUILD_MRVIEWER)
string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS}
string(JOIN " " EXTRA_EXE_LINKER_FLAGS ${EXTRA_EXE_LINKER_FLAGS}
"-s EXPORTED_RUNTIME_METHODS=[ccall]"
"-s USE_WEBGL2=1"
"-s USE_GLFW=3"
"-s FULL_ES3=1"
)

IF(NOT MR_DISABLE_EMSCRIPTEN_ASYNCIFY)
string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS}
string(JOIN " " EXTRA_EXE_LINKER_FLAGS ${EXTRA_EXE_LINKER_FLAGS}
"-s ASYNCIFY"
# FIXME: comment required
"-Wno-limited-postlink-optimizations"
)
ENDIF()
ENDIF()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS}")
string(APPEND CMAKE_CXX_FLAGS " ${EXTRA_CXX_FLAGS}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${EXTRA_EXE_LINKER_FLAGS}")
string(APPEND MESHLIB_EMSCRIPTEN_CXX_FLAGS " ${EXTRA_CXX_FLAGS}")
string(APPEND MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS " ${EXTRA_EXE_LINKER_FLAGS}")

unset(EXTRA_CXX_FLAGS)
unset(EXTRA_EXE_LINKER_FLAGS)
37 changes: 37 additions & 0 deletions cmake/Modules/DefaultEmscriptenOptions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# this file must be included BEFORE the `project' command: MEMORY64 has to be in effect while CMake probes the compiler

if(MR_EMSCRIPTEN)
if(MR_EMSCRIPTEN_WASM64)
string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}
"-s MEMORY64=1"
)
string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS}
"-s MEMORY64=1"
)
endif()

if(NOT MR_EMSCRIPTEN_SINGLETHREAD)
string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}
"-pthread"
)
endif()

option(MR_EMSCRIPTEN_WASM2023 "Enable Unity's WebAssembly 2023 target (a set of general-purpose optimizations, including SIMD)" ON)
if(MR_EMSCRIPTEN_WASM2023)
# Those flags come from here: https://docs.unity3d.com/6000.7/Documentation/Manual/webgl-native-plugins-with-emscripten.html
# Skipping `-fwasm-exceptions` because we don't use exceptions.
# Skipping `-sSUPPORT_LONGJMP=wasm` because that conflicts with our `-s NO_DISABLE_EXCEPTION_CATCHING=1`, and also prevents CMake from finding FreeType during configuration.
# In theory, this flag is supposed to be implemented in terms of `-fwasm-exceptions`, so I'm not sure how it works without that one, but it seems to work (other than the issues above).
# Either way, we don't use `longjmp()`, so it doesn't seem terribly useful.
string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}
"-msimd128"
"-mbulk-memory"
"-mnontrapping-fptoint"
"-msse4.2"
)
endif()

string(APPEND CMAKE_C_FLAGS " ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}")
string(APPEND CMAKE_CXX_FLAGS " ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS}")
endif()
13 changes: 5 additions & 8 deletions cmake/Modules/DefaultOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ ENDIF()
set(CMAKE_CXX_STANDARD ${MR_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED ON)

IF(MR_EMSCRIPTEN AND MR_EMSCRIPTEN_WASM64)
# required to be set before `project()' command for correct platform detection
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s MEMORY64=1")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MEMORY64=1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MEMORY64=1")
ENDIF()

add_compile_definitions(MR_USE_CMAKE_CONFIGURE_FILE)

# MSVC debug information format
IF(POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:Embedded>")
ENDIF()
ENDIF()

if(MR_EMSCRIPTEN)
include(DefaultEmscriptenOptions)
endif()
138 changes: 138 additions & 0 deletions scripts/build_cpm_thirdparty.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/bin/bash

# This script builds thirdparty with CPM from `thirdparty/cpm`
# Usage: ./scripts/build_cpm_thirdparty.sh [INSTALL_PREFIX]

# exit if any command failed
set -eo pipefail

dt=$(date '+%d-%m-%Y_%H:%M:%S');
logfile="`pwd`/install_thirdparty_${dt}.log"
echo "Thirdparty build script started."
echo "You could find output in ${logfile}"

# NOTE: realpath is not supported on older macOS versions
BASE_DIR=$( cd "$( dirname "$0" )"/.. ; pwd -P )
SCRIPT_DIR=${BASE_DIR}/scripts/

MESHLIB_THIRDPARTY_DIR=${BASE_DIR}/thirdparty/cpm/
MESHLIB_THIRDPARTY_BUILD_DIR="${MESHLIB_THIRDPARTY_BUILD_DIR:-${BASE_DIR}/thirdparty_build/}"

MESHLIB_THIRDPARTY_ROOT_DIR="${1:-./installed}"
mkdir -p "${MESHLIB_THIRDPARTY_ROOT_DIR}"
MESHLIB_THIRDPARTY_ROOT_DIR=$( cd "${MESHLIB_THIRDPARTY_ROOT_DIR}" ; pwd -P )

if [[ $OSTYPE == 'darwin'* ]]; then
echo "Host system: MacOS"
INSTALL_REQUIREMENTS="install_brew_requirements.sh"
elif [[ $OSTYPE == 'linux'* ]]; then
source /etc/os-release
echo "Host system: ${NAME} ${DISTRIB_RELEASE}"
if [[ "${ID}" == "ubuntu" ]] || [[ "${ID_LIKE}" == *"ubuntu"* ]]; then
INSTALL_REQUIREMENTS="install_apt_requirements.sh"
fi
else
echo "Host system: ${OSTYPE}"
fi

. "$SCRIPT_DIR/ask_emscripten_mode.src"

if [ $MR_EMSCRIPTEN == "ON" ]; then
true # Nothing.
elif [ -n "${INSTALL_REQUIREMENTS}" ]; then
echo "Check requirements. Running ${INSTALL_REQUIREMENTS} ..."
${SCRIPT_DIR}/$INSTALL_REQUIREMENTS
else
echo "Unsupported system. Installing dependencies is your responsibility."
fi

# FIXME: make it optional
rm -rf "${MESHLIB_THIRDPARTY_BUILD_DIR}"
mkdir -p "${MESHLIB_THIRDPARTY_BUILD_DIR}"
# FIXME: make it optional
for SUBDIR in lib include share ; do
rm -rf "${MESHLIB_THIRDPARTY_ROOT_DIR}"/${SUBDIR}
mkdir -p "${MESHLIB_THIRDPARTY_ROOT_DIR}"/${SUBDIR}
done

MR_CMAKE_OPTIONS="${MR_CMAKE_OPTIONS} \
-D CMAKE_INSTALL_PREFIX=${MESHLIB_THIRDPARTY_ROOT_DIR} \
-D CMAKE_BUILD_TYPE=Release \
"

if [ "${MR_EMSCRIPTEN}" != "ON" ] ; then
CMAKE_C_COMPILER="${CMAKE_C_COMPILER:-${CC}}"
if [ -n "${CMAKE_C_COMPILER}" ] ; then
MR_CMAKE_OPTIONS="${MR_CMAKE_OPTIONS} -D CMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
fi

CMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER:-${CXX}}"
if [ -n "${CMAKE_CXX_COMPILER}" ] ; then
MR_CMAKE_OPTIONS="${MR_CMAKE_OPTIONS} -D CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"

# special conditions for Clang on macOS
if [[ $OSTYPE == 'darwin'* ]] && command -v brew >/dev/null 2>&1; then
HOMEBREW_PREFIX=$(brew --prefix)
if [[ "${CMAKE_CXX_COMPILER}" == "${HOMEBREW_PREFIX}"* ]] ; then
# use system libc++ instead of Clang's one
MACOS_SDK_PATH=$(xcrun --show-sdk-path | xargs) # trim trailing whitespace
CXXFLAGS="-nostdinc++ -isystem ${MACOS_SDK_PATH}/usr/include/c++/v1 -isysroot ${MACOS_SDK_PATH}"
LDFLAGS="-nostdlib++ -L${MACOS_SDK_PATH}/usr/lib -lc++ -lc++abi"
# use Homebrew zlib instead of system one
MR_CMAKE_OPTIONS="${MR_CMAKE_OPTIONS} -D ZLIB_ROOT=$(brew --prefix zlib)"
fi
fi
fi
fi

if command -v ninja >/dev/null 2>&1 ; then
MR_CMAKE_OPTIONS="${MR_CMAKE_OPTIONS} -G Ninja"
fi

if [ "${MR_EMSCRIPTEN}" == "ON" ]; then
if [ -z "${EMSDK}" ] ; then
echo "Emscripten SDK not found"
exit 1
fi
EMSCRIPTEN_ROOT="${EMSDK}/upstream/emscripten"

export CFLAGS=""
export CXXFLAGS=""
export LDFLAGS=""
[[ ${MR_EMSCRIPTEN_WASM2023:=} ]] || export MR_EMSCRIPTEN_WASM2023=1
MR_CMAKE_OPTIONS="${MR_CMAKE_OPTIONS} \
-D CMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN_ROOT}/cmake/Modules/Platform/Emscripten.cmake \
-D CMAKE_FIND_ROOT_PATH=${MESHLIB_THIRDPARTY_ROOT_DIR} \
-D MR_EMSCRIPTEN=1 \
-D MR_EMSCRIPTEN_SINGLETHREAD=${MR_EMSCRIPTEN_SINGLETHREAD} \
-D MR_EMSCRIPTEN_WASM64=${MR_EMSCRIPTEN_WASM64} \
-D MR_EMSCRIPTEN_WASM2023=${MR_EMSCRIPTEN_WASM2023} \
"
fi

if [[ $OSTYPE == 'darwin'* ]]; then
NPROC=$(sysctl -n hw.logicalcpu)
else
NPROC=$(nproc)
fi

# CPM downloads dependency sources here. Kept outside MESHLIB_THIRDPARTY_BUILD_DIR, which is
# wiped above, so a rebuild re-configures without re-downloading.
export CPM_SOURCE_CACHE="${CPM_SOURCE_CACHE:-${BASE_DIR}/thirdparty_sources}"

# build
echo "Starting build..."
pushd "${MESHLIB_THIRDPARTY_BUILD_DIR}"
for STAGE in stage1 stage2 ; do
cmake -S ${MESHLIB_THIRDPARTY_DIR}/${STAGE} -B ${STAGE} ${MR_CMAKE_OPTIONS}
cmake --build ${STAGE} -j ${NPROC}
cmake --install ${STAGE}
done

if [ "${MR_EMSCRIPTEN}" == "ON" ]; then
# remove excess header files as they're distributed by Emscripten
find ${MESHLIB_THIRDPARTY_ROOT_DIR}/include/boost -mindepth 1 -maxdepth 1 -not -name 'locale*' -exec rm -r "{}" \;
fi
popd

printf "\rThirdparty build script successfully finished. Required libs located in ${MESHLIB_THIRDPARTY_ROOT_DIR} folder. You could run ./scripts/build_source.sh\n\n"
30 changes: 30 additions & 0 deletions scripts/fetch_cpm_thirdparty.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

# This script downloads thirdparty sources with CPM from `thirdparty/cpm` without building them
# Usage: ./scripts/fetch_cpm_thirdparty.sh [PACKAGE...]
# Fetches the given packages (all of thirdparty/cpm/package-lock.cmake by default) into CPM_SOURCE_CACHE
# and prints one `SRC_<package>=<path>` line per package.

set -eo pipefail

# NOTE: realpath is not supported on older macOS versions
BASE_DIR=$( cd "$( dirname "$0" )"/.. ; pwd -P )

MESHLIB_THIRDPARTY_DIR=${BASE_DIR}/thirdparty/cpm/
MESHLIB_THIRDPARTY_FETCH_DIR=${BASE_DIR}/build/thirdparty_fetch/
MESHLIB_FETCH_OUTPUT=${MESHLIB_THIRDPARTY_FETCH_DIR}/thirdparty_sources.sh

export CPM_SOURCE_CACHE="${CPM_SOURCE_CACHE:-${BASE_DIR}/thirdparty_sources}"

if [ $# -gt 0 ] ; then
PACKAGES=$( IFS=';' ; echo "$*" )
else
PACKAGES=$( sed -n 's/^set(MESHLIB_PACKAGE_\(.*\)$/\1/p' "${MESHLIB_THIRDPARTY_DIR}/package-lock.cmake" | paste -sd ';' )
fi

cmake -S "${MESHLIB_THIRDPARTY_DIR}/fetch" -B "${MESHLIB_THIRDPARTY_FETCH_DIR}" \
-D CPM_SOURCE_CACHE="${CPM_SOURCE_CACHE}" \
-D MESHLIB_FETCH_PACKAGES="${PACKAGES}" \
-D MESHLIB_FETCH_OUTPUT="${MESHLIB_FETCH_OUTPUT}" \
1>&2
cat "${MESHLIB_FETCH_OUTPUT}"
3 changes: 3 additions & 0 deletions source/MRIOExtras/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ IF(NOT MRIOEXTRAS_NO_CTM)
ENDIF()

IF(NOT MRIOEXTRAS_NO_E57)
find_package(E57Format CONFIG REQUIRED
HINTS "${MESHLIB_THIRDPARTY_ROOT_DIR}"
)
target_link_libraries(${PROJECT_NAME} PRIVATE E57Format)

IF(MSVC AND DEFINED VCPKG_INSTALLED_DIR AND DEFINED VCPKG_TARGET_TRIPLET)
Expand Down
Loading
Loading