From 8a8d08fcb1704c5c2952d10bedc3a92a28e5eab6 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sat, 15 Aug 2026 22:47:16 +0200 Subject: [PATCH 01/19] WIP: Use CPM instead of submodules for third-party libraries --- .../install-macos-thirdparty/action.yml | 38 +- .../build-test-emscripten-c-bindings.yml | 2 +- .github/workflows/build-test-emscripten.yml | 6 +- .github/workflows/build-test-linux-vcpkg.yml | 2 +- .github/workflows/build-test-ubuntu-arm64.yml | 2 +- .github/workflows/build-test-ubuntu-x64.yml | 2 +- .github/workflows/build-test-windows.yml | 2 +- .github/workflows/pip-build.yml | 2 +- .github/workflows/update-docs-manual.yml | 2 +- .gitignore | 1 + .gitmodules | 78 - docker/emscripten-build-c-bindingsDockerfile | 1 + docker/emscriptenDockerfile | 1 + docs/third_party_licenses.md | 18 +- scripts/build_thirdparty.sh | 39 +- scripts/check_third_party_licenses.py | 64 +- scripts/clone_submodules_emscripten.sh | 23 - .../clone_submodules_emscripten_bindings.sh | 7 - scripts/clone_submodules_linux.sh | 21 +- scripts/clone_submodules_macos.sh | 11 - scripts/clone_submodules_windows.ps1 | 5 - scripts/cmake_install.sh | 4 +- .../devops/docker_image_source_checksum.sh | 1 - scripts/mrbind/generate.mk | 36 +- scripts/thirdparty/boost-libs-download.sh | 19 - scripts/thirdparty/boost-libs.sh | 15 - scripts/thirdparty/clip.sh | 16 - scripts/thirdparty/eigen.sh | 14 - scripts/thirdparty/fastmcpp.sh | 16 - scripts/thirdparty/libE57Format.sh | 14 - scripts/thirdparty/libjpeg-turbo.sh | 17 - scripts/thirdparty/mbedtls.sh | 14 - scripts/thirdparty/openvdb.sh | 23 - thirdparty/cmake/CPM.cmake | 1379 +++++++++++++++++ thirdparty/common_post_project.cmake | 28 + thirdparty/common_pre_project.cmake | 26 + thirdparty/fetch/CMakeLists.txt | 22 + thirdparty/licenses/manifest.json | 121 +- thirdparty/package-lock.cmake | 150 ++ .../patches/boost-locale-no-thread.patch | 11 + .../patches}/boost-locale-std-mutex.patch | 30 +- thirdparty/{ => stage1}/CMakeLists.txt | 127 +- thirdparty/stage2/CMakeLists.txt | 64 + 43 files changed, 1944 insertions(+), 530 deletions(-) delete mode 100755 scripts/thirdparty/boost-libs-download.sh delete mode 100755 scripts/thirdparty/boost-libs.sh delete mode 100755 scripts/thirdparty/clip.sh delete mode 100755 scripts/thirdparty/eigen.sh delete mode 100755 scripts/thirdparty/fastmcpp.sh delete mode 100755 scripts/thirdparty/libE57Format.sh delete mode 100755 scripts/thirdparty/libjpeg-turbo.sh delete mode 100755 scripts/thirdparty/mbedtls.sh delete mode 100755 scripts/thirdparty/openvdb.sh create mode 100644 thirdparty/cmake/CPM.cmake create mode 100644 thirdparty/common_post_project.cmake create mode 100644 thirdparty/common_pre_project.cmake create mode 100644 thirdparty/fetch/CMakeLists.txt create mode 100644 thirdparty/package-lock.cmake create mode 100644 thirdparty/patches/boost-locale-no-thread.patch rename {scripts/thirdparty => thirdparty/patches}/boost-locale-std-mutex.patch (83%) rename thirdparty/{ => stage1}/CMakeLists.txt (56%) create mode 100644 thirdparty/stage2/CMakeLists.txt diff --git a/.github/actions/install-macos-thirdparty/action.yml b/.github/actions/install-macos-thirdparty/action.yml index 7a68a3978afa..3be401fafa70 100644 --- a/.github/actions/install-macos-thirdparty/action.yml +++ b/.github/actions/install-macos-thirdparty/action.yml @@ -91,10 +91,12 @@ runs: # the prefix is baked into mrbind's rpath. # - thirdparty-hash: unified hash of everything that influences the # thirdparty ./lib + ./include outputs -- brew prefix (baked into the - # rpaths of the produced .dylibs), submodule SHAs pinned in HEAD (the - # source we compile), and the build-relevant scripts + CMakeLists + - # brew-requirements list. `git ls-tree` reads gitlink entries from the - # index, so it works whether or not the submodules are checked out. + # rpaths of the produced .dylibs), the dependency versions (pinned in + # package-lock.cmake, plus the mrbind-pybind11 gitlink for the one + # dependency that is still a submodule), and the build-relevant scripts + + # stage projects + brew-requirements list. `git ls-tree` reads gitlink + # entries from the index, so it works whether or not the submodule is + # checked out. - name: Compute cache key inputs id: cache-keys shell: bash @@ -104,23 +106,14 @@ runs: echo "brew-hash=$(printf %s "$BREW_PREFIX" | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT" echo "thirdparty-hash=$( { printf '%s\n' "$BREW_PREFIX" - git ls-tree HEAD \ - thirdparty/googletest \ - thirdparty/OpenCTM-git \ - thirdparty/parallel-hashmap \ - thirdparty/libE57Format \ - thirdparty/glad \ - thirdparty/mrbind-pybind11 \ - thirdparty/tinygltf \ - thirdparty/laz-perf \ - thirdparty/clip \ - thirdparty/fastmcpp + git ls-tree HEAD thirdparty/mrbind-pybind11 shasum -a 256 \ scripts/build_thirdparty.sh \ scripts/install_brew_requirements.sh \ - scripts/thirdparty/clip.sh \ - scripts/thirdparty/fastmcpp.sh \ - thirdparty/CMakeLists.txt \ + thirdparty/package-lock.cmake \ + thirdparty/common.cmake \ + thirdparty/stage1/CMakeLists.txt \ + thirdparty/stage2/CMakeLists.txt \ requirements/macos.txt } | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT" @@ -137,6 +130,15 @@ runs: include key: ${{ inputs.cache-prefix }}-${{ inputs.cache-instance }}-${{ inputs.cache-compiler }}-${{ steps.cache-keys.outputs.thirdparty-hash }} + # CPM downloads dependency sources here when the build runs. Keyed on the pins alone -- + # sources are independent of runner and compiler, so every instance shares one entry. + - name: Cache thirdparty sources + if: ${{ steps.thirdparty-cache.outputs.cache-hit != 'true' }} + uses: actions/cache@v5 + with: + path: thirdparty_sources + key: ${{ inputs.cache-prefix }}-sources-${{ hashFiles('thirdparty/package-lock.cmake') }} + # Always run: cached thirdparty .dylibs link against brew libs at runtime, # so brew packages must be installed on hosted runners even on cache hit. - name: Install brew requirements diff --git a/.github/workflows/build-test-emscripten-c-bindings.yml b/.github/workflows/build-test-emscripten-c-bindings.yml index 56a018542179..6139d502a954 100644 --- a/.github/workflows/build-test-emscripten-c-bindings.yml +++ b/.github/workflows/build-test-emscripten-c-bindings.yml @@ -75,7 +75,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-emscripten.yml b/.github/workflows/build-test-emscripten.yml index 055ce65933a7..2a03e01c4230 100644 --- a/.github/workflows/build-test-emscripten.yml +++ b/.github/workflows/build-test-emscripten.yml @@ -85,7 +85,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh - name: Install thirdparty libs run: | @@ -191,7 +191,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh - name: Install thirdparty libs run: | @@ -277,7 +277,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty + bash scripts/retry.sh -- scripts/clone_submodules_emscripten.sh - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index 01c13ed17fe3..aaf8da184c8c 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -121,7 +121,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux_vcpkg.sh --skip-prebuilt-thirdparty + scripts/clone_submodules_linux_vcpkg.sh - name: Install MRBind if: ${{ inputs.mrbind || inputs.mrbind_c }} diff --git a/.github/workflows/build-test-ubuntu-arm64.yml b/.github/workflows/build-test-ubuntu-arm64.yml index 7dc3578bf7cd..a519a1e4e1ba 100644 --- a/.github/workflows/build-test-ubuntu-arm64.yml +++ b/.github/workflows/build-test-ubuntu-arm64.yml @@ -94,7 +94,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory '*' # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux.sh --skip-prebuilt-thirdparty + scripts/clone_submodules_linux.sh - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-ubuntu-x64.yml b/.github/workflows/build-test-ubuntu-x64.yml index 09314c466fc0..c743ff5b6227 100644 --- a/.github/workflows/build-test-ubuntu-x64.yml +++ b/.github/workflows/build-test-ubuntu-x64.yml @@ -73,7 +73,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory '*' # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux.sh --skip-prebuilt-thirdparty + scripts/clone_submodules_linux.sh - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-windows.yml b/.github/workflows/build-test-windows.yml index 02d8194ce309..88200ea3f0f9 100644 --- a/.github/workflows/build-test-windows.yml +++ b/.github/workflows/build-test-windows.yml @@ -72,7 +72,7 @@ jobs: - name: Checkout third-party submodules shell: bash run: | - bash scripts/retry.sh --timeout 300 -- powershell scripts/clone_submodules_windows.ps1 --skip-prebuilt-thirdparty + bash scripts/retry.sh --timeout 300 -- powershell scripts/clone_submodules_windows.ps1 - name: Get AWS instance type uses: ./.github/actions/get-aws-instance-type diff --git a/.github/workflows/pip-build.yml b/.github/workflows/pip-build.yml index ee51e935edfb..c45902103137 100644 --- a/.github/workflows/pip-build.yml +++ b/.github/workflows/pip-build.yml @@ -259,7 +259,7 @@ jobs: git config --global --add safe.directory ${GITHUB_WORKSPACE}/thirdparty/mrbind git config --global --add safe.directory ${GITHUB_WORKSPACE}/thirdparty/mrbind/deps/cppdecl # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh - name: Install mrbind uses: ./.github/actions/build-mrbind diff --git a/.github/workflows/update-docs-manual.yml b/.github/workflows/update-docs-manual.yml index cf4e67a6de4b..20f10010904d 100644 --- a/.github/workflows/update-docs-manual.yml +++ b/.github/workflows/update-docs-manual.yml @@ -47,7 +47,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory '*' # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux.sh --skip-prebuilt-thirdparty + scripts/clone_submodules_linux.sh - name: Install thirdparty libs run: | diff --git a/.gitignore b/.gitignore index 3c8c8a91f832..1502c96ce1d5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ include/* share/* bin/* thirdparty_build/* +thirdparty_sources/* .vscode/* distr/* *.log diff --git a/.gitmodules b/.gitmodules index 1e3587ecdcfa..65154c99f6da 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,90 +1,12 @@ -[submodule "thirdparty/cpr"] - path = thirdparty/cpr - url = https://github.com/whoshuu/cpr.git -[submodule "thirdparty/parallel-hashmap"] - path = thirdparty/parallel-hashmap - url = https://github.com/greg7mdp/parallel-hashmap.git -[submodule "thirdparty/eigen"] - path = thirdparty/eigen - url = https://gitlab.com/libeigen/eigen.git -[submodule "thirdparty/expected"] - path = thirdparty/expected - url = https://github.com/Developer-Ecosystem-Engineering/expected.git -[submodule "thirdparty/googletest"] - path = thirdparty/googletest - url = https://github.com/google/googletest.git -[submodule "thirdparty/spdlog"] - path = thirdparty/spdlog - url = https://github.com/gabime/spdlog.git -[submodule "thirdparty/libzip"] - path = thirdparty/libzip - url = https://github.com/nih-at/libzip.git -[submodule "thirdparty/jsoncpp"] - path = thirdparty/jsoncpp - url = https://github.com/open-source-parsers/jsoncpp.git [submodule "thirdparty/imgui"] path = thirdparty/imgui url = https://github.com/ocornut/imgui.git -[submodule "thirdparty/glad"] - path = thirdparty/glad - url = https://github.com/Dav1dde/glad.git -[submodule "thirdparty/clip"] - path = thirdparty/clip - url = https://github.com/dacap/clip.git -[submodule "thirdparty/openvdb/v10/openvdb"] - path = thirdparty/openvdb/v10/openvdb - url = https://github.com/AcademySoftwareFoundation/openvdb -[submodule "thirdparty/tinygltf"] - path = thirdparty/tinygltf - url = https://github.com/syoyo/tinygltf -[submodule "thirdparty/onetbb"] - path = thirdparty/onetbb - url = https://github.com/oneapi-src/oneTBB.git -[submodule "thirdparty/libE57Format"] - path = thirdparty/libE57Format - url = https://github.com/MeshInspector/libE57Format -[submodule "thirdparty/laz-perf"] - path = thirdparty/laz-perf - url = https://github.com/MeshInspector/laz-perf -[submodule "thirdparty/mbedtls"] - path = thirdparty/mbedtls - url = https://github.com/Mbed-TLS/mbedtls -[submodule "thirdparty/GDCM"] - path = thirdparty/GDCM - url = https://github.com/malaterre/GDCM.git -[submodule "thirdparty/tinyxml2"] - path = thirdparty/tinyxml2 - url = https://github.com/leethomason/tinyxml2.git -[submodule "thirdparty/libjpeg-turbo"] - path = thirdparty/libjpeg-turbo - url = https://github.com/libjpeg-turbo/libjpeg-turbo.git -[submodule "thirdparty/c-blosc"] - path = thirdparty/c-blosc - url = https://github.com/Blosc/c-blosc.git -[submodule "thirdparty/fmt"] - path = thirdparty/fmt - url = https://github.com/fmtlib/fmt.git [submodule "thirdparty/mrbind-pybind11"] path = thirdparty/mrbind-pybind11 url = https://github.com/MeshInspector/mrbind-pybind11 [submodule "thirdparty/mrbind"] path = thirdparty/mrbind url = https://github.com/MeshInspector/mrbind -[submodule "thirdparty/OpenCTM-git"] - path = thirdparty/OpenCTM-git - url = https://github.com/MeshInspector/OpenCTM.git -[submodule "thirdparty/fastmcpp"] - path = thirdparty/fastmcpp - url = https://github.com/MeshInspector/fastmcpp -[submodule "thirdparty/nlohmann-json"] - path = thirdparty/nlohmann-json - url = https://github.com/nlohmann/json -[submodule "thirdparty/cpp-httplib"] - path = thirdparty/cpp-httplib - url = https://github.com/yhirose/cpp-httplib -[submodule "thirdparty/zlib-ng"] - path = thirdparty/zlib-ng - url = https://github.com/zlib-ng/zlib-ng.git [submodule "test_data"] path = test_data url = https://github.com/MeshInspector/MeshLibTestData.git diff --git a/docker/emscripten-build-c-bindingsDockerfile b/docker/emscripten-build-c-bindingsDockerfile index 111cacd7719f..91640907b6e3 100644 --- a/docker/emscripten-build-c-bindingsDockerfile +++ b/docker/emscripten-build-c-bindingsDockerfile @@ -52,6 +52,7 @@ COPY . . ENV MR_STATE=DOCKER_BUILD ENV MR_EMSCRIPTEN=ON +ENV CPM_SOURCE_CACHE=/opt/cpm-cache # 32-bit multi-threaded RUN < pinned ref, parsed from thirdparty/package-lock.cmake. + + The ref is the GIT_TAG (a release tag or a commit hash) or, for packages fetched as an + archive, the URL. Either changes whenever the dependency is bumped, which is all the + tripwire needs. + """ + global _CPM_PINS + if _CPM_PINS is None: + text = PACKAGE_LOCK.read_text(encoding="utf-8") + _CPM_PINS = {} + for name, body in re.findall(r"^set\(MESHLIB_PACKAGE_(\S+)(.*?)^\)$", text, + re.MULTILINE | re.DOTALL): + ref = re.search(r"^\s*(?:GIT_TAG|URL)\s+(\S+)$", body, re.MULTILINE) + if ref is None: + raise ValueError(f"package '{name}' in {PACKAGE_LOCK.name} " + f"declares neither GIT_TAG nor URL") + _CPM_PINS[name] = ref.group(1) + return _CPM_PINS + + +def cpm_pin(package): + pin = cpm_pins().get(package) + if pin is None: + raise ValueError(f"package '{package}' is not declared in {PACKAGE_LOCK.name}") + return pin + + def vcpkg_default_registry(): data = json.loads(VCPKG_JSON.read_text(encoding="utf-8")) reg = data["configuration"]["default-registry"] @@ -148,6 +188,8 @@ def current_version(source, resolve_registry=False): see check_vcpkg_baseline. """ t = source["type"] + if t == "cpm": + return cpm_pin(source["package"]) if t == "submodule": return submodule_sha(source["path"]) if t == "vcpkg-overlay": @@ -294,7 +336,7 @@ def check(): errors.append(f"unexpected entry {REL}/{entry.name} -- only " f"{', '.join(sorted(ALLOWED_ENTRIES))} belong here") - # 3b. shippable-looking submodules missing from the manifest (warning only) + # 3b. shippable-looking dependencies missing from the manifest (warning only) covered = {c["source"].get("path") for c in components if c["source"]["type"] == "submodule"} for path in gitmodules_paths(): @@ -303,6 +345,14 @@ def check(): warnings.append(f"submodule '{path}' is not in manifest.json and not in " f"EXCLUDED_SUBMODULES -- add a license entry or exclude it") + covered = {c["source"].get("package") for c in components + if c["source"]["type"] == "cpm"} + for package in cpm_pins(): + if package in covered or package in EXCLUDED_PACKAGES: + continue + warnings.append(f"package '{package}' is not in manifest.json and not in " + f"EXCLUDED_PACKAGES -- add a license entry or exclude it") + for w in warnings: print(f"WARNING: {w}", file=sys.stderr) for e in errors: diff --git a/scripts/clone_submodules_emscripten.sh b/scripts/clone_submodules_emscripten.sh index 2993667d7436..6ed707205509 100755 --- a/scripts/clone_submodules_emscripten.sh +++ b/scripts/clone_submodules_emscripten.sh @@ -8,28 +8,5 @@ SUBMODULES=( thirdparty/mrbind-pybind11 ) -if [[ $1 != --skip-prebuilt-thirdparty ]]; then - SUBMODULES+=( - thirdparty/c-blosc - thirdparty/clip - thirdparty/expected - thirdparty/fastmcpp - thirdparty/fmt - thirdparty/GDCM - thirdparty/glad - thirdparty/googletest - thirdparty/jsoncpp - thirdparty/laz-perf - thirdparty/libzip - thirdparty/onetbb - thirdparty/OpenCTM-git - thirdparty/parallel-hashmap - thirdparty/spdlog - thirdparty/tinygltf - thirdparty/tinyxml2 - thirdparty/zlib-ng - ) -fi - "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/.. "${SUBMODULES[@]}" "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/../thirdparty/mrbind deps/cppdecl diff --git a/scripts/clone_submodules_emscripten_bindings.sh b/scripts/clone_submodules_emscripten_bindings.sh index 4e77f6efcf69..65884d4c99f5 100755 --- a/scripts/clone_submodules_emscripten_bindings.sh +++ b/scripts/clone_submodules_emscripten_bindings.sh @@ -3,15 +3,8 @@ # This is to be used on platforms that generate C/C# bindings through Emscripten: on Windows, and optionally on Linux. Not needed on Mac. git -C "$(dirname "$BASH_SOURCE")"/.. submodule update --init --depth 1 \ - thirdparty/eigen \ - thirdparty/expected \ thirdparty/imgui \ - thirdparty/jsoncpp \ thirdparty/mrbind \ thirdparty/mrbind-pybind11 \ - thirdparty/onetbb \ - thirdparty/openvdb/v10/openvdb \ - thirdparty/parallel-hashmap \ - thirdparty/spdlog \ git -C "$(dirname "$BASH_SOURCE")"/../thirdparty/mrbind submodule update --init --depth 1 deps/cppdecl diff --git a/scripts/clone_submodules_linux.sh b/scripts/clone_submodules_linux.sh index 5bff1d2b4c80..6ed707205509 100755 --- a/scripts/clone_submodules_linux.sh +++ b/scripts/clone_submodules_linux.sh @@ -4,28 +4,9 @@ SCRIPT_DIR="$(dirname "$BASH_SOURCE")" SUBMODULES=( thirdparty/imgui - thirdparty/eigen - thirdparty/mrbind-pybind11 thirdparty/mrbind + thirdparty/mrbind-pybind11 ) -if [[ $1 != --skip-prebuilt-thirdparty ]]; then - SUBMODULES+=( - thirdparty/clip - thirdparty/cpp-httplib - thirdparty/cpr - thirdparty/fastmcpp - thirdparty/glad - thirdparty/laz-perf - thirdparty/libE57Format - thirdparty/nlohmann-json - thirdparty/OpenCTM-git - thirdparty/openvdb/v10/openvdb - thirdparty/parallel-hashmap - thirdparty/tinygltf - thirdparty/zlib-ng - ) -fi - "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/.. "${SUBMODULES[@]}" "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/../thirdparty/mrbind deps/cppdecl diff --git a/scripts/clone_submodules_macos.sh b/scripts/clone_submodules_macos.sh index 9c037f3a6518..6ed707205509 100755 --- a/scripts/clone_submodules_macos.sh +++ b/scripts/clone_submodules_macos.sh @@ -3,20 +3,9 @@ SCRIPT_DIR="$(dirname "$BASH_SOURCE")" SUBMODULES=( - thirdparty/clip - thirdparty/cpp-httplib - thirdparty/eigen - thirdparty/expected - thirdparty/fastmcpp - thirdparty/glad thirdparty/imgui - thirdparty/laz-perf - thirdparty/libE57Format thirdparty/mrbind thirdparty/mrbind-pybind11 - thirdparty/nlohmann-json - thirdparty/OpenCTM-git - thirdparty/tinygltf ) "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/.. "${SUBMODULES[@]}" diff --git a/scripts/clone_submodules_windows.ps1 b/scripts/clone_submodules_windows.ps1 index 1b72ce625379..076932300137 100644 --- a/scripts/clone_submodules_windows.ps1 +++ b/scripts/clone_submodules_windows.ps1 @@ -1,10 +1,5 @@ git -C "$PSScriptRoot\.." submodule update --init --depth 1 ` thirdparty/imgui ` - thirdparty/eigen ` - thirdparty/expected ` - thirdparty/fastmcpp ` - thirdparty/nlohmann-json ` - thirdparty/cpp-httplib ` thirdparty/mrbind ` thirdparty/mrbind-pybind11 ` diff --git a/scripts/cmake_install.sh b/scripts/cmake_install.sh index ec37f69fb1cf..b4dbbfac12fb 100755 --- a/scripts/cmake_install.sh +++ b/scripts/cmake_install.sh @@ -20,8 +20,6 @@ cmake_install () { cmake_install ${BASE_DIR}/build/Release cmake_install ${BASE_DIR}/build/Debug -cmake_install ${BASE_DIR}/thirdparty_build -# Emscripten dependencies -for BUILD_DIR in ${BASE_DIR}/thirdparty_build/*_build ; do +for BUILD_DIR in ${BASE_DIR}/thirdparty_build/stage* ; do cmake_install ${BUILD_DIR} done diff --git a/scripts/devops/docker_image_source_checksum.sh b/scripts/devops/docker_image_source_checksum.sh index 4c8457c8a267..1fa2e45edbe0 100755 --- a/scripts/devops/docker_image_source_checksum.sh +++ b/scripts/devops/docker_image_source_checksum.sh @@ -7,7 +7,6 @@ distro=$1 common=( scripts/build_thirdparty.sh scripts/ask_emscripten_mode.src - scripts/thirdparty thirdparty ':(exclude)thirdparty/install.bat' ':(exclude)thirdparty/vcpkg/**' diff --git a/scripts/mrbind/generate.mk b/scripts/mrbind/generate.mk index a1124c3f6ba9..90f3d3189c89 100644 --- a/scripts/mrbind/generate.mk +++ b/scripts/mrbind/generate.mk @@ -571,6 +571,24 @@ endif ifneq ($(TARGET),csharp) # Stuff below is for all languages except C#. C# logic is at the bottom of this makefile. +# Dependency sources we parse MeshLib headers against. `thirdparty/fetch` downloads them at the +# versions pinned in `thirdparty/package-lock.cmake` and writes `SRC_=` lines, which +# make re-reads after remaking the include below. Nothing here is built. +FETCH_PACKAGES := eigen +ifneq ($(IS_WINDOWS),) +FETCH_PACKAGES += parallel-hashmap +endif +ifneq ($(TARGETING_EMSCRIPTEN),) +FETCH_PACKAGES += expected spdlog parallel-hashmap onetbb jsoncpp googletest openvdb +endif + +THIRDPARTY_SOURCES_MK := $(TEMP_OUTPUT_DIR)/thirdparty_sources.mk +$(THIRDPARTY_SOURCES_MK): $(makefile_dir)../../thirdparty/package-lock.cmake + cmake -S $(makefile_dir)../../thirdparty/fetch -B $(TEMP_OUTPUT_DIR)/thirdparty_fetch \ + -D MESHLIB_FETCH_PACKAGES="$(subst $(space),;,$(sort $(FETCH_PACKAGES)))" \ + -D MESHLIB_FETCH_OUTPUT=$(abspath $@) +include $(THIRDPARTY_SOURCES_MK) + INPUT_GLOBS := *.h ifeq ($(TARGET),python) @@ -600,7 +618,7 @@ ifneq ($(DEPS_INCLUDE_DIR),) COMPILER_FLAGS += -I$(DEPS_INCLUDE_DIR)/eigen3 endif # TODO: use system Eigen -COMPILER_FLAGS += -isystem $(makefile_dir)../../thirdparty/eigen +COMPILER_FLAGS += -isystem $(SRC_eigen) COMPILER_FLAGS += -isystem $(makefile_dir)../../thirdparty/mrbind-pybind11/include COMPILER_FLAGS_LIBCLANG := $(call load_file,$(makefile_dir)parser_only_flags.txt) COMPILER := $(CXX_FOR_BINDINGS) $(subst $(lf), ,$(call load_file,$(makefile_dir)compiler_only_flags.txt)) -I$(makefile_dir) @@ -643,19 +661,19 @@ COMPILER_FLAGS_LIBCLANG += -stdlib=libstdc++ $(default_include_paths) else COMPILER_FLAGS_LIBCLANG += --sysroot=$(call quote,$(EMSCRIPTEN_SYSROOT)) COMPILER_FLAGS_LIBCLANG += -isystem $(call quote,$(EMSCRIPTEN_SYSROOT)/include/compat)# Mhm. -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/expected/include -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/spdlog/include +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_expected)/include +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_spdlog)/include #EMSCRIPTEN_THIRDPARTY_DIR := . #$(info EMSCRIPTEN_SYSROOT = `$(EMSCRIPTEN_THIRDPARTY_DIR)`) #COMPILER_FLAGS_LIBCLANG += -isystem $(call quote,$(EMSCRIPTEN_THIRDPARTY_DIR)/include) # Those would normally be in `./include`, but we try to avoid building third-party libraries... -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/parallel-hashmap -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/onetbb/include -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/jsoncpp/include -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/googletest/googletest/include -COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/openvdb/v10/openvdb/openvdb +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_parallel_hashmap) +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_onetbb)/include +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_jsoncpp)/include +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_googletest)/googletest/include +COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_openvdb)/openvdb # OpenVDB generates a file called `openvdb/version.h` during build. To avoid having to generate it, we add our own copy of it to the include path. COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)emscripten_headers COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)emscripten_headers/openvdb @@ -718,7 +736,7 @@ LINKER_FLAGS += -rtlib=platform # Don't generate .lib files. LINKER_FLAGS += -Wl,-noimplib # Library paths: -COMPILER_FLAGS += -isystem $(makefile_dir)../../thirdparty/parallel-hashmap +COMPILER_FLAGS += -isystem $(SRC_parallel_hashmap) COMPILER_FLAGS += -D_DLL -D_MT # Only seems to matter on VS2022 and not on VS2019, for some reason. COMPILER_FLAGS += -DNOMINMAX diff --git a/scripts/thirdparty/boost-libs-download.sh b/scripts/thirdparty/boost-libs-download.sh deleted file mode 100755 index 8939b59d8587..000000000000 --- a/scripts/thirdparty/boost-libs-download.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" - -SCRIPT_DIR="$(realpath "$(dirname "$BASH_SOURCE")")" - -# Boost libraries are so large it's unreasonable to download them via git -BOOST_VERSION="1.83.0" -if [ ! -d "${SOURCE_DIR}" ] ; then - cd $(dirname "${SOURCE_DIR}") - curl -L https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION}.tar.xz | tar xJ - mv boost-${BOOST_VERSION} $(basename "${SOURCE_DIR}") - - # to support the single-threaded version, we must compile Boost.Locale without Boost.Thread - cd "${SOURCE_DIR}/libs/locale/" - sed -i '/Boost::thread/d' CMakeLists.txt - patch -Np1 -i "${SCRIPT_DIR}/boost-locale-std-mutex.patch" -fi diff --git a/scripts/thirdparty/boost-libs.sh b/scripts/thirdparty/boost-libs.sh deleted file mode 100755 index 9a4749582eab..000000000000 --- a/scripts/thirdparty/boost-libs.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./boost-libs_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D CMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -D BOOST_INCLUDE_LIBRARIES=locale \ - -D BOOST_LOCALE_ENABLE_ICONV=OFF \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/clip.sh b/scripts/thirdparty/clip.sh deleted file mode 100755 index d0bcbc2e2924..000000000000 --- a/scripts/thirdparty/clip.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./clip_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D CLIP_EXAMPLES=OFF \ - -D CLIP_TESTS=OFF \ - -D CLIP_X11_WITH_PNG=OFF \ - -D BUILD_SHARED_LIBS=ON \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/eigen.sh b/scripts/thirdparty/eigen.sh deleted file mode 100755 index 18bac03f75b7..000000000000 --- a/scripts/thirdparty/eigen.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./eigen_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D EIGEN_BUILD_DOC=OFF \ - -D BUILD_TESTING=OFF \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/fastmcpp.sh b/scripts/thirdparty/fastmcpp.sh deleted file mode 100755 index abbc9b1b25fb..000000000000 --- a/scripts/thirdparty/fastmcpp.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./fastmcpp_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D FASTMCPP_BUILD_TESTS=OFF \ - -D FASTMCPP_BUILD_EXAMPLES=OFF \ - -D FASTMCPP_FETCH_CURL=OFF \ - -D CMAKE_CXX_FLAGS=-fPIC \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/libE57Format.sh b/scripts/thirdparty/libE57Format.sh deleted file mode 100755 index 8b5dec6341ae..000000000000 --- a/scripts/thirdparty/libE57Format.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./libE57Format_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D E57_BUILD_TEST=OFF \ - -D E57_XML_PARSER=TinyXML2 \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/libjpeg-turbo.sh b/scripts/thirdparty/libjpeg-turbo.sh deleted file mode 100755 index 9b23b34e9467..000000000000 --- a/scripts/thirdparty/libjpeg-turbo.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./libjpeg-turbo_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D WITH_JAVA=OFF \ - -D WITH_JPEG8=ON \ - -D WITH_SIMD=OFF \ - -D BUILD_TESTING=OFF \ - -D ENABLE_STATIC=OFF \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/mbedtls.sh b/scripts/thirdparty/mbedtls.sh deleted file mode 100755 index ad22ee62a749..000000000000 --- a/scripts/thirdparty/mbedtls.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./mbedtls_build}" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D ENABLE_PROGRAMS=OFF \ - -D ENABLE_TESTING=OFF \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/openvdb.sh b/scripts/thirdparty/openvdb.sh deleted file mode 100755 index 63139741d016..000000000000 --- a/scripts/thirdparty/openvdb.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -set -eo pipefail - -SOURCE_DIR="$1" -BUILD_DIR="${2:-./openvdb_build}" - -CXXFLAGS="${CXXFLAGS} -Wno-missing-template-arg-list-after-template-kw" - -CMAKE_OPTIONS="${CMAKE_OPTIONS} \ - -D OPENVDB_ENABLE_UNINSTALL=OFF \ - -D OPENVDB_ENABLE_INSTALL=OFF \ - -D OPENVDB_CORE_SHARED=ON \ - -D OPENVDB_CORE_STATIC=OFF \ - -D OPENVDB_BUILD_BINARIES=OFF \ - -D OPENVDB_BUILD_VDB_PRINT=OFF \ - -D OPENVDB_USE_DELAYED_LOADING=OFF \ - -D USE_EXPLICIT_INSTANTIATION=OFF \ - -D Tbb_VERSION=2021.12 \ -" - -cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} -cmake --build "${BUILD_DIR}" -j `nproc` -cmake --install "${BUILD_DIR}" diff --git a/thirdparty/cmake/CPM.cmake b/thirdparty/cmake/CPM.cmake new file mode 100644 index 000000000000..e7bb536a48ed --- /dev/null +++ b/thirdparty/cmake/CPM.cmake @@ -0,0 +1,1379 @@ +# CPM.cmake - CMake's missing package manager +# =========================================== +# See https://github.com/cpm-cmake/CPM.cmake for usage and update instructions. +# +# MIT License +# ----------- +#[[ + Copyright (c) 2019-2023 Lars Melchior and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +]] + +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +# Initialize logging prefix +if(NOT CPM_INDENT) + set(CPM_INDENT + "CPM:" + CACHE INTERNAL "" + ) +endif() + +if(NOT COMMAND cpm_message) + function(cpm_message) + message(${ARGV}) + endfunction() +endif() + +if(DEFINED EXTRACTED_CPM_VERSION) + set(CURRENT_CPM_VERSION "${EXTRACTED_CPM_VERSION}${CPM_DEVELOPMENT}") +else() + set(CURRENT_CPM_VERSION 0.43.1) +endif() + +get_filename_component(CPM_CURRENT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" REALPATH) +if(CPM_DIRECTORY) + if(NOT CPM_DIRECTORY STREQUAL CPM_CURRENT_DIRECTORY) + if(CPM_VERSION VERSION_LESS CURRENT_CPM_VERSION) + message( + AUTHOR_WARNING + "${CPM_INDENT} \ +A dependency is using a more recent CPM version (${CURRENT_CPM_VERSION}) than the current project (${CPM_VERSION}). \ +It is recommended to upgrade CPM to the most recent version. \ +See https://github.com/cpm-cmake/CPM.cmake for more information." + ) + endif() + if(${CMAKE_VERSION} VERSION_LESS "3.17.0") + include(FetchContent) + endif() + return() + endif() + + get_property( + CPM_INITIALIZED GLOBAL "" + PROPERTY CPM_INITIALIZED + SET + ) + if(CPM_INITIALIZED) + return() + endif() +endif() + +if(CURRENT_CPM_VERSION MATCHES "development-version") + message( + WARNING "${CPM_INDENT} Your project is using an unstable development version of CPM.cmake. \ +Please update to a recent release if possible. \ +See https://github.com/cpm-cmake/CPM.cmake for details." + ) +endif() + +set_property(GLOBAL PROPERTY CPM_INITIALIZED true) + +macro(cpm_set_policies) + # the policy allows us to change options without caching + cmake_policy(SET CMP0077 NEW) + set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) + + # the policy allows us to change set(CACHE) without caching + if(POLICY CMP0126) + cmake_policy(SET CMP0126 NEW) + set(CMAKE_POLICY_DEFAULT_CMP0126 NEW) + endif() + + # The policy uses the download time for timestamp, instead of the timestamp in the archive. This + # allows for proper rebuilds when a projects url changes + if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) + set(CMAKE_POLICY_DEFAULT_CMP0135 NEW) + endif() + + # treat relative git repository paths as being relative to the parent project's remote + if(POLICY CMP0150) + cmake_policy(SET CMP0150 NEW) + set(CMAKE_POLICY_DEFAULT_CMP0150 NEW) + endif() +endmacro() +cpm_set_policies() + +option(CPM_USE_LOCAL_PACKAGES "Always try to use `find_package` to get dependencies" + $ENV{CPM_USE_LOCAL_PACKAGES} +) +option(CPM_LOCAL_PACKAGES_ONLY "Only use `find_package` to get dependencies" + $ENV{CPM_LOCAL_PACKAGES_ONLY} +) +option(CPM_DOWNLOAD_ALL "Always download dependencies from source" $ENV{CPM_DOWNLOAD_ALL}) +option(CPM_DONT_UPDATE_MODULE_PATH "Don't update the module path to allow using find_package" + $ENV{CPM_DONT_UPDATE_MODULE_PATH} +) +option(CPM_DONT_CREATE_PACKAGE_LOCK "Don't create a package lock file in the binary path" + $ENV{CPM_DONT_CREATE_PACKAGE_LOCK} +) +option(CPM_INCLUDE_ALL_IN_PACKAGE_LOCK + "Add all packages added through CPM.cmake to the package lock" + $ENV{CPM_INCLUDE_ALL_IN_PACKAGE_LOCK} +) +option(CPM_USE_NAMED_CACHE_DIRECTORIES + "Use additional directory of package name in cache on the most nested level." + $ENV{CPM_USE_NAMED_CACHE_DIRECTORIES} +) + +set(CPM_VERSION + ${CURRENT_CPM_VERSION} + CACHE INTERNAL "" +) +set(CPM_DIRECTORY + ${CPM_CURRENT_DIRECTORY} + CACHE INTERNAL "" +) +set(CPM_FILE + ${CMAKE_CURRENT_LIST_FILE} + CACHE INTERNAL "" +) +set(CPM_PACKAGES + "" + CACHE INTERNAL "" +) +set(CPM_DRY_RUN + OFF + CACHE INTERNAL "Don't download or configure dependencies (for testing)" +) + +if(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_SOURCE_CACHE_DEFAULT $ENV{CPM_SOURCE_CACHE}) +else() + set(CPM_SOURCE_CACHE_DEFAULT OFF) +endif() + +set(CPM_SOURCE_CACHE + ${CPM_SOURCE_CACHE_DEFAULT} + CACHE PATH "Directory to download CPM dependencies" +) + +if(NOT CPM_DONT_UPDATE_MODULE_PATH AND NOT DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR) + set(CPM_MODULE_PATH + "${CMAKE_BINARY_DIR}/CPM_modules" + CACHE INTERNAL "" + ) + # remove old modules + file(REMOVE_RECURSE ${CPM_MODULE_PATH}) + file(MAKE_DIRECTORY ${CPM_MODULE_PATH}) + # locally added CPM modules should override global packages + set(CMAKE_MODULE_PATH "${CPM_MODULE_PATH};${CMAKE_MODULE_PATH}") +endif() + +if(NOT CPM_DONT_CREATE_PACKAGE_LOCK) + set(CPM_PACKAGE_LOCK_FILE + "${CMAKE_BINARY_DIR}/cpm-package-lock.cmake" + CACHE INTERNAL "" + ) + file(WRITE ${CPM_PACKAGE_LOCK_FILE} + "# CPM Package Lock\n# This file should be committed to version control\n\n" + ) +endif() + +include(FetchContent) + +# Try to infer package name from git repository uri (path or url) +function(cpm_package_name_from_git_uri URI RESULT) + if("${URI}" MATCHES "([^/:]+)/?.git/?$") + set(${RESULT} + ${CMAKE_MATCH_1} + PARENT_SCOPE + ) + else() + unset(${RESULT} PARENT_SCOPE) + endif() +endfunction() + +# Find the shortest hash that can be used eg, if origin_hash is +# cccb77ae9609d2768ed80dd42cec54f77b1f1455 the following files will be checked, until one is found +# that is either empty (allowing us to assign origin_hash), or whose contents matches ${origin_hash} +# +# * .../cccb.hash +# * .../cccb77ae.hash +# * .../cccb77ae9609.hash +# * .../cccb77ae9609d276.hash +# * etc +# +# We will be able to use a shorter path with very high probability, but in the (rare) event that the +# first couple characters collide, we will check longer and longer substrings. +function(cpm_get_shortest_hash source_cache_dir origin_hash short_hash_output_var) + # for compatibility with caches populated by a previous version of CPM, check if a directory using + # the full hash already exists + if(EXISTS "${source_cache_dir}/${origin_hash}") + set(${short_hash_output_var} + "${origin_hash}" + PARENT_SCOPE + ) + return() + endif() + + foreach(len RANGE 4 40 4) + string(SUBSTRING "${origin_hash}" 0 ${len} short_hash) + set(hash_lock ${source_cache_dir}/${short_hash}.lock) + set(hash_fp ${source_cache_dir}/${short_hash}.hash) + # Take a lock, so we don't have a race condition with another instance of cmake. We will release + # this lock when we can, however, if there is an error, we want to ensure it gets released on + # it's own on exit from the function. + file(LOCK ${hash_lock} GUARD FUNCTION) + + # Load the contents of .../${short_hash}.hash + file(TOUCH ${hash_fp}) + file(READ ${hash_fp} hash_fp_contents) + + if(hash_fp_contents STREQUAL "") + # Write the origin hash + file(WRITE ${hash_fp} ${origin_hash}) + file(LOCK ${hash_lock} RELEASE) + break() + elseif(hash_fp_contents STREQUAL origin_hash) + file(LOCK ${hash_lock} RELEASE) + break() + else() + file(LOCK ${hash_lock} RELEASE) + endif() + endforeach() + set(${short_hash_output_var} + "${short_hash}" + PARENT_SCOPE + ) +endfunction() + +# Try to infer package name and version from a url +function(cpm_package_name_and_ver_from_url url outName outVer) + if(url MATCHES + "[/\\?]([a-zA-Z0-9_\\.-]+)\\.(tar|tar\\.gz|tar\\.bz2|tar\\.xz|tar\\.zst|zip|ZIP)(\\?|/|$)" + ) + # We matched an archive + set(filename "${CMAKE_MATCH_1}") + + if(filename MATCHES "([a-zA-Z0-9_\\.-]+)[_-]v?(([0-9]+\\.)*[0-9]+[a-zA-Z0-9]*)") + # We matched - (ie foo-1.2.3) + set(${outName} + "${CMAKE_MATCH_1}" + PARENT_SCOPE + ) + set(${outVer} + "${CMAKE_MATCH_2}" + PARENT_SCOPE + ) + elseif(filename MATCHES "(([0-9]+\\.)+[0-9]+[a-zA-Z0-9]*)") + # We couldn't find a name, but we found a version + # + # In many cases (which we don't handle here) the url would look something like + # `irrelevant/ACTUAL_PACKAGE_NAME/irrelevant/1.2.3.zip`. In such a case we can't possibly + # distinguish the package name from the irrelevant bits. Moreover if we try to match the + # package name from the filename, we'd get bogus at best. + unset(${outName} PARENT_SCOPE) + set(${outVer} + "${CMAKE_MATCH_1}" + PARENT_SCOPE + ) + else() + # Boldly assume that the file name is the package name. + # + # Yes, something like `irrelevant/ACTUAL_NAME/irrelevant/download.zip` will ruin our day, but + # such cases should be quite rare. No popular service does this... we think. + set(${outName} + "${filename}" + PARENT_SCOPE + ) + unset(${outVer} PARENT_SCOPE) + endif() + else() + # No ideas yet what to do with non-archives + unset(${outName} PARENT_SCOPE) + unset(${outVer} PARENT_SCOPE) + endif() +endfunction() + +function(cpm_find_package NAME VERSION) + string(REPLACE " " ";" EXTRA_ARGS "${ARGN}") + find_package(${NAME} ${VERSION} ${EXTRA_ARGS} QUIET) + if(${CPM_ARGS_NAME}_FOUND) + if(DEFINED ${CPM_ARGS_NAME}_VERSION) + set(VERSION ${${CPM_ARGS_NAME}_VERSION}) + endif() + cpm_message(STATUS "${CPM_INDENT} Using local package ${CPM_ARGS_NAME}@${VERSION}") + CPMRegisterPackage(${CPM_ARGS_NAME} "${VERSION}") + set(CPM_PACKAGE_FOUND + YES + PARENT_SCOPE + ) + else() + set(CPM_PACKAGE_FOUND + NO + PARENT_SCOPE + ) + endif() +endfunction() + +# Create a custom FindXXX.cmake module for a CPM package This prevents `find_package(NAME)` from +# finding the system library +function(cpm_create_module_file Name) + if(NOT CPM_DONT_UPDATE_MODULE_PATH) + if(DEFINED CMAKE_FIND_PACKAGE_REDIRECTS_DIR) + # Redirect find_package calls to the CPM package. This is what FetchContent does when you set + # OVERRIDE_FIND_PACKAGE. The CMAKE_FIND_PACKAGE_REDIRECTS_DIR works for find_package in CONFIG + # mode, unlike the Find${Name}.cmake fallback. CMAKE_FIND_PACKAGE_REDIRECTS_DIR is not defined + # in script mode, or in CMake < 3.24. + # https://cmake.org/cmake/help/latest/module/FetchContent.html#fetchcontent-find-package-integration-examples + string(TOLOWER ${Name} NameLower) + file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-config.cmake + "include(\"\${CMAKE_CURRENT_LIST_DIR}/${NameLower}-extra.cmake\" OPTIONAL)\n" + "include(\"\${CMAKE_CURRENT_LIST_DIR}/${Name}Extra.cmake\" OPTIONAL)\n" + ) + file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${NameLower}-config-version.cmake + "set(PACKAGE_VERSION_COMPATIBLE TRUE)\n" "set(PACKAGE_VERSION_EXACT TRUE)\n" + ) + else() + file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake + "include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)" + ) + endif() + endif() +endfunction() + +# Find a package locally or fallback to CPMAddPackage +function(CPMFindPackage) + set(oneValueArgs NAME VERSION GIT_TAG FIND_PACKAGE_ARGUMENTS) + + cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "" ${ARGN}) + + if(NOT DEFINED CPM_ARGS_VERSION) + if(DEFINED CPM_ARGS_GIT_TAG) + cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION) + endif() + endif() + + set(downloadPackage ${CPM_DOWNLOAD_ALL}) + if(DEFINED CPM_DOWNLOAD_${CPM_ARGS_NAME}) + set(downloadPackage ${CPM_DOWNLOAD_${CPM_ARGS_NAME}}) + elseif(DEFINED ENV{CPM_DOWNLOAD_${CPM_ARGS_NAME}}) + set(downloadPackage $ENV{CPM_DOWNLOAD_${CPM_ARGS_NAME}}) + endif() + if(downloadPackage) + CPMAddPackage(${ARGN}) + cpm_export_variables(${CPM_ARGS_NAME}) + return() + endif() + + cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS}) + + if(NOT CPM_PACKAGE_FOUND) + CPMAddPackage(${ARGN}) + cpm_export_variables(${CPM_ARGS_NAME}) + endif() + +endfunction() + +# checks if a package has been added before +function(cpm_check_if_package_already_added CPM_ARGS_NAME CPM_ARGS_VERSION) + if("${CPM_ARGS_NAME}" IN_LIST CPM_PACKAGES) + CPMGetPackageVersion(${CPM_ARGS_NAME} CPM_PACKAGE_VERSION) + if("${CPM_PACKAGE_VERSION}" VERSION_LESS "${CPM_ARGS_VERSION}") + message( + WARNING + "${CPM_INDENT} Requires a newer version of ${CPM_ARGS_NAME} (${CPM_ARGS_VERSION}) than currently included (${CPM_PACKAGE_VERSION})." + ) + endif() + cpm_get_fetch_properties(${CPM_ARGS_NAME}) + set(${CPM_ARGS_NAME}_ADDED NO) + set(CPM_PACKAGE_ALREADY_ADDED + YES + PARENT_SCOPE + ) + cpm_export_variables(${CPM_ARGS_NAME}) + else() + set(CPM_PACKAGE_ALREADY_ADDED + NO + PARENT_SCOPE + ) + endif() +endfunction() + +# Parse the argument of CPMAddPackage in case a single one was provided and convert it to a list of +# arguments which can then be parsed idiomatically. For example gh:foo/bar@1.2.3 will be converted +# to: GITHUB_REPOSITORY;foo/bar;VERSION;1.2.3 +function(cpm_parse_add_package_single_arg arg outArgs) + # Look for a scheme + if("${arg}" MATCHES "^([a-zA-Z]+):(.+)$") + string(TOLOWER "${CMAKE_MATCH_1}" scheme) + set(uri "${CMAKE_MATCH_2}") + + # Check for CPM-specific schemes + if(scheme STREQUAL "gh") + set(out "GITHUB_REPOSITORY;${uri}") + set(packageType "git") + elseif(scheme STREQUAL "gl") + set(out "GITLAB_REPOSITORY;${uri}") + set(packageType "git") + elseif(scheme STREQUAL "bb") + set(out "BITBUCKET_REPOSITORY;${uri}") + set(packageType "git") + # A CPM-specific scheme was not found. Looks like this is a generic URL so try to determine + # type + elseif(arg MATCHES ".git/?(@|#|$)") + set(out "GIT_REPOSITORY;${arg}") + set(packageType "git") + else() + # Fall back to a URL + set(out "URL;${arg}") + set(packageType "archive") + + # We could also check for SVN since FetchContent supports it, but SVN is so rare these days. + # We just won't bother with the additional complexity it will induce in this function. SVN is + # done by multi-arg + endif() + else() + if(arg MATCHES ".git/?(@|#|$)") + set(out "GIT_REPOSITORY;${arg}") + set(packageType "git") + else() + # Give up + message(FATAL_ERROR "${CPM_INDENT} Can't determine package type of '${arg}'") + endif() + endif() + + # For all packages we interpret @... as version. Only replace the last occurrence. Thus URIs + # containing '@' can be used + string(REGEX REPLACE "@([^@]+)$" ";VERSION;\\1" out "${out}") + + # Parse the rest according to package type + if(packageType STREQUAL "git") + # For git repos we interpret #... as a tag or branch or commit hash + string(REGEX REPLACE "#([^#]+)$" ";GIT_TAG;\\1" out "${out}") + elseif(packageType STREQUAL "archive") + # For archives we interpret #... as a URL hash. + string(REGEX REPLACE "#([^#]+)$" ";URL_HASH;\\1" out "${out}") + # We don't try to parse the version if it's not provided explicitly. cpm_get_version_from_url + # should do this at a later point + else() + # We should never get here. This is an assertion and hitting it means there's a problem with the + # code above. A packageType was set, but not handled by this if-else. + message(FATAL_ERROR "${CPM_INDENT} Unsupported package type '${packageType}' of '${arg}'") + endif() + + set(${outArgs} + ${out} + PARENT_SCOPE + ) +endfunction() + +# Check that the working directory for a git repo is clean +function(cpm_check_git_working_dir_is_clean repoPath gitTag isClean) + + find_package(Git REQUIRED) + + if(NOT GIT_EXECUTABLE) + # No git executable, assume directory is clean + set(${isClean} + TRUE + PARENT_SCOPE + ) + return() + endif() + + # check for uncommitted changes + execute_process( + COMMAND ${GIT_EXECUTABLE} status --porcelain + RESULT_VARIABLE resultGitStatus + OUTPUT_VARIABLE repoStatus + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET + WORKING_DIRECTORY ${repoPath} + ) + if(resultGitStatus) + # not supposed to happen, assume clean anyway + message(WARNING "${CPM_INDENT} Calling git status on folder ${repoPath} failed") + set(${isClean} + TRUE + PARENT_SCOPE + ) + return() + endif() + + if(NOT "${repoStatus}" STREQUAL "") + set(${isClean} + FALSE + PARENT_SCOPE + ) + return() + endif() + + # check for committed changes + execute_process( + COMMAND ${GIT_EXECUTABLE} diff -s --exit-code ${gitTag} + RESULT_VARIABLE resultGitDiff + OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_QUIET + WORKING_DIRECTORY ${repoPath} + ) + + if(${resultGitDiff} EQUAL 0) + set(${isClean} + TRUE + PARENT_SCOPE + ) + else() + set(${isClean} + FALSE + PARENT_SCOPE + ) + endif() + +endfunction() + +# Add PATCH_COMMAND to CPM_ARGS_UNPARSED_ARGUMENTS. This method consumes a list of files in ARGN +# then generates a `PATCH_COMMAND` appropriate for `ExternalProject_Add()`. This command is appended +# to the parent scope's `CPM_ARGS_UNPARSED_ARGUMENTS`. +function(cpm_add_patches) + # Return if no patch files are supplied. + if(NOT ARGN) + return() + endif() + + # Find the patch program. + find_program(PATCH_EXECUTABLE patch) + if(CMAKE_HOST_WIN32 AND NOT PATCH_EXECUTABLE) + # The Windows git executable is distributed with patch.exe. Find the path to the executable, if + # it exists, then search `../usr/bin` and `../../usr/bin` for patch.exe. + find_package(Git QUIET) + if(GIT_EXECUTABLE) + get_filename_component(extra_search_path ${GIT_EXECUTABLE} DIRECTORY) + get_filename_component(extra_search_path_1up ${extra_search_path} DIRECTORY) + get_filename_component(extra_search_path_2up ${extra_search_path_1up} DIRECTORY) + find_program( + PATCH_EXECUTABLE patch HINTS "${extra_search_path_1up}/usr/bin" + "${extra_search_path_2up}/usr/bin" + ) + endif() + endif() + if(NOT PATCH_EXECUTABLE) + message(FATAL_ERROR "Couldn't find `patch` executable to use with PATCHES keyword.") + endif() + + # Create a temporary + set(temp_list ${CPM_ARGS_UNPARSED_ARGUMENTS}) + + # Ensure each file exists (or error out) and add it to the list. + set(first_item True) + foreach(PATCH_FILE ${ARGN}) + # Make sure the patch file exists, if we can't find it, try again in the current directory. + if(NOT EXISTS "${PATCH_FILE}") + if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}") + message(FATAL_ERROR "Couldn't find patch file: '${PATCH_FILE}'") + endif() + set(PATCH_FILE "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}") + endif() + + # Convert to absolute path for use with patch file command. + get_filename_component(PATCH_FILE "${PATCH_FILE}" ABSOLUTE) + + # The first patch entry must be preceded by "PATCH_COMMAND" while the following items are + # preceded by "&&". + if(first_item) + set(first_item False) + list(APPEND temp_list "PATCH_COMMAND") + else() + list(APPEND temp_list "&&") + endif() + # Add the patch command to the list + list(APPEND temp_list "${PATCH_EXECUTABLE}" "-p1" "<" "${PATCH_FILE}") + endforeach() + + # Move temp out into parent scope. + set(CPM_ARGS_UNPARSED_ARGUMENTS + ${temp_list} + PARENT_SCOPE + ) + +endfunction() + +# method to overwrite internal FetchContent properties, to allow using CPM.cmake to overload +# FetchContent calls. As these are internal cmake properties, this method should be used carefully +# and may need modification in future CMake versions. Source: +# https://github.com/Kitware/CMake/blob/dc3d0b5a0a7d26d43d6cfeb511e224533b5d188f/Modules/FetchContent.cmake#L1152 +function(cpm_override_fetchcontent contentName) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "SOURCE_DIR;BINARY_DIR" "") + if(NOT "${arg_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "${CPM_INDENT} Unsupported arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + string(TOLOWER ${contentName} contentNameLower) + set(prefix "_FetchContent_${contentNameLower}") + + set(propertyName "${prefix}_sourceDir") + define_property( + GLOBAL + PROPERTY ${propertyName} + BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" + FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" + ) + set_property(GLOBAL PROPERTY ${propertyName} "${arg_SOURCE_DIR}") + + set(propertyName "${prefix}_binaryDir") + define_property( + GLOBAL + PROPERTY ${propertyName} + BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" + FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" + ) + set_property(GLOBAL PROPERTY ${propertyName} "${arg_BINARY_DIR}") + + set(propertyName "${prefix}_populated") + define_property( + GLOBAL + PROPERTY ${propertyName} + BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" + FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" + ) + set_property(GLOBAL PROPERTY ${propertyName} TRUE) +endfunction() + +# Download and add a package from source +function(CPMAddPackage) + cpm_set_policies() + + set(oneValueArgs + NAME + FORCE + VERSION + GIT_TAG + DOWNLOAD_ONLY + GITHUB_REPOSITORY + GITLAB_REPOSITORY + BITBUCKET_REPOSITORY + GIT_REPOSITORY + SOURCE_DIR + FIND_PACKAGE_ARGUMENTS + NO_CACHE + SYSTEM + GIT_SHALLOW + EXCLUDE_FROM_ALL + SOURCE_SUBDIR + CUSTOM_CACHE_KEY + ) + + set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND PATCHES) + + list(LENGTH ARGN argnLength) + + # Parse single shorthand argument + if(argnLength EQUAL 1) + cpm_parse_add_package_single_arg("${ARGN}" ARGN) + + # The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM + set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;") + + # Parse URI shorthand argument + elseif(argnLength GREATER 1 AND "${ARGV0}" STREQUAL "URI") + list(REMOVE_AT ARGN 0 1) # remove "URI gh:<...>@version#tag" + cpm_parse_add_package_single_arg("${ARGV1}" ARGV0) + + set(ARGN "${ARGV0};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;${ARGN}") + endif() + + cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}") + + # Set default values for arguments + if(NOT DEFINED CPM_ARGS_VERSION) + if(DEFINED CPM_ARGS_GIT_TAG) + cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION) + endif() + endif() + + if(CPM_ARGS_DOWNLOAD_ONLY) + set(DOWNLOAD_ONLY ${CPM_ARGS_DOWNLOAD_ONLY}) + else() + set(DOWNLOAD_ONLY NO) + endif() + + if(DEFINED CPM_ARGS_GITHUB_REPOSITORY) + set(CPM_ARGS_GIT_REPOSITORY "https://github.com/${CPM_ARGS_GITHUB_REPOSITORY}.git") + elseif(DEFINED CPM_ARGS_GITLAB_REPOSITORY) + set(CPM_ARGS_GIT_REPOSITORY "https://gitlab.com/${CPM_ARGS_GITLAB_REPOSITORY}.git") + elseif(DEFINED CPM_ARGS_BITBUCKET_REPOSITORY) + set(CPM_ARGS_GIT_REPOSITORY "https://bitbucket.org/${CPM_ARGS_BITBUCKET_REPOSITORY}.git") + endif() + + if(DEFINED CPM_ARGS_GIT_REPOSITORY) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_REPOSITORY ${CPM_ARGS_GIT_REPOSITORY}) + if(NOT DEFINED CPM_ARGS_GIT_TAG) + set(CPM_ARGS_GIT_TAG v${CPM_ARGS_VERSION}) + endif() + + # If a name wasn't provided, try to infer it from the git repo + if(NOT DEFINED CPM_ARGS_NAME) + cpm_package_name_from_git_uri(${CPM_ARGS_GIT_REPOSITORY} CPM_ARGS_NAME) + endif() + endif() + + set(CPM_SKIP_FETCH FALSE) + + if(DEFINED CPM_ARGS_GIT_TAG) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_TAG ${CPM_ARGS_GIT_TAG}) + # If GIT_SHALLOW is explicitly specified, honor the value. + if(DEFINED CPM_ARGS_GIT_SHALLOW) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_SHALLOW ${CPM_ARGS_GIT_SHALLOW}) + endif() + endif() + + if(DEFINED CPM_ARGS_URL) + # If a name or version aren't provided, try to infer them from the URL + list(GET CPM_ARGS_URL 0 firstUrl) + cpm_package_name_and_ver_from_url(${firstUrl} nameFromUrl verFromUrl) + # If we fail to obtain name and version from the first URL, we could try other URLs if any. + # However multiple URLs are expected to be quite rare, so for now we won't bother. + + # If the caller provided their own name and version, they trump the inferred ones. + if(NOT DEFINED CPM_ARGS_NAME) + set(CPM_ARGS_NAME ${nameFromUrl}) + endif() + if(NOT DEFINED CPM_ARGS_VERSION) + set(CPM_ARGS_VERSION ${verFromUrl}) + endif() + + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS URL "${CPM_ARGS_URL}") + endif() + + # Check for required arguments + + if(NOT DEFINED CPM_ARGS_NAME) + message( + FATAL_ERROR + "${CPM_INDENT} 'NAME' was not provided and couldn't be automatically inferred for package added with arguments: '${ARGN}'" + ) + endif() + + # Check if package has been added before + cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}") + if(CPM_PACKAGE_ALREADY_ADDED) + cpm_export_variables(${CPM_ARGS_NAME}) + return() + endif() + + if(NOT DEFINED CPM_${CPM_ARGS_NAME}_SOURCE AND DEFINED ENV{CPM_${CPM_ARGS_NAME}_SOURCE}) + # Normalize separators to support Windows paths when reading from environment variables. + file(TO_CMAKE_PATH "$ENV{CPM_${CPM_ARGS_NAME}_SOURCE}" CPM_${CPM_ARGS_NAME}_SOURCE) + message(WARNING "${CPM_INDENT} '${CPM_ARGS_NAME}' version overridden by environment variable " + "CPM_${CPM_ARGS_NAME}_SOURCE='${CPM_${CPM_ARGS_NAME}_SOURCE}'" + ) + endif() + + # Check for manual overrides + if(NOT CPM_ARGS_FORCE AND NOT "${CPM_${CPM_ARGS_NAME}_SOURCE}" STREQUAL "") + set(PACKAGE_SOURCE ${CPM_${CPM_ARGS_NAME}_SOURCE}) + set(CPM_${CPM_ARGS_NAME}_SOURCE "") + if(NOT DEFINED ENV{CPM_${CPM_ARGS_NAME}_SOURCE}) + message(WARNING "${CPM_INDENT} '${CPM_ARGS_NAME}' version overridden by CMake variable " + "CPM_${CPM_ARGS_NAME}_SOURCE='${PACKAGE_SOURCE}'" + ) + endif() + CPMAddPackage( + NAME "${CPM_ARGS_NAME}" + SOURCE_DIR "${PACKAGE_SOURCE}" + EXCLUDE_FROM_ALL "${CPM_ARGS_EXCLUDE_FROM_ALL}" + SYSTEM "${CPM_ARGS_SYSTEM}" + PATCHES "${CPM_ARGS_PATCHES}" + OPTIONS "${CPM_ARGS_OPTIONS}" + SOURCE_SUBDIR "${CPM_ARGS_SOURCE_SUBDIR}" + DOWNLOAD_ONLY "${DOWNLOAD_ONLY}" + FORCE True + ) + cpm_export_variables(${CPM_ARGS_NAME}) + return() + endif() + + # Check for available declaration + if(NOT CPM_ARGS_FORCE AND NOT "${CPM_DECLARATION_${CPM_ARGS_NAME}}" STREQUAL "") + set(declaration ${CPM_DECLARATION_${CPM_ARGS_NAME}}) + set(CPM_DECLARATION_${CPM_ARGS_NAME} "") + CPMAddPackage(${declaration}) + cpm_export_variables(${CPM_ARGS_NAME}) + # checking again to ensure version and option compatibility + cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}") + return() + endif() + + if(NOT CPM_ARGS_FORCE) + if(CPM_USE_LOCAL_PACKAGES OR CPM_LOCAL_PACKAGES_ONLY) + cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS}) + + if(CPM_PACKAGE_FOUND) + cpm_export_variables(${CPM_ARGS_NAME}) + return() + endif() + + if(CPM_LOCAL_PACKAGES_ONLY) + message( + SEND_ERROR + "${CPM_INDENT} ${CPM_ARGS_NAME} not found via find_package(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION})" + ) + endif() + endif() + endif() + + CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}") + + if(DEFINED CPM_ARGS_GIT_TAG) + set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}") + elseif(DEFINED CPM_ARGS_SOURCE_DIR) + set(PACKAGE_INFO "${CPM_ARGS_SOURCE_DIR}") + else() + set(PACKAGE_INFO "${CPM_ARGS_VERSION}") + endif() + + if(DEFINED FETCHCONTENT_BASE_DIR) + # respect user's FETCHCONTENT_BASE_DIR if set + set(CPM_FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR}) + else() + set(CPM_FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_deps) + endif() + + cpm_add_patches(${CPM_ARGS_PATCHES}) + + if(DEFINED CPM_ARGS_DOWNLOAD_COMMAND) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND}) + elseif(DEFINED CPM_ARGS_SOURCE_DIR) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${CPM_ARGS_SOURCE_DIR}) + if(NOT IS_ABSOLUTE ${CPM_ARGS_SOURCE_DIR}) + # Expand `CPM_ARGS_SOURCE_DIR` relative path. This is important because EXISTS doesn't work + # for relative paths. + get_filename_component( + source_directory ${CPM_ARGS_SOURCE_DIR} REALPATH BASE_DIR ${CMAKE_CURRENT_BINARY_DIR} + ) + else() + set(source_directory ${CPM_ARGS_SOURCE_DIR}) + endif() + if(NOT EXISTS ${source_directory}) + string(TOLOWER ${CPM_ARGS_NAME} lower_case_name) + # remove timestamps so CMake will re-download the dependency + file(REMOVE_RECURSE "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild") + endif() + elseif(CPM_SOURCE_CACHE AND NOT CPM_ARGS_NO_CACHE) + string(TOLOWER ${CPM_ARGS_NAME} lower_case_name) + set(origin_parameters ${CPM_ARGS_UNPARSED_ARGUMENTS}) + list(SORT origin_parameters) + if(CPM_ARGS_CUSTOM_CACHE_KEY) + # Application set a custom unique directory name + set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${CPM_ARGS_CUSTOM_CACHE_KEY}) + elseif(CPM_USE_NAMED_CACHE_DIRECTORIES) + string(SHA1 origin_hash "${origin_parameters};NEW_CACHE_STRUCTURE_TAG") + cpm_get_shortest_hash( + "${CPM_SOURCE_CACHE}/${lower_case_name}" # source cache directory + "${origin_hash}" # Input hash + origin_hash # Computed hash + ) + set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash}/${CPM_ARGS_NAME}) + else() + string(SHA1 origin_hash "${origin_parameters}") + cpm_get_shortest_hash( + "${CPM_SOURCE_CACHE}/${lower_case_name}" # source cache directory + "${origin_hash}" # Input hash + origin_hash # Computed hash + ) + set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash}) + endif() + # Expand `download_directory` relative path. This is important because EXISTS doesn't work for + # relative paths. + get_filename_component(download_directory ${download_directory} ABSOLUTE) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${download_directory}) + + if(CPM_SOURCE_CACHE) + file(LOCK ${download_directory}/../cmake.lock) + endif() + + if(EXISTS ${download_directory}) + if(CPM_SOURCE_CACHE) + file(LOCK ${download_directory}/../cmake.lock RELEASE) + endif() + + cpm_store_fetch_properties( + ${CPM_ARGS_NAME} "${download_directory}" + "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build" + ) + cpm_get_fetch_properties("${CPM_ARGS_NAME}") + + if(DEFINED CPM_ARGS_GIT_TAG AND NOT (PATCH_COMMAND IN_LIST CPM_ARGS_UNPARSED_ARGUMENTS)) + # warn if cache has been changed since checkout + cpm_check_git_working_dir_is_clean(${download_directory} ${CPM_ARGS_GIT_TAG} IS_CLEAN) + if(NOT ${IS_CLEAN}) + message( + WARNING "${CPM_INDENT} Cache for ${CPM_ARGS_NAME} (${download_directory}) is dirty" + ) + endif() + endif() + + cpm_add_subdirectory( + "${CPM_ARGS_NAME}" + "${DOWNLOAD_ONLY}" + "${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" + "${${CPM_ARGS_NAME}_BINARY_DIR}" + "${CPM_ARGS_EXCLUDE_FROM_ALL}" + "${CPM_ARGS_SYSTEM}" + "${CPM_ARGS_OPTIONS}" + ) + set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}") + + # As the source dir is already cached/populated, we override the call to FetchContent. + set(CPM_SKIP_FETCH TRUE) + cpm_override_fetchcontent( + "${lower_case_name}" SOURCE_DIR "${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" + BINARY_DIR "${${CPM_ARGS_NAME}_BINARY_DIR}" + ) + + else() + # Enable shallow clone when GIT_TAG is not a commit hash. Our guess may not be accurate, but + # it should guarantee no commit hash get mis-detected. + if(NOT DEFINED CPM_ARGS_GIT_SHALLOW) + cpm_is_git_tag_commit_hash("${CPM_ARGS_GIT_TAG}" IS_HASH) + if(NOT ${IS_HASH}) + list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS GIT_SHALLOW TRUE) + endif() + endif() + + # remove timestamps so CMake will re-download the dependency + file(REMOVE_RECURSE ${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild) + set(PACKAGE_INFO "${PACKAGE_INFO} to ${download_directory}") + endif() + endif() + + if(NOT "${DOWNLOAD_ONLY}") + cpm_create_module_file(${CPM_ARGS_NAME} "CPMAddPackage(\"${ARGN}\")") + endif() + + if(CPM_PACKAGE_LOCK_ENABLED) + if((CPM_ARGS_VERSION AND NOT CPM_ARGS_SOURCE_DIR) OR CPM_INCLUDE_ALL_IN_PACKAGE_LOCK) + cpm_add_to_package_lock(${CPM_ARGS_NAME} "${ARGN}") + elseif(CPM_ARGS_SOURCE_DIR) + cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "local directory") + else() + cpm_add_comment_to_package_lock(${CPM_ARGS_NAME} "${ARGN}") + endif() + endif() + + cpm_message( + STATUS "${CPM_INDENT} Adding package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION} (${PACKAGE_INFO})" + ) + + if(NOT CPM_SKIP_FETCH) + # CMake 3.28 added EXCLUDE, SYSTEM (3.25), and SOURCE_SUBDIR (3.18) to FetchContent_Declare. + # Calling FetchContent_MakeAvailable will then internally forward these options to + # add_subdirectory. Up until these changes, we had to call FetchContent_Populate and + # add_subdirectory separately, which is no longer necessary and has been deprecated as of 3.30. + # A Bug in CMake prevents us to use the non-deprecated functions until 3.30.3. + set(fetchContentDeclareExtraArgs "") + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3") + if(${CPM_ARGS_EXCLUDE_FROM_ALL}) + list(APPEND fetchContentDeclareExtraArgs EXCLUDE_FROM_ALL) + endif() + if(${CPM_ARGS_SYSTEM}) + list(APPEND fetchContentDeclareExtraArgs SYSTEM) + endif() + if(DEFINED CPM_ARGS_SOURCE_SUBDIR) + list(APPEND fetchContentDeclareExtraArgs SOURCE_SUBDIR ${CPM_ARGS_SOURCE_SUBDIR}) + endif() + # For CMake version <3.28 OPTIONS are parsed in cpm_add_subdirectory + if(CPM_ARGS_OPTIONS AND NOT DOWNLOAD_ONLY) + foreach(OPTION ${CPM_ARGS_OPTIONS}) + cpm_parse_option("${OPTION}") + set(${OPTION_KEY} "${OPTION_VALUE}") + endforeach() + endif() + endif() + cpm_declare_fetch( + "${CPM_ARGS_NAME}" ${fetchContentDeclareExtraArgs} "${CPM_ARGS_UNPARSED_ARGUMENTS}" + ) + + cpm_fetch_package("${CPM_ARGS_NAME}" ${DOWNLOAD_ONLY} populated ${CPM_ARGS_UNPARSED_ARGUMENTS}) + if(CPM_SOURCE_CACHE AND download_directory) + file(LOCK ${download_directory}/../cmake.lock RELEASE) + endif() + if(${populated} AND ${CMAKE_VERSION} VERSION_LESS "3.30.3") + cpm_add_subdirectory( + "${CPM_ARGS_NAME}" + "${DOWNLOAD_ONLY}" + "${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" + "${${CPM_ARGS_NAME}_BINARY_DIR}" + "${CPM_ARGS_EXCLUDE_FROM_ALL}" + "${CPM_ARGS_SYSTEM}" + "${CPM_ARGS_OPTIONS}" + ) + endif() + cpm_get_fetch_properties("${CPM_ARGS_NAME}") + endif() + + set(${CPM_ARGS_NAME}_ADDED YES) + cpm_export_variables("${CPM_ARGS_NAME}") +endfunction() + +# Fetch a previously declared package +macro(CPMGetPackage Name) + if(DEFINED "CPM_DECLARATION_${Name}") + CPMAddPackage(NAME ${Name}) + else() + message(SEND_ERROR "${CPM_INDENT} Cannot retrieve package ${Name}: no declaration available") + endif() +endmacro() + +# export variables available to the caller to the parent scope expects ${CPM_ARGS_NAME} to be set +macro(cpm_export_variables name) + set(${name}_SOURCE_DIR + "${${name}_SOURCE_DIR}" + PARENT_SCOPE + ) + set(${name}_BINARY_DIR + "${${name}_BINARY_DIR}" + PARENT_SCOPE + ) + set(${name}_ADDED + "${${name}_ADDED}" + PARENT_SCOPE + ) + set(CPM_LAST_PACKAGE_NAME + "${name}" + PARENT_SCOPE + ) +endmacro() + +# declares a package, so that any call to CPMAddPackage for the package name will use these +# arguments instead. Previous declarations will not be overridden. +macro(CPMDeclarePackage Name) + if(NOT DEFINED "CPM_DECLARATION_${Name}") + set("CPM_DECLARATION_${Name}" "${ARGN}") + endif() +endmacro() + +function(cpm_add_to_package_lock Name) + if(NOT CPM_DONT_CREATE_PACKAGE_LOCK) + cpm_prettify_package_arguments(PRETTY_ARGN false ${ARGN}) + file(APPEND ${CPM_PACKAGE_LOCK_FILE} "# ${Name}\nCPMDeclarePackage(${Name}\n${PRETTY_ARGN})\n") + endif() +endfunction() + +function(cpm_add_comment_to_package_lock Name) + if(NOT CPM_DONT_CREATE_PACKAGE_LOCK) + cpm_prettify_package_arguments(PRETTY_ARGN true ${ARGN}) + file(APPEND ${CPM_PACKAGE_LOCK_FILE} + "# ${Name} (unversioned)\n# CPMDeclarePackage(${Name}\n${PRETTY_ARGN}#)\n" + ) + endif() +endfunction() + +# includes the package lock file if it exists and creates a target `cpm-update-package-lock` to +# update it +macro(CPMUsePackageLock file) + if(NOT CPM_DONT_CREATE_PACKAGE_LOCK) + get_filename_component(CPM_ABSOLUTE_PACKAGE_LOCK_PATH ${file} ABSOLUTE) + if(EXISTS ${CPM_ABSOLUTE_PACKAGE_LOCK_PATH}) + include(${CPM_ABSOLUTE_PACKAGE_LOCK_PATH}) + endif() + if(NOT TARGET cpm-update-package-lock) + add_custom_target( + cpm-update-package-lock COMMAND ${CMAKE_COMMAND} -E copy ${CPM_PACKAGE_LOCK_FILE} + ${CPM_ABSOLUTE_PACKAGE_LOCK_PATH} + ) + endif() + set(CPM_PACKAGE_LOCK_ENABLED true) + endif() +endmacro() + +# registers a package that has been added to CPM +function(CPMRegisterPackage PACKAGE VERSION) + list(APPEND CPM_PACKAGES ${PACKAGE}) + set(CPM_PACKAGES + ${CPM_PACKAGES} + CACHE INTERNAL "" + ) + set("CPM_PACKAGE_${PACKAGE}_VERSION" + ${VERSION} + CACHE INTERNAL "" + ) +endfunction() + +# retrieve the current version of the package to ${OUTPUT} +function(CPMGetPackageVersion PACKAGE OUTPUT) + set(${OUTPUT} + "${CPM_PACKAGE_${PACKAGE}_VERSION}" + PARENT_SCOPE + ) +endfunction() + +# declares a package in FetchContent_Declare +function(cpm_declare_fetch PACKAGE) + if(${CPM_DRY_RUN}) + cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)") + return() + endif() + + FetchContent_Declare(${PACKAGE} ${ARGN}) +endfunction() + +# returns properties for a package previously defined by cpm_declare_fetch +function(cpm_get_fetch_properties PACKAGE) + if(${CPM_DRY_RUN}) + return() + endif() + + set(${PACKAGE}_SOURCE_DIR + "${CPM_PACKAGE_${PACKAGE}_SOURCE_DIR}" + PARENT_SCOPE + ) + set(${PACKAGE}_BINARY_DIR + "${CPM_PACKAGE_${PACKAGE}_BINARY_DIR}" + PARENT_SCOPE + ) +endfunction() + +function(cpm_store_fetch_properties PACKAGE source_dir binary_dir) + if(${CPM_DRY_RUN}) + return() + endif() + + set(CPM_PACKAGE_${PACKAGE}_SOURCE_DIR + "${source_dir}" + CACHE INTERNAL "" + ) + set(CPM_PACKAGE_${PACKAGE}_BINARY_DIR + "${binary_dir}" + CACHE INTERNAL "" + ) +endfunction() + +# adds a package as a subdirectory if viable, according to provided options +function( + cpm_add_subdirectory + PACKAGE + DOWNLOAD_ONLY + SOURCE_DIR + BINARY_DIR + EXCLUDE + SYSTEM + OPTIONS +) + + if(NOT DOWNLOAD_ONLY AND EXISTS ${SOURCE_DIR}/CMakeLists.txt) + set(addSubdirectoryExtraArgs "") + if(EXCLUDE) + list(APPEND addSubdirectoryExtraArgs EXCLUDE_FROM_ALL) + endif() + if("${SYSTEM}" AND "${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.25") + # https://cmake.org/cmake/help/latest/prop_dir/SYSTEM.html#prop_dir:SYSTEM + list(APPEND addSubdirectoryExtraArgs SYSTEM) + endif() + if(OPTIONS) + foreach(OPTION ${OPTIONS}) + cpm_parse_option("${OPTION}") + set(${OPTION_KEY} "${OPTION_VALUE}") + endforeach() + endif() + set(CPM_OLD_INDENT "${CPM_INDENT}") + set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:") + add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs}) + set(CPM_INDENT "${CPM_OLD_INDENT}") + endif() +endfunction() + +# downloads a previously declared package via FetchContent and exports the variables +# `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope +function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY populated) + set(${populated} + FALSE + PARENT_SCOPE + ) + if(${CPM_DRY_RUN}) + cpm_message(STATUS "${CPM_INDENT} Package ${PACKAGE} not fetched (dry run)") + return() + endif() + + FetchContent_GetProperties(${PACKAGE}) + + string(TOLOWER "${PACKAGE}" lower_case_name) + + if(NOT ${lower_case_name}_POPULATED) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30.3") + if(DOWNLOAD_ONLY) + # MakeAvailable will call add_subdirectory internally which is not what we want when + # DOWNLOAD_ONLY is set. Populate will only download the dependency without adding it to the + # build + FetchContent_Populate( + ${PACKAGE} + SOURCE_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-src" + BINARY_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build" + SUBBUILD_DIR "${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild" + ${ARGN} + ) + else() + FetchContent_MakeAvailable(${PACKAGE}) + endif() + else() + FetchContent_Populate(${PACKAGE}) + endif() + set(${populated} + TRUE + PARENT_SCOPE + ) + endif() + + cpm_store_fetch_properties( + ${CPM_ARGS_NAME} ${${lower_case_name}_SOURCE_DIR} ${${lower_case_name}_BINARY_DIR} + ) + + set(${PACKAGE}_SOURCE_DIR + ${${lower_case_name}_SOURCE_DIR} + PARENT_SCOPE + ) + set(${PACKAGE}_BINARY_DIR + ${${lower_case_name}_BINARY_DIR} + PARENT_SCOPE + ) +endfunction() + +# splits a package option +function(cpm_parse_option OPTION) + string(REGEX MATCH "^[^ ]+" OPTION_KEY "${OPTION}") + string(LENGTH "${OPTION}" OPTION_LENGTH) + string(LENGTH "${OPTION_KEY}" OPTION_KEY_LENGTH) + if(OPTION_KEY_LENGTH STREQUAL OPTION_LENGTH) + # no value for key provided, assume user wants to set option to "ON" + set(OPTION_VALUE "ON") + else() + math(EXPR OPTION_KEY_LENGTH "${OPTION_KEY_LENGTH}+1") + string(SUBSTRING "${OPTION}" "${OPTION_KEY_LENGTH}" "-1" OPTION_VALUE) + string(STRIP "${OPTION_VALUE}" OPTION_VALUE) + endif() + set(OPTION_KEY + "${OPTION_KEY}" + PARENT_SCOPE + ) + set(OPTION_VALUE + "${OPTION_VALUE}" + PARENT_SCOPE + ) +endfunction() + +# guesses the package version from a git tag +function(cpm_get_version_from_git_tag GIT_TAG RESULT) + string(LENGTH ${GIT_TAG} length) + if(length EQUAL 40) + # GIT_TAG is probably a git hash + set(${RESULT} + 0 + PARENT_SCOPE + ) + else() + string(REGEX MATCH "v?([0123456789.]*).*" _ ${GIT_TAG}) + set(${RESULT} + ${CMAKE_MATCH_1} + PARENT_SCOPE + ) + endif() +endfunction() + +# guesses if the git tag is a commit hash or an actual tag or a branch name. +function(cpm_is_git_tag_commit_hash GIT_TAG RESULT) + string(LENGTH "${GIT_TAG}" length) + # full hash has 40 characters, and short hash has at least 7 characters. + if(length LESS 7 OR length GREATER 40) + set(${RESULT} + 0 + PARENT_SCOPE + ) + else() + if(${GIT_TAG} MATCHES "^[a-fA-F0-9]+$") + set(${RESULT} + 1 + PARENT_SCOPE + ) + else() + set(${RESULT} + 0 + PARENT_SCOPE + ) + endif() + endif() +endfunction() + +function(cpm_prettify_package_arguments OUT_VAR IS_IN_COMMENT) + set(oneValueArgs + NAME + FORCE + VERSION + GIT_TAG + DOWNLOAD_ONLY + GITHUB_REPOSITORY + GITLAB_REPOSITORY + BITBUCKET_REPOSITORY + GIT_REPOSITORY + SOURCE_DIR + FIND_PACKAGE_ARGUMENTS + NO_CACHE + SYSTEM + GIT_SHALLOW + EXCLUDE_FROM_ALL + SOURCE_SUBDIR + ) + set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND) + cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + foreach(oneArgName ${oneValueArgs}) + if(DEFINED CPM_ARGS_${oneArgName}) + if(${IS_IN_COMMENT}) + string(APPEND PRETTY_OUT_VAR "#") + endif() + if(${oneArgName} STREQUAL "SOURCE_DIR") + string(REPLACE ${CMAKE_SOURCE_DIR} "\${CMAKE_SOURCE_DIR}" CPM_ARGS_${oneArgName} + ${CPM_ARGS_${oneArgName}} + ) + endif() + string(APPEND PRETTY_OUT_VAR " ${oneArgName} ${CPM_ARGS_${oneArgName}}\n") + endif() + endforeach() + foreach(multiArgName ${multiValueArgs}) + if(DEFINED CPM_ARGS_${multiArgName}) + if(${IS_IN_COMMENT}) + string(APPEND PRETTY_OUT_VAR "#") + endif() + string(APPEND PRETTY_OUT_VAR " ${multiArgName}\n") + foreach(singleOption ${CPM_ARGS_${multiArgName}}) + if(${IS_IN_COMMENT}) + string(APPEND PRETTY_OUT_VAR "#") + endif() + string(APPEND PRETTY_OUT_VAR " \"${singleOption}\"\n") + endforeach() + endif() + endforeach() + + if(NOT "${CPM_ARGS_UNPARSED_ARGUMENTS}" STREQUAL "") + if(${IS_IN_COMMENT}) + string(APPEND PRETTY_OUT_VAR "#") + endif() + string(APPEND PRETTY_OUT_VAR " ") + foreach(CPM_ARGS_UNPARSED_ARGUMENT ${CPM_ARGS_UNPARSED_ARGUMENTS}) + string(APPEND PRETTY_OUT_VAR " ${CPM_ARGS_UNPARSED_ARGUMENT}") + endforeach() + string(APPEND PRETTY_OUT_VAR "\n") + endif() + + set(${OUT_VAR} + ${PRETTY_OUT_VAR} + PARENT_SCOPE + ) + +endfunction() diff --git a/thirdparty/common_post_project.cmake b/thirdparty/common_post_project.cmake new file mode 100644 index 000000000000..6bb8b9ca45ce --- /dev/null +++ b/thirdparty/common_post_project.cmake @@ -0,0 +1,28 @@ +# Shared stage setup that must run after project(); see common_pre_project.cmake for why the +# two halves are separate files. + +# all binaries will be located in ./build/Release/bin +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +# Inhibit all warning messages +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") + +IF(MR_EMSCRIPTEN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_BOOST_HEADERS=1") + IF(NOT MR_EMSCRIPTEN_SINGLETHREAD) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + ENDIF() +ENDIF() + +# CPM.cmake reissues cmake_minimum_required(3.14), so include it after project() to keep that +# out of the policy scope the stage files are configured under. +include(${MESHLIB_THIRDPARTY_DIR}/cmake/CPM.cmake) +include(${MESHLIB_THIRDPARTY_DIR}/package-lock.cmake) + +macro(meshlib_add_package name) + CPMAddPackage(NAME ${name} ${MESHLIB_PACKAGE_${name}} ${ARGN}) +endmacro() diff --git a/thirdparty/common_pre_project.cmake b/thirdparty/common_pre_project.cmake new file mode 100644 index 000000000000..9da06a72aa61 --- /dev/null +++ b/thirdparty/common_pre_project.cmake @@ -0,0 +1,26 @@ +# Shared stage setup that must run BEFORE project(), because it decides how the compiler is +# probed: the language standard, the Emscripten memory model and the vcpkg toolchain. +# +# CMake requires a literal, direct project() call in the top-level CMakeLists.txt -- calling it +# from an included file makes CMake inject an implicit project() at line 1, which probes the +# compiler before these flags are set. That is why this file and common_post_project.cmake are +# separate rather than one common.cmake. + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0) + set(CMAKE_POLICY_VERSION_MINIMUM 3.5) +endif() + +set(MESHLIB_THIRDPARTY_DIR "${CMAKE_CURRENT_LIST_DIR}") +set(MESHLIB_THIRDPARTY_INCLUDE_DIR "include") + +list(APPEND CMAKE_MODULE_PATH "${MESHLIB_THIRDPARTY_DIR}/../cmake/Modules") +include(ConfigureVcpkg) + +IF(MR_EMSCRIPTEN_WASM64) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MEMORY64=1") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s MEMORY64=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MEMORY64=1") +ENDIF() diff --git a/thirdparty/fetch/CMakeLists.txt b/thirdparty/fetch/CMakeLists.txt new file mode 100644 index 000000000000..557f4d867ef1 --- /dev/null +++ b/thirdparty/fetch/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.18 FATAL_ERROR) + +# Materializes dependency sources without building them, and writes their locations to +# MESHLIB_FETCH_OUTPUT as `SRC_=` lines -- a form both `sh` and `make` can read. +# scripts/mrbind/generate.mk uses this to parse MeshLib headers against raw dependency sources +# on platforms that never run scripts/build_thirdparty.sh. +# +# project(... NONE) skips compiler detection, so this configures with no toolchain file even +# when the caller is targeting Emscripten. +project(MeshLib_thirdparty_fetch NONE) + +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/CPM.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../package-lock.cmake) + +foreach(pkg IN LISTS MESHLIB_FETCH_PACKAGES) + CPMAddPackage(NAME ${pkg} ${MESHLIB_PACKAGE_${pkg}} DOWNLOAD_ONLY YES) + # Hyphenated package names are not legal shell or make variable names. + string(MAKE_C_IDENTIFIER "${pkg}" var) + string(APPEND sources "SRC_${var}=${${pkg}_SOURCE_DIR}\n") +endforeach() + +file(WRITE "${MESHLIB_FETCH_OUTPUT}" "${sources}") diff --git a/thirdparty/licenses/manifest.json b/thirdparty/licenses/manifest.json index 03fc932ce7d3..4a83d527999c 100644 --- a/thirdparty/licenses/manifest.json +++ b/thirdparty/licenses/manifest.json @@ -9,9 +9,10 @@ "and recomputes the version from the source below, FAILING if it drifts, so a human", "re-checks the license on every bump. To re-pin after verifying the texts are still", "correct: run the script with --update-versions. Inclusion authority:", - "doxygen/general_pages/ThirdpartyList.dox, reconciled against .gitmodules and", - "thirdparty/vcpkg/vcpkg.json.", - "source.type: submodule=gitlink SHA | vcpkg-overlay=port version+port-version |", + "doxygen/general_pages/ThirdpartyList.dox, reconciled against", + "thirdparty/package-lock.cmake, .gitmodules and thirdparty/vcpkg/vcpkg.json.", + "source.type: cpm=GIT_TAG or URL pinned in thirdparty/package-lock.cmake |", + "submodule=gitlink SHA | vcpkg-overlay=port version+port-version |", "vcpkg-registry=baseline version of each listed port (sound: vcpkg.json has no", "per-port overrides), so a registry bump only implicates the components whose own", "ports moved |", @@ -71,10 +72,10 @@ "license": "MPL-2.0", "upstream": "https://eigen.tuxfamily.org", "source": { - "type": "submodule", - "path": "thirdparty/eigen" + "type": "cpm", + "package": "eigen" }, - "version": "bc3b39870ecb690a623a3f49149a358b95c5781d" + "version": "5.0.1" }, { "id": "spdlog", @@ -84,8 +85,8 @@ "license": "MIT", "upstream": "https://github.com/gabime/spdlog", "source": { - "type": "submodule", - "path": "thirdparty/spdlog" + "type": "cpm", + "package": "spdlog" }, "version": "6fa36017cfd5731d617e1a934f0e5ea9c4445b13" }, @@ -97,8 +98,8 @@ "license": "MIT", "upstream": "https://github.com/fmtlib/fmt", "source": { - "type": "submodule", - "path": "thirdparty/fmt" + "type": "cpm", + "package": "fmt" }, "version": "47a66c5eccc0cce71ad81b4a681a2032d86ca951" }, @@ -128,8 +129,8 @@ "license": "MIT", "upstream": "https://github.com/open-source-parsers/jsoncpp", "source": { - "type": "submodule", - "path": "thirdparty/jsoncpp" + "type": "cpm", + "package": "jsoncpp" }, "version": "42e892d96e47b1f6e29844cc705e148ec4856448" }, @@ -141,10 +142,10 @@ "license": "BSD-3-Clause", "upstream": "https://libzip.org", "source": { - "type": "submodule", - "path": "thirdparty/libzip" + "type": "cpm", + "package": "libzip" }, - "version": "6f8a0cdd24a0dc6cce9dac4a7679da784ab124ea" + "version": "v1.11.4" }, { "id": "zlib-ng", @@ -154,8 +155,8 @@ "license": "Zlib", "upstream": "https://github.com/zlib-ng/zlib-ng", "source": { - "type": "submodule", - "path": "thirdparty/zlib-ng" + "type": "cpm", + "package": "zlib-ng" }, "version": "860e4cff7917d93f54f5d7f0bc1d0e8b1a3cb988" }, @@ -184,8 +185,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/uxlfoundation/oneTBB", "source": { - "type": "submodule", - "path": "thirdparty/onetbb" + "type": "cpm", + "package": "onetbb" }, "version": "12ceae12138af08845b3e8c369b24527346fe99e" }, @@ -197,10 +198,10 @@ "license": "Apache-2.0", "upstream": "https://github.com/greg7mdp/parallel-hashmap", "source": { - "type": "submodule", - "path": "thirdparty/parallel-hashmap" + "type": "cpm", + "package": "parallel-hashmap" }, - "version": "2ec799017610ef831f4dc29c21fb3cce7e4a19b9" + "version": "v2.0.0" }, { "id": "expected", @@ -210,8 +211,8 @@ "license": "CC0-1.0", "upstream": "https://github.com/TartanLlama/expected", "source": { - "type": "submodule", - "path": "thirdparty/expected" + "type": "cpm", + "package": "expected" }, "version": "d6e1fcc766b725f196d7f58097d72f8cfab4d56a" }, @@ -223,10 +224,10 @@ "license": "Apache-2.0", "upstream": "https://github.com/Mbed-TLS/mbedtls", "source": { - "type": "submodule", - "path": "thirdparty/mbedtls" + "type": "cpm", + "package": "mbedtls" }, - "version": "1ec69067fa1351427f904362c1221b31538c8b57" + "version": "v3.5.0" }, { "id": "libHaru", @@ -254,8 +255,8 @@ "license": "BSD-3-Clause AND IJG", "upstream": "https://libjpeg-turbo.org", "source": { - "type": "submodule", - "path": "thirdparty/libjpeg-turbo" + "type": "cpm", + "package": "libjpeg-turbo" }, "version": "7fa4b5b762c9a99b46b0b7838f5fd55071b92ea5" }, @@ -299,8 +300,8 @@ "license": "MIT", "upstream": "https://github.com/syoyo/tinygltf", "source": { - "type": "submodule", - "path": "thirdparty/tinygltf" + "type": "cpm", + "package": "tinygltf" }, "version": "98adbb3fb32850bb4918cc147a2d2428b011ad91" }, @@ -312,8 +313,8 @@ "license": "Zlib", "upstream": "https://sourceforge.net/projects/openctm/", "source": { - "type": "submodule", - "path": "thirdparty/OpenCTM-git" + "type": "cpm", + "package": "OpenCTM" }, "version": "2b444a4c70c432c1f4990fb32b0fcb11d0d81aad" }, @@ -325,8 +326,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/hobuinc/laz-perf", "source": { - "type": "submodule", - "path": "thirdparty/laz-perf" + "type": "cpm", + "package": "laz-perf" }, "version": "05ea01542e5c4417c05e7222f920e06276c79324" }, @@ -338,8 +339,8 @@ "license": "BSL-1.0", "upstream": "https://github.com/asmaloney/libE57Format", "source": { - "type": "submodule", - "path": "thirdparty/libE57Format" + "type": "cpm", + "package": "libE57Format" }, "version": "46eb0d02e00a6b0aeaee3e6655328b78c7e07b5b" }, @@ -351,8 +352,8 @@ "license": "Zlib", "upstream": "https://leethomason.github.io/tinyxml2/", "source": { - "type": "submodule", - "path": "thirdparty/tinyxml2" + "type": "cpm", + "package": "tinyxml2" }, "version": "321ea883b7190d4e85cae5512a12e5eaa8f8731f" }, @@ -366,8 +367,8 @@ "license": "MIT", "upstream": "https://github.com/nlohmann/json", "source": { - "type": "submodule", - "path": "thirdparty/nlohmann-json" + "type": "cpm", + "package": "nlohmann-json" }, "version": "3946872265598aed5a7aea68cad4d9d1f168bd4b" }, @@ -427,8 +428,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/AcademySoftwareFoundation/openvdb", "source": { - "type": "submodule", - "path": "thirdparty/openvdb/v10/openvdb" + "type": "cpm", + "package": "openvdb" }, "version": "87a508ca48a69f06d149be6cb0d8289fc1314f72" }, @@ -440,10 +441,10 @@ "license": "BSD-3-Clause", "upstream": "https://sourceforge.net/projects/gdcm/", "source": { - "type": "submodule", - "path": "thirdparty/GDCM" + "type": "cpm", + "package": "GDCM" }, - "version": "9c71b163416130ffdec26534444e9b85fcf0682a" + "version": "v3.2.6" }, { "id": "c-blosc", @@ -453,10 +454,10 @@ "license": "BSD-3-Clause", "upstream": "https://github.com/Blosc/c-blosc", "source": { - "type": "submodule", - "path": "thirdparty/c-blosc" + "type": "cpm", + "package": "c-blosc" }, - "version": "616f4b7343a8479f7e71dd3d7025bd92c9a6bbd0" + "version": "v1.21.6" }, { "id": "CUDA", @@ -478,8 +479,8 @@ "license": "MIT", "upstream": "https://github.com/Dav1dde/glad", "source": { - "type": "submodule", - "path": "thirdparty/glad" + "type": "cpm", + "package": "glad" }, "version": "e86f90457371c6233053bacf0d6f486a51ddcd67" }, @@ -522,10 +523,10 @@ "license": "MIT", "upstream": "https://github.com/libcpr/cpr", "source": { - "type": "submodule", - "path": "thirdparty/cpr" + "type": "cpm", + "package": "cpr" }, - "version": "f091b2c061b307ee89b164c39976fc9202a1c79d" + "version": "1.14.2" }, { "id": "libcurl", @@ -548,8 +549,8 @@ "license": "MIT", "upstream": "https://github.com/dacap/clip", "source": { - "type": "submodule", - "path": "thirdparty/clip" + "type": "cpm", + "package": "clip" }, "version": "7f2e86ab9690f7df88440002083edd257f87bc58" }, @@ -633,8 +634,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/MeshInspector/fastmcpp", "source": { - "type": "submodule", - "path": "thirdparty/fastmcpp" + "type": "cpm", + "package": "fastmcpp" }, "version": "9aa1a179f886f6d098f67693e18ee4778db924b7" }, @@ -647,8 +648,8 @@ "license": "MIT", "upstream": "https://github.com/yhirose/cpp-httplib", "source": { - "type": "submodule", - "path": "thirdparty/cpp-httplib" + "type": "cpm", + "package": "cpp-httplib" }, "version": "b045ee7f6b434a85fd011e96e28c6d4abfb18788" }, diff --git a/thirdparty/package-lock.cmake b/thirdparty/package-lock.cmake new file mode 100644 index 000000000000..c8355a0bc29d --- /dev/null +++ b/thirdparty/package-lock.cmake @@ -0,0 +1,150 @@ +# Version pins for every third-party library built by thirdparty/stage1 and thirdparty/stage2. +# +# Each entry is the CPMAddPackage argument list for one dependency, minus NAME, which the +# caller supplies: the stages via meshlib_add_package(), thirdparty/fetch by appending +# DOWNLOAD_ONLY YES. Deliberately not CPMDeclarePackage -- a declaration *replaces* the +# caller's arguments rather than extending them, which silently drops DOWNLOAD_ONLY. +# +# GIT_TAG is a release tag only where the pin sits exactly on one; everywhere else it is the +# commit hash, because the pin tracks a mid-branch commit or a MeshInspector fork. Bumping a +# hash pin onto a tag is a version change, not a cleanup. +# +# scripts/check_third_party_licenses.py parses this file, so keep one argument per line. + +set(MESHLIB_PACKAGE_boost-libs + VERSION 1.83.0 + URL https://github.com/boostorg/boost/releases/download/boost-1.83.0/boost-1.83.0.tar.xz + PATCHES + ${CMAKE_CURRENT_LIST_DIR}/patches/boost-locale-no-thread.patch + ${CMAKE_CURRENT_LIST_DIR}/patches/boost-locale-std-mutex.patch +) + +set(MESHLIB_PACKAGE_c-blosc + GIT_REPOSITORY https://github.com/Blosc/c-blosc.git + GIT_TAG v1.21.6 +) + +set(MESHLIB_PACKAGE_clip + GIT_REPOSITORY https://github.com/dacap/clip.git + GIT_TAG 7f2e86ab9690f7df88440002083edd257f87bc58 +) + +set(MESHLIB_PACKAGE_cpp-httplib + GIT_REPOSITORY https://github.com/yhirose/cpp-httplib + GIT_TAG b045ee7f6b434a85fd011e96e28c6d4abfb18788 +) + +set(MESHLIB_PACKAGE_cpr + GIT_REPOSITORY https://github.com/whoshuu/cpr.git + GIT_TAG 1.14.2 +) + +set(MESHLIB_PACKAGE_eigen + GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git + GIT_TAG 5.0.1 +) + +set(MESHLIB_PACKAGE_expected + GIT_REPOSITORY https://github.com/Developer-Ecosystem-Engineering/expected.git + GIT_TAG d6e1fcc766b725f196d7f58097d72f8cfab4d56a +) + +set(MESHLIB_PACKAGE_fastmcpp + GIT_REPOSITORY https://github.com/MeshInspector/fastmcpp + GIT_TAG 9aa1a179f886f6d098f67693e18ee4778db924b7 +) + +set(MESHLIB_PACKAGE_fmt + GIT_REPOSITORY https://github.com/fmtlib/fmt.git + GIT_TAG 47a66c5eccc0cce71ad81b4a681a2032d86ca951 +) + +set(MESHLIB_PACKAGE_GDCM + GIT_REPOSITORY https://github.com/malaterre/GDCM.git + GIT_TAG v3.2.6 +) + +set(MESHLIB_PACKAGE_glad + GIT_REPOSITORY https://github.com/Dav1dde/glad.git + GIT_TAG e86f90457371c6233053bacf0d6f486a51ddcd67 +) + +set(MESHLIB_PACKAGE_googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG b796f7d44681514f58a683a3a71ff17c94edb0c1 +) + +set(MESHLIB_PACKAGE_jsoncpp + GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp.git + GIT_TAG 42e892d96e47b1f6e29844cc705e148ec4856448 +) + +set(MESHLIB_PACKAGE_laz-perf + GIT_REPOSITORY https://github.com/MeshInspector/laz-perf + GIT_TAG 05ea01542e5c4417c05e7222f920e06276c79324 +) + +set(MESHLIB_PACKAGE_libE57Format + GIT_REPOSITORY https://github.com/MeshInspector/libE57Format + GIT_TAG 46eb0d02e00a6b0aeaee3e6655328b78c7e07b5b +) + +set(MESHLIB_PACKAGE_libjpeg-turbo + GIT_REPOSITORY https://github.com/libjpeg-turbo/libjpeg-turbo.git + GIT_TAG 7fa4b5b762c9a99b46b0b7838f5fd55071b92ea5 +) + +set(MESHLIB_PACKAGE_libzip + GIT_REPOSITORY https://github.com/nih-at/libzip.git + GIT_TAG v1.11.4 +) + +set(MESHLIB_PACKAGE_mbedtls + GIT_REPOSITORY https://github.com/Mbed-TLS/mbedtls + GIT_TAG v3.5.0 +) + +set(MESHLIB_PACKAGE_nlohmann-json + GIT_REPOSITORY https://github.com/nlohmann/json + GIT_TAG 3946872265598aed5a7aea68cad4d9d1f168bd4b +) + +set(MESHLIB_PACKAGE_onetbb + GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git + GIT_TAG 12ceae12138af08845b3e8c369b24527346fe99e +) + +set(MESHLIB_PACKAGE_OpenCTM + GIT_REPOSITORY https://github.com/MeshInspector/OpenCTM.git + GIT_TAG 2b444a4c70c432c1f4990fb32b0fcb11d0d81aad +) + +set(MESHLIB_PACKAGE_openvdb + GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/openvdb + GIT_TAG 87a508ca48a69f06d149be6cb0d8289fc1314f72 +) + +set(MESHLIB_PACKAGE_parallel-hashmap + GIT_REPOSITORY https://github.com/greg7mdp/parallel-hashmap.git + GIT_TAG v2.0.0 +) + +set(MESHLIB_PACKAGE_spdlog + GIT_REPOSITORY https://github.com/gabime/spdlog.git + GIT_TAG 6fa36017cfd5731d617e1a934f0e5ea9c4445b13 +) + +set(MESHLIB_PACKAGE_tinygltf + GIT_REPOSITORY https://github.com/syoyo/tinygltf + GIT_TAG 98adbb3fb32850bb4918cc147a2d2428b011ad91 +) + +set(MESHLIB_PACKAGE_tinyxml2 + GIT_REPOSITORY https://github.com/leethomason/tinyxml2.git + GIT_TAG 321ea883b7190d4e85cae5512a12e5eaa8f8731f +) + +set(MESHLIB_PACKAGE_zlib-ng + GIT_REPOSITORY https://github.com/zlib-ng/zlib-ng.git + GIT_TAG 860e4cff7917d93f54f5d7f0bc1d0e8b1a3cb988 +) diff --git a/thirdparty/patches/boost-locale-no-thread.patch b/thirdparty/patches/boost-locale-no-thread.patch new file mode 100644 index 000000000000..38c7621cd010 --- /dev/null +++ b/thirdparty/patches/boost-locale-no-thread.patch @@ -0,0 +1,11 @@ +diff -rup a/libs/locale/CMakeLists.txt b/libs/locale/CMakeLists.txt +--- a/libs/locale/CMakeLists.txt ++++ b/libs/locale/CMakeLists.txt +@@ -51,7 +51,6 @@ + PRIVATE + Boost::core + Boost::predef +- Boost::thread + ) + + target_compile_definitions(boost_locale diff --git a/scripts/thirdparty/boost-locale-std-mutex.patch b/thirdparty/patches/boost-locale-std-mutex.patch similarity index 83% rename from scripts/thirdparty/boost-locale-std-mutex.patch rename to thirdparty/patches/boost-locale-std-mutex.patch index 78b01abba5af..d8757b0deabd 100644 --- a/scripts/thirdparty/boost-locale-std-mutex.patch +++ b/thirdparty/patches/boost-locale-std-mutex.patch @@ -1,6 +1,6 @@ -diff -rup a/src/boost/locale/icu/date_time.cpp b/src/boost/locale/icu/date_time.cpp ---- a/src/boost/locale/icu/date_time.cpp -+++ b/src/boost/locale/icu/date_time.cpp +diff -rup a/libs/locale/src/boost/locale/icu/date_time.cpp b/libs/locale/src/boost/locale/icu/date_time.cpp +--- a/libs/locale/src/boost/locale/icu/date_time.cpp ++++ b/libs/locale/src/boost/locale/icu/date_time.cpp @@ -14,9 +14,9 @@ #include "boost/locale/icu/icu_util.hpp" #include "boost/locale/icu/time_zone.hpp" @@ -23,9 +23,9 @@ diff -rup a/src/boost/locale/icu/date_time.cpp b/src/boost/locale/icu/date_time. std::string encoding_; hold_ptr calendar_; }; -diff -rup a/src/boost/locale/shared/date_time.cpp b/src/boost/locale/shared/date_time.cpp ---- a/src/boost/locale/shared/date_time.cpp -+++ b/src/boost/locale/shared/date_time.cpp +diff -rup a/libs/locale/src/boost/locale/shared/date_time.cpp b/libs/locale/src/boost/locale/shared/date_time.cpp +--- a/libs/locale/src/boost/locale/shared/date_time.cpp ++++ b/libs/locale/src/boost/locale/shared/date_time.cpp @@ -7,9 +7,8 @@ #include #include @@ -64,9 +64,9 @@ diff -rup a/src/boost/locale/shared/date_time.cpp b/src/boost/locale/shared/date return boost::exchange(tz_id(), new_id); } } // namespace time_zone -diff -rup a/src/boost/locale/shared/generator.cpp b/src/boost/locale/shared/generator.cpp ---- a/src/boost/locale/shared/generator.cpp -+++ b/src/boost/locale/shared/generator.cpp +diff -rup a/libs/locale/src/boost/locale/shared/generator.cpp b/libs/locale/src/boost/locale/shared/generator.cpp +--- a/libs/locale/src/boost/locale/shared/generator.cpp ++++ b/libs/locale/src/boost/locale/shared/generator.cpp @@ -7,10 +7,9 @@ #include #include @@ -106,9 +106,9 @@ diff -rup a/src/boost/locale/shared/generator.cpp b/src/boost/locale/shared/gene const auto p = d->cached.find(id); if(p == d->cached.end()) d->cached[id] = result; -diff -rup a/src/boost/locale/shared/localization_backend.cpp b/src/boost/locale/shared/localization_backend.cpp ---- a/src/boost/locale/shared/localization_backend.cpp -+++ b/src/boost/locale/shared/localization_backend.cpp +diff -rup a/libs/locale/src/boost/locale/shared/localization_backend.cpp b/libs/locale/src/boost/locale/shared/localization_backend.cpp +--- a/libs/locale/src/boost/locale/shared/localization_backend.cpp ++++ b/libs/locale/src/boost/locale/shared/localization_backend.cpp @@ -5,10 +5,9 @@ // https://www.boost.org/LICENSE_1_0.txt @@ -148,9 +148,9 @@ diff -rup a/src/boost/locale/shared/localization_backend.cpp b/src/boost/locale/ return exchange(localization_backend_manager_global(), in); } -diff -rup a/src/boost/locale/win32/lcid.cpp b/src/boost/locale/win32/lcid.cpp ---- a/src/boost/locale/win32/lcid.cpp -+++ b/src/boost/locale/win32/lcid.cpp +diff -rup a/libs/locale/src/boost/locale/win32/lcid.cpp b/libs/locale/src/boost/locale/win32/lcid.cpp +--- a/libs/locale/src/boost/locale/win32/lcid.cpp ++++ b/libs/locale/src/boost/locale/win32/lcid.cpp @@ -10,9 +10,8 @@ #include "boost/locale/win32/lcid.hpp" diff --git a/thirdparty/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt similarity index 56% rename from thirdparty/CMakeLists.txt rename to thirdparty/stage1/CMakeLists.txt index ec83af0e41b0..7d8b33fc950a 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -1,62 +1,36 @@ # to force update thirdparty touch this line cmake_minimum_required(VERSION 3.18 FATAL_ERROR) -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0) - set(CMAKE_POLICY_VERSION_MINIMUM 3.5) -endif() +include(${CMAKE_CURRENT_LIST_DIR}/../common_pre_project.cmake) +project(MeshLib_thirdparty_stage1 CXX) +include(${CMAKE_CURRENT_LIST_DIR}/../common_post_project.cmake) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake/Modules") -include(ConfigureVcpkg) +# Libraries with no dependency on anything else built here. Everything that reaches for a +# sibling through find_package lives in ../stage2, which is configured after this one is +# installed. -IF(MR_EMSCRIPTEN_WASM64) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MEMORY64=1") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s MEMORY64=1") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MEMORY64=1") -ENDIF() - -project(MeshLib_thirdparty CXX) - -# all binaries will be located in ./build/Release/bin -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) - -set(MESHLIB_THIRDPARTY_DIR "${PROJECT_SOURCE_DIR}") -set(MESHLIB_THIRDPARTY_INCLUDE_DIR "include") +IF(EMSCRIPTEN) + set(BOOST_INCLUDE_LIBRARIES locale) + set(BOOST_LOCALE_ENABLE_ICONV OFF) + meshlib_add_package(boost-libs) -# Inhibit all warning messages -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") + set(WITH_JAVA OFF) + set(WITH_JPEG8 ON) + set(WITH_SIMD OFF) + set(BUILD_TESTING OFF) + set(ENABLE_STATIC OFF) + meshlib_add_package(libjpeg-turbo) -IF(MR_EMSCRIPTEN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_BOOST_HEADERS=1") - IF(NOT MR_EMSCRIPTEN_SINGLETHREAD) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") - ENDIF() -ENDIF() + set(ENABLE_PROGRAMS OFF) + set(ENABLE_TESTING OFF) + meshlib_add_package(mbedtls) -IF(EMSCRIPTEN) set(INSTALL_GTEST ON) add_compile_definitions(GTEST_HAS_CXXABI_H_=0) - add_subdirectory(./googletest ./googletest) + meshlib_add_package(googletest) ENDIF() IF(NOT APPLE AND NOT MR_EMSCRIPTEN) - find_package(OpenVDB 10 COMPONENTS openvdb) - IF(NOT OpenVDB_FOUND) - set(OPENVDB_ENABLE_UNINSTALL OFF) - set(OPENVDB_ENABLE_INSTALL OFF) - set(OPENVDB_CORE_SHARED "ON") - set(OPENVDB_CORE_STATIC "OFF") - set(OPENVDB_BUILD_BINARIES OFF) - set(OPENVDB_BUILD_VDB_PRINT OFF) - set(USE_EXPLICIT_INSTANTIATION OFF) - add_subdirectory(./openvdb/v10/openvdb) - ENDIF() - find_package(cpr) IF(NOT cpr_FOUND) set(CPR_ENABLE_UNINSTALL "OFF") @@ -65,14 +39,14 @@ IF(NOT APPLE AND NOT MR_EMSCRIPTEN) set(CPR_BUILD_TESTS "OFF") set(CPR_BUILD_TESTS_SSL "OFF") set(CPR_FORCE_USE_SYSTEM_CURL ON) - add_subdirectory(./cpr) + meshlib_add_package(cpr) ENDIF() find_package(nlohmann_json) if(NOT TARGET nlohmann_json::nlohmann_json) set(JSON_BuildTests OFF) set(JSON_Install ON) - add_subdirectory(./nlohmann-json) + meshlib_add_package(nlohmann-json) endif() find_package(httplib) @@ -82,7 +56,7 @@ IF(NOT APPLE AND NOT MR_EMSCRIPTEN) set(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF) set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF) set(HTTPLIB_USE_ZSTD_IF_AVAILABLE OFF) - add_subdirectory(./cpp-httplib) + meshlib_add_package(cpp-httplib) endif() find_package(PkgConfig) @@ -90,11 +64,11 @@ IF(NOT APPLE AND NOT MR_EMSCRIPTEN) pkg_check_modules(tinyxml2 QUIET tinyxml2) ENDIF() IF(NOT tinyxml2_FOUND OR tinyxml2_VERSION VERSION_LESS 10) - add_subdirectory(./tinyxml2) + meshlib_add_package(tinyxml2) ENDIF() ENDIF() -add_subdirectory(./OpenCTM-git ./OpenCTM) +meshlib_add_package(OpenCTM) IF(NOT APPLE) set(ZLIB_COMPAT OFF CACHE BOOL "") @@ -107,75 +81,72 @@ IF(NOT APPLE) # libz-ng.a rules under Emscripten. Restore to undefined (not empty) # afterwards -- jsoncpp downstream breaks on empty BUILD_SHARED_LIBS. set(BUILD_SHARED_LIBS OFF) - add_subdirectory(./zlib-ng) + meshlib_add_package(zlib-ng) unset(BUILD_SHARED_LIBS) ELSE() - add_subdirectory(./zlib-ng) + meshlib_add_package(zlib-ng) ENDIF() option(PHMAP_INSTALL "" ON) - add_subdirectory(./parallel-hashmap) + meshlib_add_package(parallel-hashmap) ENDIF() IF(EMSCRIPTEN) - add_subdirectory(./expected ./expected) + meshlib_add_package(expected) set(GDCM_BUILD_APPLICATIONS OFF) set(GDCM_BUILD_SHARED_LIBS OFF) set(GDCM_BUILD_TESTING OFF) set(GDCM_BUILD_DOCBOOK_MANPAGES OFF) - add_subdirectory(./GDCM) - - set(BUILD_TOOLS OFF CACHE BOOL "") - set(BUILD_REGRESS OFF CACHE BOOL "") - set(BUILD_EXAMPLES OFF CACHE BOOL "") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_ZLIB=1") - set(LIBZIP_DO_INSTALL ON) - add_subdirectory(./libzip) + meshlib_add_package(GDCM) set(CMAKE_CXX_FLAGS_BACKUP "${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_DISABLE_EXCEPTION_CATCHING=1") set(JSONCPP_WITH_TESTS OFF) set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF) set(BUILD_STATIC_LIBS OFF) - add_subdirectory(./jsoncpp) + meshlib_add_package(jsoncpp) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BACKUP}") - add_subdirectory(./fmt) - #install(DIRECTORY fmt/include/fmt DESTINATION ${MESHLIB_THIRDPARTY_INCLUDE_DIR}) + meshlib_add_package(fmt) set(SPDLOG_INSTALL ON) set(SPDLOG_FMT_EXTERNAL ON) - add_subdirectory(./spdlog) + meshlib_add_package(spdlog) option(TBB_TEST "Enable testing" OFF) set(CMAKE_SYSTEM_PROCESSOR_BACKUP "${CMAKE_SYSTEM_PROCESSOR}") set(CMAKE_SYSTEM_PROCESSOR "unknown") - add_subdirectory(./onetbb) + meshlib_add_package(onetbb) set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR_BACKUP}") - install(DIRECTORY onetbb/include/tbb DESTINATION ${MESHLIB_THIRDPARTY_INCLUDE_DIR}) + install(DIRECTORY ${onetbb_SOURCE_DIR}/include/tbb DESTINATION ${MESHLIB_THIRDPARTY_INCLUDE_DIR}) - add_subdirectory(./tinyxml2) + meshlib_add_package(tinyxml2) set(BUILD_TESTS OFF CACHE BOOL "") set(BUILD_FUZZERS OFF CACHE BOOL "") set(BUILD_BENCHMARKS OFF CACHE BOOL "") set(BUILD_STATIC OFF CACHE BOOL "") set(BLOSC_INSTALL ON) - add_subdirectory(./c-blosc) + meshlib_add_package(c-blosc) + + set(EIGEN_BUILD_DOC OFF) + set(BUILD_TESTING OFF) + meshlib_add_package(eigen) ELSE() # not MR_EMSCRIPTEN set(BUILD_SHARED_LIBS ON) - set(E57_GIT_SUBMODULE_UPDATE OFF) - set(E57_XML_PARSER TinyXML2 CACHE STRING "") - add_subdirectory(./libE57Format) + set(CLIP_EXAMPLES OFF) + set(CLIP_TESTS OFF) + set(CLIP_X11_WITH_PNG OFF) + meshlib_add_package(clip) ENDIF() find_package(glad) IF(NOT glad_FOUND) set(GLAD_INSTALL ON CACHE BOOL "") set(GLAD_REPRODUCIBLE ON CACHE BOOL "") - add_subdirectory(./glad) + meshlib_add_package(glad) ENDIF() IF(NOT MR_EMSCRIPTEN) @@ -188,12 +159,12 @@ IF(NOT MR_EMSCRIPTEN) # Note that regardless of this setting, the python-version-specific shims always need to be built in our main `CMakeLists.txt`, # to see our configuration CMake variables. option(PYBIND11_NONLIMITEDAPI_BUILD_STUBS "" OFF) - add_subdirectory(./mrbind-pybind11) + add_subdirectory(${MESHLIB_THIRDPARTY_DIR}/mrbind-pybind11 ./mrbind-pybind11) ENDIF() set(TINYGLTF_INSTALL ON) -add_subdirectory(./tinygltf) +meshlib_add_package(tinygltf) set(WITH_TESTS OFF CACHE BOOL "") set(WITH_EMBIND OFF CACHE BOOL "") -add_subdirectory(./laz-perf) +meshlib_add_package(laz-perf) diff --git a/thirdparty/stage2/CMakeLists.txt b/thirdparty/stage2/CMakeLists.txt new file mode 100644 index 000000000000..99db54b39321 --- /dev/null +++ b/thirdparty/stage2/CMakeLists.txt @@ -0,0 +1,64 @@ +# to force update thirdparty touch this line +cmake_minimum_required(VERSION 3.18 FATAL_ERROR) + +include(${CMAKE_CURRENT_LIST_DIR}/../common_pre_project.cmake) +project(MeshLib_thirdparty_stage2 CXX) +include(${CMAKE_CURRENT_LIST_DIR}/../common_post_project.cmake) + +# Libraries that resolve a dependency built by ../stage1 through find_package, so they can only +# be configured once stage1 has been installed into CMAKE_INSTALL_PREFIX: +# libzip -> MbedTLS, libE57Format -> tinyxml2, openvdb -> TBB + Blosc + Boost, fastmcpp -> +# httplib + nlohmann_json. + +IF(NOT APPLE AND NOT MR_EMSCRIPTEN) + find_package(OpenVDB 10 COMPONENTS openvdb) + IF(NOT OpenVDB_FOUND) + set(OPENVDB_ENABLE_UNINSTALL OFF) + set(OPENVDB_ENABLE_INSTALL OFF) + set(OPENVDB_CORE_SHARED "ON") + set(OPENVDB_CORE_STATIC "OFF") + set(OPENVDB_BUILD_BINARIES OFF) + set(OPENVDB_BUILD_VDB_PRINT OFF) + set(USE_EXPLICIT_INSTANTIATION OFF) + meshlib_add_package(openvdb) + ENDIF() +ENDIF() + +IF(EMSCRIPTEN) + set(BUILD_TOOLS OFF CACHE BOOL "") + set(BUILD_REGRESS OFF CACHE BOOL "") + set(BUILD_EXAMPLES OFF CACHE BOOL "") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_ZLIB=1") + set(LIBZIP_DO_INSTALL ON) + meshlib_add_package(libzip) + + set(E57_BUILD_TEST OFF) + set(E57_XML_PARSER TinyXML2) + meshlib_add_package(libE57Format) + + set(OPENVDB_ENABLE_UNINSTALL OFF) + set(OPENVDB_ENABLE_INSTALL OFF) + set(OPENVDB_CORE_SHARED "ON") + set(OPENVDB_CORE_STATIC "OFF") + set(OPENVDB_BUILD_BINARIES OFF) + set(OPENVDB_BUILD_VDB_PRINT OFF) + set(OPENVDB_USE_DELAYED_LOADING OFF) + set(USE_EXPLICIT_INSTANTIATION OFF) + set(Tbb_VERSION 2021.12) + set(CMAKE_CXX_FLAGS_BACKUP "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-template-arg-list-after-template-kw") + meshlib_add_package(openvdb) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BACKUP}") +ELSE() # not MR_EMSCRIPTEN + set(BUILD_SHARED_LIBS ON) + + set(E57_GIT_SUBMODULE_UPDATE OFF) + set(E57_XML_PARSER TinyXML2 CACHE STRING "") + meshlib_add_package(libE57Format) + + set(FASTMCPP_BUILD_TESTS OFF) + set(FASTMCPP_BUILD_EXAMPLES OFF) + set(FASTMCPP_FETCH_CURL OFF) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + meshlib_add_package(fastmcpp) +ENDIF() From f00cfde376fe8fdea3368d7bb5d1e01934ef7f52 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sat, 15 Aug 2026 22:52:52 +0200 Subject: [PATCH 02/19] WIP: Don't remove submodules temporarily --- .gitmodules | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/.gitmodules b/.gitmodules index 65154c99f6da..1e3587ecdcfa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,90 @@ +[submodule "thirdparty/cpr"] + path = thirdparty/cpr + url = https://github.com/whoshuu/cpr.git +[submodule "thirdparty/parallel-hashmap"] + path = thirdparty/parallel-hashmap + url = https://github.com/greg7mdp/parallel-hashmap.git +[submodule "thirdparty/eigen"] + path = thirdparty/eigen + url = https://gitlab.com/libeigen/eigen.git +[submodule "thirdparty/expected"] + path = thirdparty/expected + url = https://github.com/Developer-Ecosystem-Engineering/expected.git +[submodule "thirdparty/googletest"] + path = thirdparty/googletest + url = https://github.com/google/googletest.git +[submodule "thirdparty/spdlog"] + path = thirdparty/spdlog + url = https://github.com/gabime/spdlog.git +[submodule "thirdparty/libzip"] + path = thirdparty/libzip + url = https://github.com/nih-at/libzip.git +[submodule "thirdparty/jsoncpp"] + path = thirdparty/jsoncpp + url = https://github.com/open-source-parsers/jsoncpp.git [submodule "thirdparty/imgui"] path = thirdparty/imgui url = https://github.com/ocornut/imgui.git +[submodule "thirdparty/glad"] + path = thirdparty/glad + url = https://github.com/Dav1dde/glad.git +[submodule "thirdparty/clip"] + path = thirdparty/clip + url = https://github.com/dacap/clip.git +[submodule "thirdparty/openvdb/v10/openvdb"] + path = thirdparty/openvdb/v10/openvdb + url = https://github.com/AcademySoftwareFoundation/openvdb +[submodule "thirdparty/tinygltf"] + path = thirdparty/tinygltf + url = https://github.com/syoyo/tinygltf +[submodule "thirdparty/onetbb"] + path = thirdparty/onetbb + url = https://github.com/oneapi-src/oneTBB.git +[submodule "thirdparty/libE57Format"] + path = thirdparty/libE57Format + url = https://github.com/MeshInspector/libE57Format +[submodule "thirdparty/laz-perf"] + path = thirdparty/laz-perf + url = https://github.com/MeshInspector/laz-perf +[submodule "thirdparty/mbedtls"] + path = thirdparty/mbedtls + url = https://github.com/Mbed-TLS/mbedtls +[submodule "thirdparty/GDCM"] + path = thirdparty/GDCM + url = https://github.com/malaterre/GDCM.git +[submodule "thirdparty/tinyxml2"] + path = thirdparty/tinyxml2 + url = https://github.com/leethomason/tinyxml2.git +[submodule "thirdparty/libjpeg-turbo"] + path = thirdparty/libjpeg-turbo + url = https://github.com/libjpeg-turbo/libjpeg-turbo.git +[submodule "thirdparty/c-blosc"] + path = thirdparty/c-blosc + url = https://github.com/Blosc/c-blosc.git +[submodule "thirdparty/fmt"] + path = thirdparty/fmt + url = https://github.com/fmtlib/fmt.git [submodule "thirdparty/mrbind-pybind11"] path = thirdparty/mrbind-pybind11 url = https://github.com/MeshInspector/mrbind-pybind11 [submodule "thirdparty/mrbind"] path = thirdparty/mrbind url = https://github.com/MeshInspector/mrbind +[submodule "thirdparty/OpenCTM-git"] + path = thirdparty/OpenCTM-git + url = https://github.com/MeshInspector/OpenCTM.git +[submodule "thirdparty/fastmcpp"] + path = thirdparty/fastmcpp + url = https://github.com/MeshInspector/fastmcpp +[submodule "thirdparty/nlohmann-json"] + path = thirdparty/nlohmann-json + url = https://github.com/nlohmann/json +[submodule "thirdparty/cpp-httplib"] + path = thirdparty/cpp-httplib + url = https://github.com/yhirose/cpp-httplib +[submodule "thirdparty/zlib-ng"] + path = thirdparty/zlib-ng + url = https://github.com/zlib-ng/zlib-ng.git [submodule "test_data"] path = test_data url = https://github.com/MeshInspector/MeshLibTestData.git From 92aa757afefcfc35e14d512a81dedd08689dd157 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sat, 15 Aug 2026 23:03:08 +0200 Subject: [PATCH 03/19] WIP: Fix build --- thirdparty/package-lock.cmake | 2 ++ .../libjpeg-turbo-allow-add-subdirectory.patch | 14 ++++++++++++++ thirdparty/stage1/CMakeLists.txt | 3 +++ 3 files changed, 19 insertions(+) create mode 100644 thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch diff --git a/thirdparty/package-lock.cmake b/thirdparty/package-lock.cmake index c8355a0bc29d..4e584dbbb9d8 100644 --- a/thirdparty/package-lock.cmake +++ b/thirdparty/package-lock.cmake @@ -92,6 +92,8 @@ set(MESHLIB_PACKAGE_libE57Format set(MESHLIB_PACKAGE_libjpeg-turbo GIT_REPOSITORY https://github.com/libjpeg-turbo/libjpeg-turbo.git GIT_TAG 7fa4b5b762c9a99b46b0b7838f5fd55071b92ea5 + PATCHES + ${CMAKE_CURRENT_LIST_DIR}/patches/libjpeg-turbo-allow-add-subdirectory.patch ) set(MESHLIB_PACKAGE_libzip diff --git a/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch b/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch new file mode 100644 index 000000000000..15a12ecfebeb --- /dev/null +++ b/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch @@ -0,0 +1,14 @@ +diff -rup a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -50,10 +50,6 @@ + # ExternalProject_Add() or make downstream modifications to the libjpeg-turbo + # build system to suit their specific needs. Please do not file bug reports, + # feature requests, or pull requests regarding this. +-if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) +- message(FATAL_ERROR "The libjpeg-turbo build system cannot be integrated into another build system using add_subdirectory(). Use ExternalProject_Add() instead.") +-endif() +- + # CMake 3.14 and later sets CMAKE_MACOSX_BUNDLE to TRUE by default when + # CMAKE_SYSTEM_NAME is iOS, tvOS, or watchOS, which breaks the libjpeg-turbo + # build. (Specifically, when CMAKE_MACOSX_BUNDLE is TRUE, executables for diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt index 7d8b33fc950a..e49c7349a7a7 100644 --- a/thirdparty/stage1/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -23,6 +23,7 @@ IF(EMSCRIPTEN) set(ENABLE_PROGRAMS OFF) set(ENABLE_TESTING OFF) + set(DISABLE_PACKAGE_CONFIG_AND_INSTALL OFF) meshlib_add_package(mbedtls) set(INSTALL_GTEST ON) @@ -132,6 +133,8 @@ IF(EMSCRIPTEN) set(EIGEN_BUILD_DOC OFF) set(BUILD_TESTING OFF) + set(EIGEN_BUILD_CMAKE_PACKAGE ON) + set(EIGEN_BUILD_PKGCONFIG ON) meshlib_add_package(eigen) ELSE() # not MR_EMSCRIPTEN set(BUILD_SHARED_LIBS ON) From ed0f48f25d1f2d0f74c9d1b5ec9a5d50d69da345 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sat, 15 Aug 2026 23:13:12 +0200 Subject: [PATCH 04/19] WIP: Fix build --- thirdparty/licenses/manifest.json | 2 +- thirdparty/package-lock.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/thirdparty/licenses/manifest.json b/thirdparty/licenses/manifest.json index 4a83d527999c..e083a6c83095 100644 --- a/thirdparty/licenses/manifest.json +++ b/thirdparty/licenses/manifest.json @@ -303,7 +303,7 @@ "type": "cpm", "package": "tinygltf" }, - "version": "98adbb3fb32850bb4918cc147a2d2428b011ad91" + "version": "v2.8.2" }, { "id": "OpenCTM", diff --git a/thirdparty/package-lock.cmake b/thirdparty/package-lock.cmake index 4e584dbbb9d8..7f986218720c 100644 --- a/thirdparty/package-lock.cmake +++ b/thirdparty/package-lock.cmake @@ -138,7 +138,7 @@ set(MESHLIB_PACKAGE_spdlog set(MESHLIB_PACKAGE_tinygltf GIT_REPOSITORY https://github.com/syoyo/tinygltf - GIT_TAG 98adbb3fb32850bb4918cc147a2d2428b011ad91 + GIT_TAG v2.8.2 ) set(MESHLIB_PACKAGE_tinyxml2 From e88547947433632ddb4339400ee458c49eddc222 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sun, 16 Aug 2026 09:04:49 +0200 Subject: [PATCH 05/19] WIP: Fix build --- thirdparty/stage1/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt index e49c7349a7a7..5d465b7560e5 100644 --- a/thirdparty/stage1/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -19,7 +19,13 @@ IF(EMSCRIPTEN) set(WITH_SIMD OFF) set(BUILD_TESTING OFF) set(ENABLE_STATIC OFF) + set(CMAKE_INSTALL_DOCDIR_BACKUP "${CMAKE_INSTALL_DOCDIR}") + set(CMAKE_INSTALL_MANDIR_BACKUP "${CMAKE_INSTALL_MANDIR}") + set(CMAKE_INSTALL_DOCDIR "share/doc/libjpeg-turbo") + set(CMAKE_INSTALL_MANDIR "share/man") meshlib_add_package(libjpeg-turbo) + set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DOCDIR_BACKUP}") + set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_MANDIR_BACKUP}") set(ENABLE_PROGRAMS OFF) set(ENABLE_TESTING OFF) From b079871762c5922131266bc78f203cd99b6578b0 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sun, 16 Aug 2026 09:09:50 +0200 Subject: [PATCH 06/19] WIP: Fix build --- .github/actions/install-macos-thirdparty/action.yml | 12 ++++++++---- thirdparty/package-lock.cmake | 4 ++++ .../libjpeg-turbo-allow-add-subdirectory.patch | 9 +++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/actions/install-macos-thirdparty/action.yml b/.github/actions/install-macos-thirdparty/action.yml index 3be401fafa70..8750f360b863 100644 --- a/.github/actions/install-macos-thirdparty/action.yml +++ b/.github/actions/install-macos-thirdparty/action.yml @@ -111,9 +111,11 @@ runs: scripts/build_thirdparty.sh \ scripts/install_brew_requirements.sh \ thirdparty/package-lock.cmake \ - thirdparty/common.cmake \ + thirdparty/common_pre_project.cmake \ + thirdparty/common_post_project.cmake \ thirdparty/stage1/CMakeLists.txt \ thirdparty/stage2/CMakeLists.txt \ + thirdparty/patches/* \ requirements/macos.txt } | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT" @@ -130,14 +132,16 @@ runs: include key: ${{ inputs.cache-prefix }}-${{ inputs.cache-instance }}-${{ inputs.cache-compiler }}-${{ steps.cache-keys.outputs.thirdparty-hash }} - # CPM downloads dependency sources here when the build runs. Keyed on the pins alone -- - # sources are independent of runner and compiler, so every instance shares one entry. + # CPM downloads dependency sources here when the build runs. Keyed on the pins and the + # patches -- sources are independent of runner and compiler, so every instance shares one + # entry. The patches matter because CPM's own source-cache key covers a patch file's path + # but not its contents, so editing one in place would otherwise reuse the old patched tree. - name: Cache thirdparty sources if: ${{ steps.thirdparty-cache.outputs.cache-hit != 'true' }} uses: actions/cache@v5 with: path: thirdparty_sources - key: ${{ inputs.cache-prefix }}-sources-${{ hashFiles('thirdparty/package-lock.cmake') }} + key: ${{ inputs.cache-prefix }}-sources-${{ hashFiles('thirdparty/package-lock.cmake', 'thirdparty/patches/*') }} # Always run: cached thirdparty .dylibs link against brew libs at runtime, # so brew packages must be installed on hosted runners even on cache hit. diff --git a/thirdparty/package-lock.cmake b/thirdparty/package-lock.cmake index 7f986218720c..7f152665e09d 100644 --- a/thirdparty/package-lock.cmake +++ b/thirdparty/package-lock.cmake @@ -9,6 +9,10 @@ # commit hash, because the pin tracks a mid-branch commit or a MeshInspector fork. Bumping a # hash pin onto a tag is a version change, not a cleanup. # +# Editing a file under patches/ in place does not invalidate CPM's source cache -- its key +# covers a patch's path, not its contents. Clear CPM_SOURCE_CACHE (thirdparty_sources/ by +# default) after doing so, or the previously patched tree is reused. +# # scripts/check_third_party_licenses.py parses this file, so keep one argument per line. set(MESHLIB_PACKAGE_boost-libs diff --git a/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch b/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch index 15a12ecfebeb..aaabff57592b 100644 --- a/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch +++ b/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch @@ -12,3 +12,12 @@ diff -rup a/CMakeLists.txt b/CMakeLists.txt # CMake 3.14 and later sets CMAKE_MACOSX_BUNDLE to TRUE by default when # CMAKE_SYSTEM_NAME is iOS, tvOS, or watchOS, which breaks the libjpeg-turbo # build. (Specifically, when CMAKE_MACOSX_BUNDLE is TRUE, executables for +@@ -1820,8 +1816,3 @@ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT include) + + include(cmakescripts/BuildPackages.cmake) +- +-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmakescripts/cmake_uninstall.cmake.in" +- "cmake_uninstall.cmake" IMMEDIATE @ONLY) +- +-add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P cmake_uninstall.cmake) From 68dc793b7f58abfa157bfbe643f016094a3e13ba Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sun, 16 Aug 2026 09:13:07 +0200 Subject: [PATCH 07/19] WIP: Fix build --- thirdparty/stage1/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt index 5d465b7560e5..b390cf6ba75d 100644 --- a/thirdparty/stage1/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -71,6 +71,7 @@ IF(NOT APPLE AND NOT MR_EMSCRIPTEN) pkg_check_modules(tinyxml2 QUIET tinyxml2) ENDIF() IF(NOT tinyxml2_FOUND OR tinyxml2_VERSION VERSION_LESS 10) + set(tinyxml2_SHARED_LIBS ON) meshlib_add_package(tinyxml2) ENDIF() ENDIF() From ff5a11f06af8002a3b5b64e47ab3b5190c20f25b Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sun, 16 Aug 2026 09:31:43 +0200 Subject: [PATCH 08/19] WIP: Fix build --- thirdparty/package-lock.cmake | 1 + .../patches/boost-honor-skip-install-rules.patch | 15 +++++++++++++++ thirdparty/stage1/CMakeLists.txt | 1 + 3 files changed, 17 insertions(+) create mode 100644 thirdparty/patches/boost-honor-skip-install-rules.patch diff --git a/thirdparty/package-lock.cmake b/thirdparty/package-lock.cmake index 7f152665e09d..285328213189 100644 --- a/thirdparty/package-lock.cmake +++ b/thirdparty/package-lock.cmake @@ -21,6 +21,7 @@ set(MESHLIB_PACKAGE_boost-libs PATCHES ${CMAKE_CURRENT_LIST_DIR}/patches/boost-locale-no-thread.patch ${CMAKE_CURRENT_LIST_DIR}/patches/boost-locale-std-mutex.patch + ${CMAKE_CURRENT_LIST_DIR}/patches/boost-honor-skip-install-rules.patch ) set(MESHLIB_PACKAGE_c-blosc diff --git a/thirdparty/patches/boost-honor-skip-install-rules.patch b/thirdparty/patches/boost-honor-skip-install-rules.patch new file mode 100644 index 000000000000..a367e01d80ff --- /dev/null +++ b/thirdparty/patches/boost-honor-skip-install-rules.patch @@ -0,0 +1,15 @@ +diff -rup a/tools/cmake/include/BoostRoot.cmake b/tools/cmake/include/BoostRoot.cmake +--- a/tools/cmake/include/BoostRoot.cmake ++++ b/tools/cmake/include/BoostRoot.cmake +@@ -107,8 +107,11 @@ + set(BOOST_ENABLE_PYTHON OFF) + endif() + ++ if(NOT DEFINED BOOST_SKIP_INSTALL_RULES) ++ set(BOOST_SKIP_INSTALL_RULES ON) ++ endif() ++ + set(BUILD_TESTING OFF) +- set(BOOST_SKIP_INSTALL_RULES ON) + + endif() diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt index b390cf6ba75d..734d7a57044a 100644 --- a/thirdparty/stage1/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -12,6 +12,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/../common_post_project.cmake) IF(EMSCRIPTEN) set(BOOST_INCLUDE_LIBRARIES locale) set(BOOST_LOCALE_ENABLE_ICONV OFF) + set(BOOST_SKIP_INSTALL_RULES OFF) meshlib_add_package(boost-libs) set(WITH_JAVA OFF) From 940a3a5c85128fe3bb510d1011a57deb91d3ddb6 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sun, 16 Aug 2026 13:44:18 +0200 Subject: [PATCH 09/19] WIP: Fix build --- thirdparty/package-lock.cmake | 2 ++ .../patches/clip-config-use-project-name.patch | 10 ++++++++++ thirdparty/stage1/CMakeLists.txt | 12 ++++++------ 3 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 thirdparty/patches/clip-config-use-project-name.patch diff --git a/thirdparty/package-lock.cmake b/thirdparty/package-lock.cmake index 285328213189..c9009a2daf27 100644 --- a/thirdparty/package-lock.cmake +++ b/thirdparty/package-lock.cmake @@ -32,6 +32,8 @@ set(MESHLIB_PACKAGE_c-blosc set(MESHLIB_PACKAGE_clip GIT_REPOSITORY https://github.com/dacap/clip.git GIT_TAG 7f2e86ab9690f7df88440002083edd257f87bc58 + PATCHES + ${CMAKE_CURRENT_LIST_DIR}/patches/clip-config-use-project-name.patch ) set(MESHLIB_PACKAGE_cpp-httplib diff --git a/thirdparty/patches/clip-config-use-project-name.patch b/thirdparty/patches/clip-config-use-project-name.patch new file mode 100644 index 000000000000..babe2b2dd134 --- /dev/null +++ b/thirdparty/patches/clip-config-use-project-name.patch @@ -0,0 +1,10 @@ +diff -rup a/clip-config.cmake.in b/clip-config.cmake.in +--- a/clip-config.cmake.in ++++ b/clip-config.cmake.in +@@ -1,4 +1,4 @@ + @PACKAGE_INIT@ + +-include("${CMAKE_CURRENT_LIST_DIR}/@CMAKE_PROJECT_NAME@-targets.cmake") +-check_required_components("@CMAKE_PROJECT_NAME@") ++include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake") ++check_required_components("@PROJECT_NAME@") diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt index 734d7a57044a..066445da26bf 100644 --- a/thirdparty/stage1/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -28,9 +28,9 @@ IF(EMSCRIPTEN) set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DOCDIR_BACKUP}") set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_MANDIR_BACKUP}") - set(ENABLE_PROGRAMS OFF) - set(ENABLE_TESTING OFF) - set(DISABLE_PACKAGE_CONFIG_AND_INSTALL OFF) + set(ENABLE_PROGRAMS OFF CACHE BOOL "") + set(ENABLE_TESTING OFF CACHE BOOL "") + set(DISABLE_PACKAGE_CONFIG_AND_INSTALL OFF CACHE BOOL "") meshlib_add_package(mbedtls) set(INSTALL_GTEST ON) @@ -147,9 +147,9 @@ IF(EMSCRIPTEN) ELSE() # not MR_EMSCRIPTEN set(BUILD_SHARED_LIBS ON) - set(CLIP_EXAMPLES OFF) - set(CLIP_TESTS OFF) - set(CLIP_X11_WITH_PNG OFF) + set(CLIP_EXAMPLES OFF CACHE BOOL "") + set(CLIP_TESTS OFF CACHE BOOL "") + set(CLIP_X11_WITH_PNG OFF CACHE BOOL "") meshlib_add_package(clip) ENDIF() From 7c026f6d55d70a04374165bc47e3f0ddadefca3c Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Sun, 16 Aug 2026 16:35:27 +0200 Subject: [PATCH 10/19] WIP: Fix build --- thirdparty/stage1/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/stage1/CMakeLists.txt index 066445da26bf..33377834046a 100644 --- a/thirdparty/stage1/CMakeLists.txt +++ b/thirdparty/stage1/CMakeLists.txt @@ -39,6 +39,8 @@ IF(EMSCRIPTEN) ENDIF() IF(NOT APPLE AND NOT MR_EMSCRIPTEN) + set(BUILD_SHARED_LIBS ON) + find_package(cpr) IF(NOT cpr_FOUND) set(CPR_ENABLE_UNINSTALL "OFF") @@ -72,7 +74,6 @@ IF(NOT APPLE AND NOT MR_EMSCRIPTEN) pkg_check_modules(tinyxml2 QUIET tinyxml2) ENDIF() IF(NOT tinyxml2_FOUND OR tinyxml2_VERSION VERSION_LESS 10) - set(tinyxml2_SHARED_LIBS ON) meshlib_add_package(tinyxml2) ENDIF() ENDIF() From cb5153a81bd757c04f10a06febcd802f0e64f673 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Mon, 17 Aug 2026 09:44:04 +0200 Subject: [PATCH 11/19] WIP: Fix build --- .github/actions/install-macos-thirdparty/action.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/actions/install-macos-thirdparty/action.yml b/.github/actions/install-macos-thirdparty/action.yml index 8750f360b863..2ba01651c474 100644 --- a/.github/actions/install-macos-thirdparty/action.yml +++ b/.github/actions/install-macos-thirdparty/action.yml @@ -136,12 +136,18 @@ runs: # patches -- sources are independent of runner and compiler, so every instance shares one # entry. The patches matter because CPM's own source-cache key covers a patch file's path # but not its contents, so editing one in place would otherwise reuse the old patched tree. + # COPYFILE_DISABLE stops bsdtar from storing macOS xattrs as `._name` AppleDouble members. + # This is the only entry restored on a different runner image than saved it, and a tar that + # does not reassemble those members leaves `._*.cpp` files that upstream source globs then + # try to compile; `-v2-` drops the entries saved before that. - name: Cache thirdparty sources if: ${{ steps.thirdparty-cache.outputs.cache-hit != 'true' }} uses: actions/cache@v5 + env: + COPYFILE_DISABLE: '1' with: path: thirdparty_sources - key: ${{ inputs.cache-prefix }}-sources-${{ hashFiles('thirdparty/package-lock.cmake', 'thirdparty/patches/*') }} + key: ${{ inputs.cache-prefix }}-sources-v2-${{ hashFiles('thirdparty/package-lock.cmake', 'thirdparty/patches/*') }} # Always run: cached thirdparty .dylibs link against brew libs at runtime, # so brew packages must be installed on hosted runners even on cache hit. From dff1903bd4f896bc6f6f32b2242eeee17bf3abe0 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Mon, 17 Aug 2026 09:44:09 +0200 Subject: [PATCH 12/19] WIP: Fix build --- scripts/mrbind/generate.mk | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/mrbind/generate.mk b/scripts/mrbind/generate.mk index 90f3d3189c89..94a5d011ea0d 100644 --- a/scripts/mrbind/generate.mk +++ b/scripts/mrbind/generate.mk @@ -582,9 +582,16 @@ ifneq ($(TARGETING_EMSCRIPTEN),) FETCH_PACKAGES += expected spdlog parallel-hashmap onetbb jsoncpp googletest openvdb endif -THIRDPARTY_SOURCES_MK := $(TEMP_OUTPUT_DIR)/thirdparty_sources.mk +# Both the sources and the CMake scratch have to stay out of `$(TEMP_OUTPUT_DIR)`: for TARGET=c +# that is `source/MeshLibC2/temp`, which ships whole as the CBindings artifact and is fed to +# Doxygen. The download location defaults to the one scripts/build_thirdparty.sh uses, so a +# checkout that built the thirdparty libs already has these sources. +CPM_SOURCE_CACHE ?= $(abspath $(makefile_dir)../../thirdparty_sources) +THIRDPARTY_FETCH_DIR := $(makefile_dir)../../build/thirdparty_fetch +THIRDPARTY_SOURCES_MK := $(THIRDPARTY_FETCH_DIR)/thirdparty_sources.mk $(THIRDPARTY_SOURCES_MK): $(makefile_dir)../../thirdparty/package-lock.cmake - cmake -S $(makefile_dir)../../thirdparty/fetch -B $(TEMP_OUTPUT_DIR)/thirdparty_fetch \ + cmake -S $(makefile_dir)../../thirdparty/fetch -B $(THIRDPARTY_FETCH_DIR) \ + -D CPM_SOURCE_CACHE=$(CPM_SOURCE_CACHE) \ -D MESHLIB_FETCH_PACKAGES="$(subst $(space),;,$(sort $(FETCH_PACKAGES)))" \ -D MESHLIB_FETCH_OUTPUT=$(abspath $@) include $(THIRDPARTY_SOURCES_MK) From 9589621c8c4ff088f30d82aa9969f5508d520400 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Thu, 3 Sep 2026 10:20:25 +0200 Subject: [PATCH 13/19] Revert the breaking changes --- .../install-macos-thirdparty/action.yml | 48 ++--- .../build-test-emscripten-c-bindings.yml | 2 +- .github/workflows/build-test-emscripten.yml | 6 +- .github/workflows/build-test-linux-vcpkg.yml | 2 +- .github/workflows/build-test-ubuntu-arm64.yml | 2 +- .github/workflows/build-test-ubuntu-x64.yml | 2 +- .github/workflows/build-test-windows.yml | 2 +- .github/workflows/pip-build.yml | 2 +- .github/workflows/update-docs-manual.yml | 2 +- docker/emscripten-build-c-bindingsDockerfile | 1 - docker/emscriptenDockerfile | 1 - docs/third_party_licenses.md | 18 +- scripts/build_cpm_thirdparty.sh | 148 +++++++++++++ scripts/build_thirdparty.sh | 39 +++- scripts/check_third_party_licenses.py | 64 +----- scripts/clone_submodules_emscripten.sh | 23 ++ .../clone_submodules_emscripten_bindings.sh | 7 + scripts/clone_submodules_linux.sh | 21 +- scripts/clone_submodules_macos.sh | 11 + scripts/clone_submodules_windows.ps1 | 5 + scripts/cmake_install.sh | 4 +- .../devops/docker_image_source_checksum.sh | 1 + scripts/mrbind/generate.mk | 43 +--- scripts/thirdparty/boost-libs-download.sh | 19 ++ scripts/thirdparty/boost-libs.sh | 15 ++ .../thirdparty/boost-locale-std-mutex.patch | 185 ++++++++++++++++ scripts/thirdparty/clip.sh | 16 ++ scripts/thirdparty/eigen.sh | 14 ++ scripts/thirdparty/fastmcpp.sh | 16 ++ scripts/thirdparty/libE57Format.sh | 15 ++ scripts/thirdparty/libjpeg-turbo.sh | 17 ++ scripts/thirdparty/mbedtls.sh | 14 ++ scripts/thirdparty/openvdb.sh | 23 ++ thirdparty/CMakeLists.txt | 199 ++++++++++++++++++ thirdparty/{ => cpm}/cmake/CPM.cmake | 0 .../{ => cpm}/common_post_project.cmake | 4 +- thirdparty/{ => cpm}/common_pre_project.cmake | 2 +- thirdparty/{ => cpm}/fetch/CMakeLists.txt | 0 thirdparty/{ => cpm}/package-lock.cmake | 4 +- .../boost-honor-skip-install-rules.patch | 0 .../patches/boost-locale-no-thread.patch | 0 .../patches/boost-locale-std-mutex.patch | 0 .../clip-config-use-project-name.patch | 0 ...libjpeg-turbo-allow-add-subdirectory.patch | 0 thirdparty/{ => cpm}/stage1/CMakeLists.txt | 0 thirdparty/{ => cpm}/stage2/CMakeLists.txt | 0 thirdparty/licenses/manifest.json | 123 ++++++----- 47 files changed, 898 insertions(+), 222 deletions(-) create mode 100755 scripts/build_cpm_thirdparty.sh create mode 100755 scripts/thirdparty/boost-libs-download.sh create mode 100755 scripts/thirdparty/boost-libs.sh create mode 100644 scripts/thirdparty/boost-locale-std-mutex.patch create mode 100755 scripts/thirdparty/clip.sh create mode 100755 scripts/thirdparty/eigen.sh create mode 100755 scripts/thirdparty/fastmcpp.sh create mode 100755 scripts/thirdparty/libjpeg-turbo.sh create mode 100755 scripts/thirdparty/mbedtls.sh create mode 100755 scripts/thirdparty/openvdb.sh create mode 100644 thirdparty/CMakeLists.txt rename thirdparty/{ => cpm}/cmake/CPM.cmake (100%) rename thirdparty/{ => cpm}/common_post_project.cmake (90%) rename thirdparty/{ => cpm}/common_pre_project.cmake (92%) rename thirdparty/{ => cpm}/fetch/CMakeLists.txt (100%) rename thirdparty/{ => cpm}/package-lock.cmake (98%) rename thirdparty/{ => cpm}/patches/boost-honor-skip-install-rules.patch (100%) rename thirdparty/{ => cpm}/patches/boost-locale-no-thread.patch (100%) rename thirdparty/{ => cpm}/patches/boost-locale-std-mutex.patch (100%) rename thirdparty/{ => cpm}/patches/clip-config-use-project-name.patch (100%) rename thirdparty/{ => cpm}/patches/libjpeg-turbo-allow-add-subdirectory.patch (100%) rename thirdparty/{ => cpm}/stage1/CMakeLists.txt (100%) rename thirdparty/{ => cpm}/stage2/CMakeLists.txt (100%) diff --git a/.github/actions/install-macos-thirdparty/action.yml b/.github/actions/install-macos-thirdparty/action.yml index 2ba01651c474..7a68a3978afa 100644 --- a/.github/actions/install-macos-thirdparty/action.yml +++ b/.github/actions/install-macos-thirdparty/action.yml @@ -91,12 +91,10 @@ runs: # the prefix is baked into mrbind's rpath. # - thirdparty-hash: unified hash of everything that influences the # thirdparty ./lib + ./include outputs -- brew prefix (baked into the - # rpaths of the produced .dylibs), the dependency versions (pinned in - # package-lock.cmake, plus the mrbind-pybind11 gitlink for the one - # dependency that is still a submodule), and the build-relevant scripts + - # stage projects + brew-requirements list. `git ls-tree` reads gitlink - # entries from the index, so it works whether or not the submodule is - # checked out. + # rpaths of the produced .dylibs), submodule SHAs pinned in HEAD (the + # source we compile), and the build-relevant scripts + CMakeLists + + # brew-requirements list. `git ls-tree` reads gitlink entries from the + # index, so it works whether or not the submodules are checked out. - name: Compute cache key inputs id: cache-keys shell: bash @@ -106,16 +104,23 @@ runs: echo "brew-hash=$(printf %s "$BREW_PREFIX" | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT" echo "thirdparty-hash=$( { printf '%s\n' "$BREW_PREFIX" - git ls-tree HEAD thirdparty/mrbind-pybind11 + git ls-tree HEAD \ + thirdparty/googletest \ + thirdparty/OpenCTM-git \ + thirdparty/parallel-hashmap \ + thirdparty/libE57Format \ + thirdparty/glad \ + thirdparty/mrbind-pybind11 \ + thirdparty/tinygltf \ + thirdparty/laz-perf \ + thirdparty/clip \ + thirdparty/fastmcpp shasum -a 256 \ scripts/build_thirdparty.sh \ scripts/install_brew_requirements.sh \ - thirdparty/package-lock.cmake \ - thirdparty/common_pre_project.cmake \ - thirdparty/common_post_project.cmake \ - thirdparty/stage1/CMakeLists.txt \ - thirdparty/stage2/CMakeLists.txt \ - thirdparty/patches/* \ + scripts/thirdparty/clip.sh \ + scripts/thirdparty/fastmcpp.sh \ + thirdparty/CMakeLists.txt \ requirements/macos.txt } | shasum -a 256 | cut -c1-16)" >> "$GITHUB_OUTPUT" @@ -132,23 +137,6 @@ runs: include key: ${{ inputs.cache-prefix }}-${{ inputs.cache-instance }}-${{ inputs.cache-compiler }}-${{ steps.cache-keys.outputs.thirdparty-hash }} - # CPM downloads dependency sources here when the build runs. Keyed on the pins and the - # patches -- sources are independent of runner and compiler, so every instance shares one - # entry. The patches matter because CPM's own source-cache key covers a patch file's path - # but not its contents, so editing one in place would otherwise reuse the old patched tree. - # COPYFILE_DISABLE stops bsdtar from storing macOS xattrs as `._name` AppleDouble members. - # This is the only entry restored on a different runner image than saved it, and a tar that - # does not reassemble those members leaves `._*.cpp` files that upstream source globs then - # try to compile; `-v2-` drops the entries saved before that. - - name: Cache thirdparty sources - if: ${{ steps.thirdparty-cache.outputs.cache-hit != 'true' }} - uses: actions/cache@v5 - env: - COPYFILE_DISABLE: '1' - with: - path: thirdparty_sources - key: ${{ inputs.cache-prefix }}-sources-v2-${{ hashFiles('thirdparty/package-lock.cmake', 'thirdparty/patches/*') }} - # Always run: cached thirdparty .dylibs link against brew libs at runtime, # so brew packages must be installed on hosted runners even on cache hit. - name: Install brew requirements diff --git a/.github/workflows/build-test-emscripten-c-bindings.yml b/.github/workflows/build-test-emscripten-c-bindings.yml index 17b22befd2db..c6c22f3d2554 100644 --- a/.github/workflows/build-test-emscripten-c-bindings.yml +++ b/.github/workflows/build-test-emscripten-c-bindings.yml @@ -75,7 +75,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-emscripten.yml b/.github/workflows/build-test-emscripten.yml index 2a03e01c4230..055ce65933a7 100644 --- a/.github/workflows/build-test-emscripten.yml +++ b/.github/workflows/build-test-emscripten.yml @@ -85,7 +85,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | @@ -191,7 +191,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | @@ -277,7 +277,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh -- scripts/clone_submodules_emscripten.sh + bash scripts/retry.sh -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-linux-vcpkg.yml b/.github/workflows/build-test-linux-vcpkg.yml index 710fbdcf3dc4..80fd31d06c1b 100644 --- a/.github/workflows/build-test-linux-vcpkg.yml +++ b/.github/workflows/build-test-linux-vcpkg.yml @@ -130,7 +130,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory ${GITHUB_WORKSPACE} # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux_vcpkg.sh + scripts/clone_submodules_linux_vcpkg.sh --skip-prebuilt-thirdparty - name: Install MRBind if: ${{ inputs.mrbind || inputs.mrbind_c }} diff --git a/.github/workflows/build-test-ubuntu-arm64.yml b/.github/workflows/build-test-ubuntu-arm64.yml index d2b579a258a7..feb0a71adc5f 100644 --- a/.github/workflows/build-test-ubuntu-arm64.yml +++ b/.github/workflows/build-test-ubuntu-arm64.yml @@ -87,7 +87,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory '*' # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux.sh + scripts/clone_submodules_linux.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-ubuntu-x64.yml b/.github/workflows/build-test-ubuntu-x64.yml index d2c32ae48563..56670d96c834 100644 --- a/.github/workflows/build-test-ubuntu-x64.yml +++ b/.github/workflows/build-test-ubuntu-x64.yml @@ -76,7 +76,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory '*' # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux.sh + scripts/clone_submodules_linux.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | diff --git a/.github/workflows/build-test-windows.yml b/.github/workflows/build-test-windows.yml index cf4eee887bf0..5be9849901e7 100644 --- a/.github/workflows/build-test-windows.yml +++ b/.github/workflows/build-test-windows.yml @@ -84,7 +84,7 @@ jobs: - name: Checkout third-party submodules shell: bash run: | - bash scripts/retry.sh --timeout 300 -- powershell scripts/clone_submodules_windows.ps1 + bash scripts/retry.sh --timeout 300 -- powershell scripts/clone_submodules_windows.ps1 --skip-prebuilt-thirdparty - name: Get AWS instance type uses: ./.github/actions/get-aws-instance-type diff --git a/.github/workflows/pip-build.yml b/.github/workflows/pip-build.yml index 19cf69104a06..196c7f0aa8b0 100644 --- a/.github/workflows/pip-build.yml +++ b/.github/workflows/pip-build.yml @@ -264,7 +264,7 @@ jobs: git config --global --add safe.directory ${GITHUB_WORKSPACE}/thirdparty/mrbind git config --global --add safe.directory ${GITHUB_WORKSPACE}/thirdparty/mrbind/deps/cppdecl # Retried via retry.sh: submodule endpoints occasionally 500. - bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh + bash scripts/retry.sh --timeout 300 -- scripts/clone_submodules_emscripten.sh --skip-prebuilt-thirdparty - name: Add the LLVM keg to PATH # Via GITHUB_PATH, not GITHUB_ENV: any GITHUB_PATH entry makes the runner diff --git a/.github/workflows/update-docs-manual.yml b/.github/workflows/update-docs-manual.yml index 4451c749f1e0..23272f4d58a4 100644 --- a/.github/workflows/update-docs-manual.yml +++ b/.github/workflows/update-docs-manual.yml @@ -47,7 +47,7 @@ jobs: export HOME=${RUNNER_TEMP} git config --global --add safe.directory '*' # No retry.sh, linux scripts retry themselves. - scripts/clone_submodules_linux.sh + scripts/clone_submodules_linux.sh --skip-prebuilt-thirdparty - name: Install thirdparty libs run: | diff --git a/docker/emscripten-build-c-bindingsDockerfile b/docker/emscripten-build-c-bindingsDockerfile index 91640907b6e3..111cacd7719f 100644 --- a/docker/emscripten-build-c-bindingsDockerfile +++ b/docker/emscripten-build-c-bindingsDockerfile @@ -52,7 +52,6 @@ COPY . . ENV MR_STATE=DOCKER_BUILD ENV MR_EMSCRIPTEN=ON -ENV CPM_SOURCE_CACHE=/opt/cpm-cache # 32-bit multi-threaded RUN </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} \ + " + if [[ ${MR_EMSCRIPTEN_SINGLETHREAD} == 0 ]] ; then + CFLAGS="${CFLAGS} -pthread" + CXXFLAGS="${CFLAGS} -pthread" + fi + if [[ ${MR_EMSCRIPTEN_WASM64} == 1 ]] ; then + CFLAGS="${CFLAGS} -s MEMORY64=1" + CXXFLAGS="${CFLAGS} -s MEMORY64=1" + LDFLAGS="${LDFLAGS} -s MEMORY64=1" + fi + if [[ ${MR_EMSCRIPTEN_WASM2023} == 1 ]] ; then + CFLAGS="${CFLAGS} -msimd128 -mbulk-memory -mnontrapping-fptoint -msse4.2" + CXXFLAGS="${CXXFLAGS} -msimd128 -mbulk-memory -mnontrapping-fptoint -msse4.2" + fi +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:-${MESHLIB_THIRDPARTY_ROOT_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 ./lib folder. You could run ./scripts/build_source.sh\n\n" diff --git a/scripts/build_thirdparty.sh b/scripts/build_thirdparty.sh index 80df08926566..6d1f2ee619ab 100755 --- a/scripts/build_thirdparty.sh +++ b/scripts/build_thirdparty.sh @@ -126,22 +126,41 @@ 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:-${MESHLIB_THIRDPARTY_ROOT_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 + # build Boost libraries separately + # TODO: build Boost.Locale as a standalone library + ${SCRIPT_DIR}/thirdparty/boost-libs-download.sh ${MESHLIB_THIRDPARTY_DIR}/boost-libs + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/boost-libs.sh ${MESHLIB_THIRDPARTY_DIR}/boost-libs # 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 "{}" \; + + # build libjpeg-turbo separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/libjpeg-turbo.sh ${MESHLIB_THIRDPARTY_DIR}/libjpeg-turbo + # build MbedTLS separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/mbedtls.sh ${MESHLIB_THIRDPARTY_DIR}/mbedtls + + cmake -S ${MESHLIB_THIRDPARTY_DIR} -B . ${MR_CMAKE_OPTIONS} + cmake --build . -j ${NPROC} + cmake --install . + + # build Eigen separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/eigen.sh ${MESHLIB_THIRDPARTY_DIR}/eigen + # build libE57Format separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/libE57Format.sh ${MESHLIB_THIRDPARTY_DIR}/libE57Format + # build OpenVDB separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/openvdb.sh ${MESHLIB_THIRDPARTY_DIR}/openvdb/v10/openvdb +else + cmake -S ${MESHLIB_THIRDPARTY_DIR} -B . ${MR_CMAKE_OPTIONS} + cmake --build . -j ${NPROC} + cmake --install . + + # build clip separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/clip.sh ${MESHLIB_THIRDPARTY_DIR}/clip + # build fastmcpp separately + CMAKE_OPTIONS="${MR_CMAKE_OPTIONS}" ${SCRIPT_DIR}/thirdparty/fastmcpp.sh ${MESHLIB_THIRDPARTY_DIR}/fastmcpp fi popd diff --git a/scripts/check_third_party_licenses.py b/scripts/check_third_party_licenses.py index 4023f4f4ca78..ede3667ca6bb 100755 --- a/scripts/check_third_party_licenses.py +++ b/scripts/check_third_party_licenses.py @@ -8,12 +8,11 @@ 1. checks the file has a matching non-empty section (id, license, upstream), with no orphan or misordered sections; - 2. recomputes the component's current version from its source (CPM pin, git submodule - SHA, vcpkg overlay-port version, vcpkg registry baseline versions, or a hash of - tracked in-tree files) and fails if it differs from the pinned `version` in the - manifest -- forcing a human to re-check the upstream license text and re-pin; - 3. warns about CPM packages and git submodules that look shippable but are absent from - the manifest. + 2. recomputes the component's current version from its source (git submodule SHA, + vcpkg overlay-port version, vcpkg registry baseline versions, or a hash of tracked + in-tree files) and fails if it differs from the pinned `version` in the manifest -- + forcing a human to re-check the upstream license text and re-pin; + 3. warns about git submodules that look shippable but are absent from the manifest. Run `--update-versions` to re-pin the manifest to current versions after you have verified the texts are still correct. That is the only mode that reads the vcpkg registry @@ -27,7 +26,6 @@ import argparse import hashlib import json -import re import subprocess import sys import urllib.parse @@ -41,7 +39,6 @@ NOTICES = LICENSES_DIR / "THIRD-PARTY-NOTICES.txt" VCPKG_JSON = REPO_ROOT / "thirdparty" / "vcpkg" / "vcpkg.json" VCPKG_PORTS = REPO_ROOT / "thirdparty" / "vcpkg" / "ports" -PACKAGE_LOCK = REPO_ROOT / "thirdparty" / "package-lock.cmake" # Section separator in THIRD-PARTY-NOTICES.txt. RULE = "#" * 80 @@ -52,17 +49,11 @@ # Submodules that ship nothing in the SDK binaries, so they need no license folder. # Keep this list short and justified -- anything not here must appear in the manifest. EXCLUDED_SUBMODULES = { + "thirdparty/googletest", # unit-test framework, not shipped "thirdparty/mrbind", # build-time binding generator, not shipped "test_data", # test assets } -# Same, for packages declared in thirdparty/package-lock.cmake. -EXCLUDED_PACKAGES = { - "googletest", # unit-test framework, not shipped - "boost-libs", # Boost's manifest entry pins the vcpkg ports instead; - # this package is the Emscripten-only source tarball -} - def git(*args): return subprocess.run( @@ -82,37 +73,6 @@ def submodule_sha(path): return sha -_CPM_PINS = None - - -def cpm_pins(): - """package -> pinned ref, parsed from thirdparty/package-lock.cmake. - - The ref is the GIT_TAG (a release tag or a commit hash) or, for packages fetched as an - archive, the URL. Either changes whenever the dependency is bumped, which is all the - tripwire needs. - """ - global _CPM_PINS - if _CPM_PINS is None: - text = PACKAGE_LOCK.read_text(encoding="utf-8") - _CPM_PINS = {} - for name, body in re.findall(r"^set\(MESHLIB_PACKAGE_(\S+)(.*?)^\)$", text, - re.MULTILINE | re.DOTALL): - ref = re.search(r"^\s*(?:GIT_TAG|URL)\s+(\S+)$", body, re.MULTILINE) - if ref is None: - raise ValueError(f"package '{name}' in {PACKAGE_LOCK.name} " - f"declares neither GIT_TAG nor URL") - _CPM_PINS[name] = ref.group(1) - return _CPM_PINS - - -def cpm_pin(package): - pin = cpm_pins().get(package) - if pin is None: - raise ValueError(f"package '{package}' is not declared in {PACKAGE_LOCK.name}") - return pin - - def vcpkg_default_registry(): data = json.loads(VCPKG_JSON.read_text(encoding="utf-8")) reg = data["configuration"]["default-registry"] @@ -188,8 +148,6 @@ def current_version(source, resolve_registry=False): see check_vcpkg_baseline. """ t = source["type"] - if t == "cpm": - return cpm_pin(source["package"]) if t == "submodule": return submodule_sha(source["path"]) if t == "vcpkg-overlay": @@ -336,7 +294,7 @@ def check(): errors.append(f"unexpected entry {REL}/{entry.name} -- only " f"{', '.join(sorted(ALLOWED_ENTRIES))} belong here") - # 3b. shippable-looking dependencies missing from the manifest (warning only) + # 3b. shippable-looking submodules missing from the manifest (warning only) covered = {c["source"].get("path") for c in components if c["source"]["type"] == "submodule"} for path in gitmodules_paths(): @@ -345,14 +303,6 @@ def check(): warnings.append(f"submodule '{path}' is not in manifest.json and not in " f"EXCLUDED_SUBMODULES -- add a license entry or exclude it") - covered = {c["source"].get("package") for c in components - if c["source"]["type"] == "cpm"} - for package in cpm_pins(): - if package in covered or package in EXCLUDED_PACKAGES: - continue - warnings.append(f"package '{package}' is not in manifest.json and not in " - f"EXCLUDED_PACKAGES -- add a license entry or exclude it") - for w in warnings: print(f"WARNING: {w}", file=sys.stderr) for e in errors: diff --git a/scripts/clone_submodules_emscripten.sh b/scripts/clone_submodules_emscripten.sh index 6ed707205509..2993667d7436 100755 --- a/scripts/clone_submodules_emscripten.sh +++ b/scripts/clone_submodules_emscripten.sh @@ -8,5 +8,28 @@ SUBMODULES=( thirdparty/mrbind-pybind11 ) +if [[ $1 != --skip-prebuilt-thirdparty ]]; then + SUBMODULES+=( + thirdparty/c-blosc + thirdparty/clip + thirdparty/expected + thirdparty/fastmcpp + thirdparty/fmt + thirdparty/GDCM + thirdparty/glad + thirdparty/googletest + thirdparty/jsoncpp + thirdparty/laz-perf + thirdparty/libzip + thirdparty/onetbb + thirdparty/OpenCTM-git + thirdparty/parallel-hashmap + thirdparty/spdlog + thirdparty/tinygltf + thirdparty/tinyxml2 + thirdparty/zlib-ng + ) +fi + "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/.. "${SUBMODULES[@]}" "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/../thirdparty/mrbind deps/cppdecl diff --git a/scripts/clone_submodules_emscripten_bindings.sh b/scripts/clone_submodules_emscripten_bindings.sh index 65884d4c99f5..4e77f6efcf69 100755 --- a/scripts/clone_submodules_emscripten_bindings.sh +++ b/scripts/clone_submodules_emscripten_bindings.sh @@ -3,8 +3,15 @@ # This is to be used on platforms that generate C/C# bindings through Emscripten: on Windows, and optionally on Linux. Not needed on Mac. git -C "$(dirname "$BASH_SOURCE")"/.. submodule update --init --depth 1 \ + thirdparty/eigen \ + thirdparty/expected \ thirdparty/imgui \ + thirdparty/jsoncpp \ thirdparty/mrbind \ thirdparty/mrbind-pybind11 \ + thirdparty/onetbb \ + thirdparty/openvdb/v10/openvdb \ + thirdparty/parallel-hashmap \ + thirdparty/spdlog \ git -C "$(dirname "$BASH_SOURCE")"/../thirdparty/mrbind submodule update --init --depth 1 deps/cppdecl diff --git a/scripts/clone_submodules_linux.sh b/scripts/clone_submodules_linux.sh index 6ed707205509..5bff1d2b4c80 100755 --- a/scripts/clone_submodules_linux.sh +++ b/scripts/clone_submodules_linux.sh @@ -4,9 +4,28 @@ SCRIPT_DIR="$(dirname "$BASH_SOURCE")" SUBMODULES=( thirdparty/imgui - thirdparty/mrbind + thirdparty/eigen thirdparty/mrbind-pybind11 + thirdparty/mrbind ) +if [[ $1 != --skip-prebuilt-thirdparty ]]; then + SUBMODULES+=( + thirdparty/clip + thirdparty/cpp-httplib + thirdparty/cpr + thirdparty/fastmcpp + thirdparty/glad + thirdparty/laz-perf + thirdparty/libE57Format + thirdparty/nlohmann-json + thirdparty/OpenCTM-git + thirdparty/openvdb/v10/openvdb + thirdparty/parallel-hashmap + thirdparty/tinygltf + thirdparty/zlib-ng + ) +fi + "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/.. "${SUBMODULES[@]}" "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/../thirdparty/mrbind deps/cppdecl diff --git a/scripts/clone_submodules_macos.sh b/scripts/clone_submodules_macos.sh index 6ed707205509..9c037f3a6518 100755 --- a/scripts/clone_submodules_macos.sh +++ b/scripts/clone_submodules_macos.sh @@ -3,9 +3,20 @@ SCRIPT_DIR="$(dirname "$BASH_SOURCE")" SUBMODULES=( + thirdparty/clip + thirdparty/cpp-httplib + thirdparty/eigen + thirdparty/expected + thirdparty/fastmcpp + thirdparty/glad thirdparty/imgui + thirdparty/laz-perf + thirdparty/libE57Format thirdparty/mrbind thirdparty/mrbind-pybind11 + thirdparty/nlohmann-json + thirdparty/OpenCTM-git + thirdparty/tinygltf ) "$SCRIPT_DIR"/checkout_submodules.sh "$SCRIPT_DIR"/.. "${SUBMODULES[@]}" diff --git a/scripts/clone_submodules_windows.ps1 b/scripts/clone_submodules_windows.ps1 index 076932300137..1b72ce625379 100644 --- a/scripts/clone_submodules_windows.ps1 +++ b/scripts/clone_submodules_windows.ps1 @@ -1,5 +1,10 @@ git -C "$PSScriptRoot\.." submodule update --init --depth 1 ` thirdparty/imgui ` + thirdparty/eigen ` + thirdparty/expected ` + thirdparty/fastmcpp ` + thirdparty/nlohmann-json ` + thirdparty/cpp-httplib ` thirdparty/mrbind ` thirdparty/mrbind-pybind11 ` diff --git a/scripts/cmake_install.sh b/scripts/cmake_install.sh index b4dbbfac12fb..ec37f69fb1cf 100755 --- a/scripts/cmake_install.sh +++ b/scripts/cmake_install.sh @@ -20,6 +20,8 @@ cmake_install () { cmake_install ${BASE_DIR}/build/Release cmake_install ${BASE_DIR}/build/Debug -for BUILD_DIR in ${BASE_DIR}/thirdparty_build/stage* ; do +cmake_install ${BASE_DIR}/thirdparty_build +# Emscripten dependencies +for BUILD_DIR in ${BASE_DIR}/thirdparty_build/*_build ; do cmake_install ${BUILD_DIR} done diff --git a/scripts/devops/docker_image_source_checksum.sh b/scripts/devops/docker_image_source_checksum.sh index 45f3a5db446c..ac9039ebf771 100755 --- a/scripts/devops/docker_image_source_checksum.sh +++ b/scripts/devops/docker_image_source_checksum.sh @@ -7,6 +7,7 @@ distro=$1 common=( scripts/build_thirdparty.sh scripts/ask_emscripten_mode.src + scripts/thirdparty thirdparty ':(exclude)thirdparty/install.bat' ':(exclude)thirdparty/vcpkg/**' diff --git a/scripts/mrbind/generate.mk b/scripts/mrbind/generate.mk index 40c76f6a8a94..df0d523168bb 100644 --- a/scripts/mrbind/generate.mk +++ b/scripts/mrbind/generate.mk @@ -594,31 +594,6 @@ endif ifneq ($(TARGET),csharp) # Stuff below is for all languages except C#. C# logic is at the bottom of this makefile. -# Dependency sources we parse MeshLib headers against. `thirdparty/fetch` downloads them at the -# versions pinned in `thirdparty/package-lock.cmake` and writes `SRC_=` lines, which -# make re-reads after remaking the include below. Nothing here is built. -FETCH_PACKAGES := eigen -ifneq ($(IS_WINDOWS),) -FETCH_PACKAGES += parallel-hashmap -endif -ifneq ($(TARGETING_EMSCRIPTEN),) -FETCH_PACKAGES += expected spdlog parallel-hashmap onetbb jsoncpp googletest openvdb -endif - -# Both the sources and the CMake scratch have to stay out of `$(TEMP_OUTPUT_DIR)`: for TARGET=c -# that is `source/MeshLibC2/temp`, which ships whole as the CBindings artifact and is fed to -# Doxygen. The download location defaults to the one scripts/build_thirdparty.sh uses, so a -# checkout that built the thirdparty libs already has these sources. -CPM_SOURCE_CACHE ?= $(abspath $(makefile_dir)../../thirdparty_sources) -THIRDPARTY_FETCH_DIR := $(makefile_dir)../../build/thirdparty_fetch -THIRDPARTY_SOURCES_MK := $(THIRDPARTY_FETCH_DIR)/thirdparty_sources.mk -$(THIRDPARTY_SOURCES_MK): $(makefile_dir)../../thirdparty/package-lock.cmake - cmake -S $(makefile_dir)../../thirdparty/fetch -B $(THIRDPARTY_FETCH_DIR) \ - -D CPM_SOURCE_CACHE=$(CPM_SOURCE_CACHE) \ - -D MESHLIB_FETCH_PACKAGES="$(subst $(space),;,$(sort $(FETCH_PACKAGES)))" \ - -D MESHLIB_FETCH_OUTPUT=$(abspath $@) -include $(THIRDPARTY_SOURCES_MK) - INPUT_GLOBS := *.h ifeq ($(TARGET),python) @@ -648,7 +623,7 @@ ifneq ($(DEPS_INCLUDE_DIR),) COMPILER_FLAGS += -I$(DEPS_INCLUDE_DIR)/eigen3 endif # TODO: use system Eigen -COMPILER_FLAGS += -isystem $(SRC_eigen) +COMPILER_FLAGS += -isystem $(makefile_dir)../../thirdparty/eigen COMPILER_FLAGS += -isystem $(makefile_dir)../../thirdparty/mrbind-pybind11/include COMPILER_FLAGS_LIBCLANG := $(call load_file,$(makefile_dir)parser_only_flags.txt) COMPILER := $(CXX_FOR_BINDINGS) $(subst $(lf), ,$(call load_file,$(makefile_dir)compiler_only_flags.txt)) -I$(makefile_dir) @@ -691,19 +666,19 @@ COMPILER_FLAGS_LIBCLANG += -stdlib=libstdc++ $(default_include_paths) else COMPILER_FLAGS_LIBCLANG += --sysroot=$(call quote,$(EMSCRIPTEN_SYSROOT)) COMPILER_FLAGS_LIBCLANG += -isystem $(call quote,$(EMSCRIPTEN_SYSROOT)/include/compat)# Mhm. -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_expected)/include -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_spdlog)/include +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/expected/include +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/spdlog/include #EMSCRIPTEN_THIRDPARTY_DIR := . #$(info EMSCRIPTEN_SYSROOT = `$(EMSCRIPTEN_THIRDPARTY_DIR)`) #COMPILER_FLAGS_LIBCLANG += -isystem $(call quote,$(EMSCRIPTEN_THIRDPARTY_DIR)/include) # Those would normally be in `./include`, but we try to avoid building third-party libraries... -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_parallel_hashmap) -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_onetbb)/include -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_jsoncpp)/include -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_googletest)/googletest/include -COMPILER_FLAGS_LIBCLANG += -isystem $(SRC_openvdb)/openvdb +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/parallel-hashmap +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/onetbb/include +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/jsoncpp/include +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/googletest/googletest/include +COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)../../thirdparty/openvdb/v10/openvdb/openvdb # OpenVDB generates a file called `openvdb/version.h` during build. To avoid having to generate it, we add our own copy of it to the include path. COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)emscripten_headers COMPILER_FLAGS_LIBCLANG += -isystem $(makefile_dir)emscripten_headers/openvdb @@ -766,7 +741,7 @@ LINKER_FLAGS += -rtlib=platform # Don't generate .lib files. LINKER_FLAGS += -Wl,-noimplib # Library paths: -COMPILER_FLAGS += -isystem $(SRC_parallel_hashmap) +COMPILER_FLAGS += -isystem $(makefile_dir)../../thirdparty/parallel-hashmap COMPILER_FLAGS += -D_DLL -D_MT # Only seems to matter on VS2022 and not on VS2019, for some reason. COMPILER_FLAGS += -DNOMINMAX diff --git a/scripts/thirdparty/boost-libs-download.sh b/scripts/thirdparty/boost-libs-download.sh new file mode 100755 index 000000000000..8939b59d8587 --- /dev/null +++ b/scripts/thirdparty/boost-libs-download.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" + +SCRIPT_DIR="$(realpath "$(dirname "$BASH_SOURCE")")" + +# Boost libraries are so large it's unreasonable to download them via git +BOOST_VERSION="1.83.0" +if [ ! -d "${SOURCE_DIR}" ] ; then + cd $(dirname "${SOURCE_DIR}") + curl -L https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION}.tar.xz | tar xJ + mv boost-${BOOST_VERSION} $(basename "${SOURCE_DIR}") + + # to support the single-threaded version, we must compile Boost.Locale without Boost.Thread + cd "${SOURCE_DIR}/libs/locale/" + sed -i '/Boost::thread/d' CMakeLists.txt + patch -Np1 -i "${SCRIPT_DIR}/boost-locale-std-mutex.patch" +fi diff --git a/scripts/thirdparty/boost-libs.sh b/scripts/thirdparty/boost-libs.sh new file mode 100755 index 000000000000..9a4749582eab --- /dev/null +++ b/scripts/thirdparty/boost-libs.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./boost-libs_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D CMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -D BOOST_INCLUDE_LIBRARIES=locale \ + -D BOOST_LOCALE_ENABLE_ICONV=OFF \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/boost-locale-std-mutex.patch b/scripts/thirdparty/boost-locale-std-mutex.patch new file mode 100644 index 000000000000..78b01abba5af --- /dev/null +++ b/scripts/thirdparty/boost-locale-std-mutex.patch @@ -0,0 +1,185 @@ +diff -rup a/src/boost/locale/icu/date_time.cpp b/src/boost/locale/icu/date_time.cpp +--- a/src/boost/locale/icu/date_time.cpp ++++ b/src/boost/locale/icu/date_time.cpp +@@ -14,9 +14,9 @@ + #include "boost/locale/icu/icu_util.hpp" + #include "boost/locale/icu/time_zone.hpp" + #include "boost/locale/icu/uconv.hpp" +-#include + #include + #include ++#include + #include + #include + #include +@@ -214,8 +214,8 @@ namespace boost { namespace locale { nam + } + + private: +- typedef boost::unique_lock guard; +- mutable boost::mutex lock_; ++ typedef std::unique_lock guard; ++ mutable std::mutex lock_; + std::string encoding_; + hold_ptr calendar_; + }; +diff -rup a/src/boost/locale/shared/date_time.cpp b/src/boost/locale/shared/date_time.cpp +--- a/src/boost/locale/shared/date_time.cpp ++++ b/src/boost/locale/shared/date_time.cpp +@@ -7,9 +7,8 @@ + #include + #include + #include +-#include +-#include + #include ++#include + + namespace boost { namespace locale { + +@@ -395,9 +394,9 @@ namespace boost { namespace locale { + } + + namespace time_zone { +- boost::mutex& tz_mutex() ++ std::mutex& tz_mutex() + { +- static boost::mutex m; ++ static std::mutex m; + return m; + } + std::string& tz_id() +@@ -407,12 +406,12 @@ namespace boost { namespace locale { + } + std::string global() + { +- boost::unique_lock lock(tz_mutex()); ++ std::unique_lock lock(tz_mutex()); + return tz_id(); + } + std::string global(const std::string& new_id) + { +- boost::unique_lock lock(tz_mutex()); ++ std::unique_lock lock(tz_mutex()); + return boost::exchange(tz_id(), new_id); + } + } // namespace time_zone +diff -rup a/src/boost/locale/shared/generator.cpp b/src/boost/locale/shared/generator.cpp +--- a/src/boost/locale/shared/generator.cpp ++++ b/src/boost/locale/shared/generator.cpp +@@ -7,10 +7,9 @@ + #include + #include + #include +-#include +-#include + #include + #include ++#include + #include + + namespace boost { namespace locale { +@@ -21,7 +20,7 @@ namespace boost { namespace locale { + {} + + mutable std::map cached; +- mutable boost::mutex cached_lock; ++ mutable std::mutex cached_lock; + + category_t cats; + char_facet_t chars; +@@ -101,7 +100,7 @@ namespace boost { namespace locale { + std::locale generator::generate(const std::locale& base, const std::string& id) const + { + if(d->caching_enabled) { +- boost::unique_lock guard(d->cached_lock); ++ std::unique_lock guard(d->cached_lock); + const auto p = d->cached.find(id); + if(p != d->cached.end()) + return p->second; +@@ -126,7 +125,7 @@ namespace boost { namespace locale { + result = backend->install(result, facet, char_facet_t::nochar); + } + if(d->caching_enabled) { +- boost::unique_lock guard(d->cached_lock); ++ std::unique_lock guard(d->cached_lock); + const auto p = d->cached.find(id); + if(p == d->cached.end()) + d->cached[id] = result; +diff -rup a/src/boost/locale/shared/localization_backend.cpp b/src/boost/locale/shared/localization_backend.cpp +--- a/src/boost/locale/shared/localization_backend.cpp ++++ b/src/boost/locale/shared/localization_backend.cpp +@@ -5,10 +5,9 @@ + // https://www.boost.org/LICENSE_1_0.txt + + #include +-#include +-#include + #include + #include ++#include + #include + + #ifdef BOOST_LOCALE_WITH_ICU +@@ -211,9 +210,9 @@ namespace boost { namespace locale { + return mgr; + } + +- boost::mutex& localization_backend_manager_mutex() ++ std::mutex& localization_backend_manager_mutex() + { +- static boost::mutex the_mutex; ++ static std::mutex the_mutex; + return the_mutex; + } + localization_backend_manager& localization_backend_manager_global() +@@ -225,12 +224,12 @@ namespace boost { namespace locale { + + localization_backend_manager localization_backend_manager::global() + { +- boost::unique_lock lock(localization_backend_manager_mutex()); ++ std::unique_lock lock(localization_backend_manager_mutex()); + return localization_backend_manager_global(); + } + localization_backend_manager localization_backend_manager::global(const localization_backend_manager& in) + { +- boost::unique_lock lock(localization_backend_manager_mutex()); ++ std::unique_lock lock(localization_backend_manager_mutex()); + return exchange(localization_backend_manager_global(), in); + } + +diff -rup a/src/boost/locale/win32/lcid.cpp b/src/boost/locale/win32/lcid.cpp +--- a/src/boost/locale/win32/lcid.cpp ++++ b/src/boost/locale/win32/lcid.cpp +@@ -10,9 +10,8 @@ + + #include "boost/locale/win32/lcid.hpp" + #include +-#include +-#include + #include ++#include + #include + #include + #include +@@ -24,9 +23,9 @@ namespace boost { namespace locale { nam + + static table_type* volatile table = 0; + +- boost::mutex& lcid_table_mutex() ++ std::mutex& lcid_table_mutex() + { +- static boost::mutex m; ++ static std::mutex m; + return m; + } + +@@ -76,7 +75,7 @@ namespace boost { namespace locale { nam + if(table) + return *table; + else { +- boost::unique_lock lock(lcid_table_mutex()); ++ std::unique_lock lock(lcid_table_mutex()); + if(table) + return *table; + EnumSystemLocalesA(proc, LCID_INSTALLED); diff --git a/scripts/thirdparty/clip.sh b/scripts/thirdparty/clip.sh new file mode 100755 index 000000000000..d0bcbc2e2924 --- /dev/null +++ b/scripts/thirdparty/clip.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./clip_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D CLIP_EXAMPLES=OFF \ + -D CLIP_TESTS=OFF \ + -D CLIP_X11_WITH_PNG=OFF \ + -D BUILD_SHARED_LIBS=ON \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/eigen.sh b/scripts/thirdparty/eigen.sh new file mode 100755 index 000000000000..18bac03f75b7 --- /dev/null +++ b/scripts/thirdparty/eigen.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./eigen_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D EIGEN_BUILD_DOC=OFF \ + -D BUILD_TESTING=OFF \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/fastmcpp.sh b/scripts/thirdparty/fastmcpp.sh new file mode 100755 index 000000000000..abbc9b1b25fb --- /dev/null +++ b/scripts/thirdparty/fastmcpp.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./fastmcpp_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D FASTMCPP_BUILD_TESTS=OFF \ + -D FASTMCPP_BUILD_EXAMPLES=OFF \ + -D FASTMCPP_FETCH_CURL=OFF \ + -D CMAKE_CXX_FLAGS=-fPIC \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/libE57Format.sh b/scripts/thirdparty/libE57Format.sh index e69de29bb2d1..c35c60aba810 100755 --- a/scripts/thirdparty/libE57Format.sh +++ b/scripts/thirdparty/libE57Format.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./libE57Format_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D E57_BUILD_TEST=OFF \ + -D E57_GIT_SUBMODULE_UPDATE=OFF \ + -D E57_XML_PARSER=TinyXML2 \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/libjpeg-turbo.sh b/scripts/thirdparty/libjpeg-turbo.sh new file mode 100755 index 000000000000..9b23b34e9467 --- /dev/null +++ b/scripts/thirdparty/libjpeg-turbo.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./libjpeg-turbo_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D WITH_JAVA=OFF \ + -D WITH_JPEG8=ON \ + -D WITH_SIMD=OFF \ + -D BUILD_TESTING=OFF \ + -D ENABLE_STATIC=OFF \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/mbedtls.sh b/scripts/thirdparty/mbedtls.sh new file mode 100755 index 000000000000..ad22ee62a749 --- /dev/null +++ b/scripts/thirdparty/mbedtls.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./mbedtls_build}" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D ENABLE_PROGRAMS=OFF \ + -D ENABLE_TESTING=OFF \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/scripts/thirdparty/openvdb.sh b/scripts/thirdparty/openvdb.sh new file mode 100755 index 000000000000..63139741d016 --- /dev/null +++ b/scripts/thirdparty/openvdb.sh @@ -0,0 +1,23 @@ +#!/bin/bash +set -eo pipefail + +SOURCE_DIR="$1" +BUILD_DIR="${2:-./openvdb_build}" + +CXXFLAGS="${CXXFLAGS} -Wno-missing-template-arg-list-after-template-kw" + +CMAKE_OPTIONS="${CMAKE_OPTIONS} \ + -D OPENVDB_ENABLE_UNINSTALL=OFF \ + -D OPENVDB_ENABLE_INSTALL=OFF \ + -D OPENVDB_CORE_SHARED=ON \ + -D OPENVDB_CORE_STATIC=OFF \ + -D OPENVDB_BUILD_BINARIES=OFF \ + -D OPENVDB_BUILD_VDB_PRINT=OFF \ + -D OPENVDB_USE_DELAYED_LOADING=OFF \ + -D USE_EXPLICIT_INSTANTIATION=OFF \ + -D Tbb_VERSION=2021.12 \ +" + +cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" -D CMAKE_C_FLAGS="${CFLAGS}" ${CMAKE_OPTIONS} +cmake --build "${BUILD_DIR}" -j `nproc` +cmake --install "${BUILD_DIR}" diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt new file mode 100644 index 000000000000..ec83af0e41b0 --- /dev/null +++ b/thirdparty/CMakeLists.txt @@ -0,0 +1,199 @@ +# to force update thirdparty touch this line +cmake_minimum_required(VERSION 3.18 FATAL_ERROR) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0) + set(CMAKE_POLICY_VERSION_MINIMUM 3.5) +endif() + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake/Modules") +include(ConfigureVcpkg) + +IF(MR_EMSCRIPTEN_WASM64) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MEMORY64=1") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s MEMORY64=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MEMORY64=1") +ENDIF() + +project(MeshLib_thirdparty CXX) + +# all binaries will be located in ./build/Release/bin +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) + +set(MESHLIB_THIRDPARTY_DIR "${PROJECT_SOURCE_DIR}") +set(MESHLIB_THIRDPARTY_INCLUDE_DIR "include") + +# Inhibit all warning messages +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") + +IF(MR_EMSCRIPTEN) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_BOOST_HEADERS=1") + IF(NOT MR_EMSCRIPTEN_SINGLETHREAD) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + ENDIF() +ENDIF() + +IF(EMSCRIPTEN) + set(INSTALL_GTEST ON) + add_compile_definitions(GTEST_HAS_CXXABI_H_=0) + add_subdirectory(./googletest ./googletest) +ENDIF() + +IF(NOT APPLE AND NOT MR_EMSCRIPTEN) + find_package(OpenVDB 10 COMPONENTS openvdb) + IF(NOT OpenVDB_FOUND) + set(OPENVDB_ENABLE_UNINSTALL OFF) + set(OPENVDB_ENABLE_INSTALL OFF) + set(OPENVDB_CORE_SHARED "ON") + set(OPENVDB_CORE_STATIC "OFF") + set(OPENVDB_BUILD_BINARIES OFF) + set(OPENVDB_BUILD_VDB_PRINT OFF) + set(USE_EXPLICIT_INSTANTIATION OFF) + add_subdirectory(./openvdb/v10/openvdb) + ENDIF() + + find_package(cpr) + IF(NOT cpr_FOUND) + set(CPR_ENABLE_UNINSTALL "OFF") + set(CPR_ENABLE_INSTALL "OFF") + set(CPR_USE_SYSTEM_GTEST "ON") + set(CPR_BUILD_TESTS "OFF") + set(CPR_BUILD_TESTS_SSL "OFF") + set(CPR_FORCE_USE_SYSTEM_CURL ON) + add_subdirectory(./cpr) + ENDIF() + + find_package(nlohmann_json) + if(NOT TARGET nlohmann_json::nlohmann_json) + set(JSON_BuildTests OFF) + set(JSON_Install ON) + add_subdirectory(./nlohmann-json) + endif() + + find_package(httplib) + if(NOT TARGET httplib::httplib) + set(HTTPLIB_TEST OFF) + set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF) + set(HTTPLIB_USE_OPENSSL_IF_AVAILABLE OFF) + set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF) + set(HTTPLIB_USE_ZSTD_IF_AVAILABLE OFF) + add_subdirectory(./cpp-httplib) + endif() + + find_package(PkgConfig) + IF(PkgConfig_FOUND) + pkg_check_modules(tinyxml2 QUIET tinyxml2) + ENDIF() + IF(NOT tinyxml2_FOUND OR tinyxml2_VERSION VERSION_LESS 10) + add_subdirectory(./tinyxml2) + ENDIF() +ENDIF() + +add_subdirectory(./OpenCTM-git ./OpenCTM) + +IF(NOT APPLE) + set(ZLIB_COMPAT OFF CACHE BOOL "") + set(ZLIB_ENABLE_TESTS OFF CACHE BOOL "") + set(ZLIBNG_ENABLE_TESTS OFF CACHE BOOL "") + set(WITH_GTEST OFF CACHE BOOL "") + set(WITH_GZFILEOP OFF CACHE BOOL "") + IF(EMSCRIPTEN) + # Force static: undefined BUILD_SHARED_LIBS makes zlib-ng emit duplicate + # libz-ng.a rules under Emscripten. Restore to undefined (not empty) + # afterwards -- jsoncpp downstream breaks on empty BUILD_SHARED_LIBS. + set(BUILD_SHARED_LIBS OFF) + add_subdirectory(./zlib-ng) + unset(BUILD_SHARED_LIBS) + ELSE() + add_subdirectory(./zlib-ng) + ENDIF() + + option(PHMAP_INSTALL "" ON) + add_subdirectory(./parallel-hashmap) +ENDIF() + +IF(EMSCRIPTEN) + add_subdirectory(./expected ./expected) + + set(GDCM_BUILD_APPLICATIONS OFF) + set(GDCM_BUILD_SHARED_LIBS OFF) + set(GDCM_BUILD_TESTING OFF) + set(GDCM_BUILD_DOCBOOK_MANPAGES OFF) + add_subdirectory(./GDCM) + + set(BUILD_TOOLS OFF CACHE BOOL "") + set(BUILD_REGRESS OFF CACHE BOOL "") + set(BUILD_EXAMPLES OFF CACHE BOOL "") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s USE_ZLIB=1") + set(LIBZIP_DO_INSTALL ON) + add_subdirectory(./libzip) + + set(CMAKE_CXX_FLAGS_BACKUP "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_DISABLE_EXCEPTION_CATCHING=1") + set(JSONCPP_WITH_TESTS OFF) + set(JSONCPP_WITH_POST_BUILD_UNITTEST OFF) + set(BUILD_STATIC_LIBS OFF) + add_subdirectory(./jsoncpp) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BACKUP}") + + add_subdirectory(./fmt) + #install(DIRECTORY fmt/include/fmt DESTINATION ${MESHLIB_THIRDPARTY_INCLUDE_DIR}) + + set(SPDLOG_INSTALL ON) + set(SPDLOG_FMT_EXTERNAL ON) + add_subdirectory(./spdlog) + + option(TBB_TEST "Enable testing" OFF) + set(CMAKE_SYSTEM_PROCESSOR_BACKUP "${CMAKE_SYSTEM_PROCESSOR}") + set(CMAKE_SYSTEM_PROCESSOR "unknown") + add_subdirectory(./onetbb) + set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR_BACKUP}") + install(DIRECTORY onetbb/include/tbb DESTINATION ${MESHLIB_THIRDPARTY_INCLUDE_DIR}) + + add_subdirectory(./tinyxml2) + + set(BUILD_TESTS OFF CACHE BOOL "") + set(BUILD_FUZZERS OFF CACHE BOOL "") + set(BUILD_BENCHMARKS OFF CACHE BOOL "") + set(BUILD_STATIC OFF CACHE BOOL "") + set(BLOSC_INSTALL ON) + add_subdirectory(./c-blosc) +ELSE() # not MR_EMSCRIPTEN + set(BUILD_SHARED_LIBS ON) + + set(E57_GIT_SUBMODULE_UPDATE OFF) + set(E57_XML_PARSER TinyXML2 CACHE STRING "") + add_subdirectory(./libE57Format) +ENDIF() + +find_package(glad) +IF(NOT glad_FOUND) + set(GLAD_INSTALL ON CACHE BOOL "") + set(GLAD_REPRODUCIBLE ON CACHE BOOL "") + add_subdirectory(./glad) +ENDIF() + +IF(NOT MR_EMSCRIPTEN) + set(PYBIND11_INSTALL ON) + # We want to build the stubs in our main `CMakeLists.txt` instead of here. + # It seems to work fine either way, but I'm not comfortable not having the stubs see the customized cmake variables + # that we set in our main `CMakeLists.txt`, such as those influencing the Pybind ABI strings. + # Even though the stubs shouldn't call any Pybind functions right now, they still include the Pybind header. + # Accidentally calling some inline Pybind function in it could have weird effects, I reckon. + # Note that regardless of this setting, the python-version-specific shims always need to be built in our main `CMakeLists.txt`, + # to see our configuration CMake variables. + option(PYBIND11_NONLIMITEDAPI_BUILD_STUBS "" OFF) + add_subdirectory(./mrbind-pybind11) +ENDIF() + +set(TINYGLTF_INSTALL ON) +add_subdirectory(./tinygltf) + +set(WITH_TESTS OFF CACHE BOOL "") +set(WITH_EMBIND OFF CACHE BOOL "") +add_subdirectory(./laz-perf) diff --git a/thirdparty/cmake/CPM.cmake b/thirdparty/cpm/cmake/CPM.cmake similarity index 100% rename from thirdparty/cmake/CPM.cmake rename to thirdparty/cpm/cmake/CPM.cmake diff --git a/thirdparty/common_post_project.cmake b/thirdparty/cpm/common_post_project.cmake similarity index 90% rename from thirdparty/common_post_project.cmake rename to thirdparty/cpm/common_post_project.cmake index 6bb8b9ca45ce..b716db5aed77 100644 --- a/thirdparty/common_post_project.cmake +++ b/thirdparty/cpm/common_post_project.cmake @@ -20,8 +20,8 @@ ENDIF() # CPM.cmake reissues cmake_minimum_required(3.14), so include it after project() to keep that # out of the policy scope the stage files are configured under. -include(${MESHLIB_THIRDPARTY_DIR}/cmake/CPM.cmake) -include(${MESHLIB_THIRDPARTY_DIR}/package-lock.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/cmake/CPM.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/package-lock.cmake) macro(meshlib_add_package name) CPMAddPackage(NAME ${name} ${MESHLIB_PACKAGE_${name}} ${ARGN}) diff --git a/thirdparty/common_pre_project.cmake b/thirdparty/cpm/common_pre_project.cmake similarity index 92% rename from thirdparty/common_pre_project.cmake rename to thirdparty/cpm/common_pre_project.cmake index 9da06a72aa61..f4421531cdca 100644 --- a/thirdparty/common_pre_project.cmake +++ b/thirdparty/cpm/common_pre_project.cmake @@ -13,7 +13,7 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0) set(CMAKE_POLICY_VERSION_MINIMUM 3.5) endif() -set(MESHLIB_THIRDPARTY_DIR "${CMAKE_CURRENT_LIST_DIR}") +get_filename_component(MESHLIB_THIRDPARTY_DIR "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY) set(MESHLIB_THIRDPARTY_INCLUDE_DIR "include") list(APPEND CMAKE_MODULE_PATH "${MESHLIB_THIRDPARTY_DIR}/../cmake/Modules") diff --git a/thirdparty/fetch/CMakeLists.txt b/thirdparty/cpm/fetch/CMakeLists.txt similarity index 100% rename from thirdparty/fetch/CMakeLists.txt rename to thirdparty/cpm/fetch/CMakeLists.txt diff --git a/thirdparty/package-lock.cmake b/thirdparty/cpm/package-lock.cmake similarity index 98% rename from thirdparty/package-lock.cmake rename to thirdparty/cpm/package-lock.cmake index c9009a2daf27..17071df4cdc2 100644 --- a/thirdparty/package-lock.cmake +++ b/thirdparty/cpm/package-lock.cmake @@ -1,7 +1,7 @@ -# Version pins for every third-party library built by thirdparty/stage1 and thirdparty/stage2. +# Version pins for every third-party library built by thirdparty/cpm/stage1 and thirdparty/cpm/stage2. # # Each entry is the CPMAddPackage argument list for one dependency, minus NAME, which the -# caller supplies: the stages via meshlib_add_package(), thirdparty/fetch by appending +# caller supplies: the stages via meshlib_add_package(), thirdparty/cpm/fetch by appending # DOWNLOAD_ONLY YES. Deliberately not CPMDeclarePackage -- a declaration *replaces* the # caller's arguments rather than extending them, which silently drops DOWNLOAD_ONLY. # diff --git a/thirdparty/patches/boost-honor-skip-install-rules.patch b/thirdparty/cpm/patches/boost-honor-skip-install-rules.patch similarity index 100% rename from thirdparty/patches/boost-honor-skip-install-rules.patch rename to thirdparty/cpm/patches/boost-honor-skip-install-rules.patch diff --git a/thirdparty/patches/boost-locale-no-thread.patch b/thirdparty/cpm/patches/boost-locale-no-thread.patch similarity index 100% rename from thirdparty/patches/boost-locale-no-thread.patch rename to thirdparty/cpm/patches/boost-locale-no-thread.patch diff --git a/thirdparty/patches/boost-locale-std-mutex.patch b/thirdparty/cpm/patches/boost-locale-std-mutex.patch similarity index 100% rename from thirdparty/patches/boost-locale-std-mutex.patch rename to thirdparty/cpm/patches/boost-locale-std-mutex.patch diff --git a/thirdparty/patches/clip-config-use-project-name.patch b/thirdparty/cpm/patches/clip-config-use-project-name.patch similarity index 100% rename from thirdparty/patches/clip-config-use-project-name.patch rename to thirdparty/cpm/patches/clip-config-use-project-name.patch diff --git a/thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch b/thirdparty/cpm/patches/libjpeg-turbo-allow-add-subdirectory.patch similarity index 100% rename from thirdparty/patches/libjpeg-turbo-allow-add-subdirectory.patch rename to thirdparty/cpm/patches/libjpeg-turbo-allow-add-subdirectory.patch diff --git a/thirdparty/stage1/CMakeLists.txt b/thirdparty/cpm/stage1/CMakeLists.txt similarity index 100% rename from thirdparty/stage1/CMakeLists.txt rename to thirdparty/cpm/stage1/CMakeLists.txt diff --git a/thirdparty/stage2/CMakeLists.txt b/thirdparty/cpm/stage2/CMakeLists.txt similarity index 100% rename from thirdparty/stage2/CMakeLists.txt rename to thirdparty/cpm/stage2/CMakeLists.txt diff --git a/thirdparty/licenses/manifest.json b/thirdparty/licenses/manifest.json index e083a6c83095..03fc932ce7d3 100644 --- a/thirdparty/licenses/manifest.json +++ b/thirdparty/licenses/manifest.json @@ -9,10 +9,9 @@ "and recomputes the version from the source below, FAILING if it drifts, so a human", "re-checks the license on every bump. To re-pin after verifying the texts are still", "correct: run the script with --update-versions. Inclusion authority:", - "doxygen/general_pages/ThirdpartyList.dox, reconciled against", - "thirdparty/package-lock.cmake, .gitmodules and thirdparty/vcpkg/vcpkg.json.", - "source.type: cpm=GIT_TAG or URL pinned in thirdparty/package-lock.cmake |", - "submodule=gitlink SHA | vcpkg-overlay=port version+port-version |", + "doxygen/general_pages/ThirdpartyList.dox, reconciled against .gitmodules and", + "thirdparty/vcpkg/vcpkg.json.", + "source.type: submodule=gitlink SHA | vcpkg-overlay=port version+port-version |", "vcpkg-registry=baseline version of each listed port (sound: vcpkg.json has no", "per-port overrides), so a registry bump only implicates the components whose own", "ports moved |", @@ -72,10 +71,10 @@ "license": "MPL-2.0", "upstream": "https://eigen.tuxfamily.org", "source": { - "type": "cpm", - "package": "eigen" + "type": "submodule", + "path": "thirdparty/eigen" }, - "version": "5.0.1" + "version": "bc3b39870ecb690a623a3f49149a358b95c5781d" }, { "id": "spdlog", @@ -85,8 +84,8 @@ "license": "MIT", "upstream": "https://github.com/gabime/spdlog", "source": { - "type": "cpm", - "package": "spdlog" + "type": "submodule", + "path": "thirdparty/spdlog" }, "version": "6fa36017cfd5731d617e1a934f0e5ea9c4445b13" }, @@ -98,8 +97,8 @@ "license": "MIT", "upstream": "https://github.com/fmtlib/fmt", "source": { - "type": "cpm", - "package": "fmt" + "type": "submodule", + "path": "thirdparty/fmt" }, "version": "47a66c5eccc0cce71ad81b4a681a2032d86ca951" }, @@ -129,8 +128,8 @@ "license": "MIT", "upstream": "https://github.com/open-source-parsers/jsoncpp", "source": { - "type": "cpm", - "package": "jsoncpp" + "type": "submodule", + "path": "thirdparty/jsoncpp" }, "version": "42e892d96e47b1f6e29844cc705e148ec4856448" }, @@ -142,10 +141,10 @@ "license": "BSD-3-Clause", "upstream": "https://libzip.org", "source": { - "type": "cpm", - "package": "libzip" + "type": "submodule", + "path": "thirdparty/libzip" }, - "version": "v1.11.4" + "version": "6f8a0cdd24a0dc6cce9dac4a7679da784ab124ea" }, { "id": "zlib-ng", @@ -155,8 +154,8 @@ "license": "Zlib", "upstream": "https://github.com/zlib-ng/zlib-ng", "source": { - "type": "cpm", - "package": "zlib-ng" + "type": "submodule", + "path": "thirdparty/zlib-ng" }, "version": "860e4cff7917d93f54f5d7f0bc1d0e8b1a3cb988" }, @@ -185,8 +184,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/uxlfoundation/oneTBB", "source": { - "type": "cpm", - "package": "onetbb" + "type": "submodule", + "path": "thirdparty/onetbb" }, "version": "12ceae12138af08845b3e8c369b24527346fe99e" }, @@ -198,10 +197,10 @@ "license": "Apache-2.0", "upstream": "https://github.com/greg7mdp/parallel-hashmap", "source": { - "type": "cpm", - "package": "parallel-hashmap" + "type": "submodule", + "path": "thirdparty/parallel-hashmap" }, - "version": "v2.0.0" + "version": "2ec799017610ef831f4dc29c21fb3cce7e4a19b9" }, { "id": "expected", @@ -211,8 +210,8 @@ "license": "CC0-1.0", "upstream": "https://github.com/TartanLlama/expected", "source": { - "type": "cpm", - "package": "expected" + "type": "submodule", + "path": "thirdparty/expected" }, "version": "d6e1fcc766b725f196d7f58097d72f8cfab4d56a" }, @@ -224,10 +223,10 @@ "license": "Apache-2.0", "upstream": "https://github.com/Mbed-TLS/mbedtls", "source": { - "type": "cpm", - "package": "mbedtls" + "type": "submodule", + "path": "thirdparty/mbedtls" }, - "version": "v3.5.0" + "version": "1ec69067fa1351427f904362c1221b31538c8b57" }, { "id": "libHaru", @@ -255,8 +254,8 @@ "license": "BSD-3-Clause AND IJG", "upstream": "https://libjpeg-turbo.org", "source": { - "type": "cpm", - "package": "libjpeg-turbo" + "type": "submodule", + "path": "thirdparty/libjpeg-turbo" }, "version": "7fa4b5b762c9a99b46b0b7838f5fd55071b92ea5" }, @@ -300,10 +299,10 @@ "license": "MIT", "upstream": "https://github.com/syoyo/tinygltf", "source": { - "type": "cpm", - "package": "tinygltf" + "type": "submodule", + "path": "thirdparty/tinygltf" }, - "version": "v2.8.2" + "version": "98adbb3fb32850bb4918cc147a2d2428b011ad91" }, { "id": "OpenCTM", @@ -313,8 +312,8 @@ "license": "Zlib", "upstream": "https://sourceforge.net/projects/openctm/", "source": { - "type": "cpm", - "package": "OpenCTM" + "type": "submodule", + "path": "thirdparty/OpenCTM-git" }, "version": "2b444a4c70c432c1f4990fb32b0fcb11d0d81aad" }, @@ -326,8 +325,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/hobuinc/laz-perf", "source": { - "type": "cpm", - "package": "laz-perf" + "type": "submodule", + "path": "thirdparty/laz-perf" }, "version": "05ea01542e5c4417c05e7222f920e06276c79324" }, @@ -339,8 +338,8 @@ "license": "BSL-1.0", "upstream": "https://github.com/asmaloney/libE57Format", "source": { - "type": "cpm", - "package": "libE57Format" + "type": "submodule", + "path": "thirdparty/libE57Format" }, "version": "46eb0d02e00a6b0aeaee3e6655328b78c7e07b5b" }, @@ -352,8 +351,8 @@ "license": "Zlib", "upstream": "https://leethomason.github.io/tinyxml2/", "source": { - "type": "cpm", - "package": "tinyxml2" + "type": "submodule", + "path": "thirdparty/tinyxml2" }, "version": "321ea883b7190d4e85cae5512a12e5eaa8f8731f" }, @@ -367,8 +366,8 @@ "license": "MIT", "upstream": "https://github.com/nlohmann/json", "source": { - "type": "cpm", - "package": "nlohmann-json" + "type": "submodule", + "path": "thirdparty/nlohmann-json" }, "version": "3946872265598aed5a7aea68cad4d9d1f168bd4b" }, @@ -428,8 +427,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/AcademySoftwareFoundation/openvdb", "source": { - "type": "cpm", - "package": "openvdb" + "type": "submodule", + "path": "thirdparty/openvdb/v10/openvdb" }, "version": "87a508ca48a69f06d149be6cb0d8289fc1314f72" }, @@ -441,10 +440,10 @@ "license": "BSD-3-Clause", "upstream": "https://sourceforge.net/projects/gdcm/", "source": { - "type": "cpm", - "package": "GDCM" + "type": "submodule", + "path": "thirdparty/GDCM" }, - "version": "v3.2.6" + "version": "9c71b163416130ffdec26534444e9b85fcf0682a" }, { "id": "c-blosc", @@ -454,10 +453,10 @@ "license": "BSD-3-Clause", "upstream": "https://github.com/Blosc/c-blosc", "source": { - "type": "cpm", - "package": "c-blosc" + "type": "submodule", + "path": "thirdparty/c-blosc" }, - "version": "v1.21.6" + "version": "616f4b7343a8479f7e71dd3d7025bd92c9a6bbd0" }, { "id": "CUDA", @@ -479,8 +478,8 @@ "license": "MIT", "upstream": "https://github.com/Dav1dde/glad", "source": { - "type": "cpm", - "package": "glad" + "type": "submodule", + "path": "thirdparty/glad" }, "version": "e86f90457371c6233053bacf0d6f486a51ddcd67" }, @@ -523,10 +522,10 @@ "license": "MIT", "upstream": "https://github.com/libcpr/cpr", "source": { - "type": "cpm", - "package": "cpr" + "type": "submodule", + "path": "thirdparty/cpr" }, - "version": "1.14.2" + "version": "f091b2c061b307ee89b164c39976fc9202a1c79d" }, { "id": "libcurl", @@ -549,8 +548,8 @@ "license": "MIT", "upstream": "https://github.com/dacap/clip", "source": { - "type": "cpm", - "package": "clip" + "type": "submodule", + "path": "thirdparty/clip" }, "version": "7f2e86ab9690f7df88440002083edd257f87bc58" }, @@ -634,8 +633,8 @@ "license": "Apache-2.0", "upstream": "https://github.com/MeshInspector/fastmcpp", "source": { - "type": "cpm", - "package": "fastmcpp" + "type": "submodule", + "path": "thirdparty/fastmcpp" }, "version": "9aa1a179f886f6d098f67693e18ee4778db924b7" }, @@ -648,8 +647,8 @@ "license": "MIT", "upstream": "https://github.com/yhirose/cpp-httplib", "source": { - "type": "cpm", - "package": "cpp-httplib" + "type": "submodule", + "path": "thirdparty/cpp-httplib" }, "version": "b045ee7f6b434a85fd011e96e28c6d4abfb18788" }, From 36538dc00ea445317206adf68dfbe1c99e261747 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Fri, 4 Sep 2026 09:17:31 +0200 Subject: [PATCH 14/19] Customize install location --- .gitignore | 1 + scripts/build_cpm_thirdparty.sh | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 1502c96ce1d5..9051fadb81fd 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ compile_commands.json /scripts/mrbind/msys2_packages /scripts/mrbind/msys2_pacman_install.log /vcpkg_installed +/installed diff --git a/scripts/build_cpm_thirdparty.sh b/scripts/build_cpm_thirdparty.sh index ee7bbc248219..3054e989e20a 100755 --- a/scripts/build_cpm_thirdparty.sh +++ b/scripts/build_cpm_thirdparty.sh @@ -1,7 +1,7 @@ #!/bin/bash # This script builds thirdparty with CPM from `thirdparty/cpm` -# Output libraries are stored in `./lib` directory +# Usage: ./scripts/build_cpm_thirdparty.sh [INSTALL_PREFIX] # exit if any command failed set -eo pipefail @@ -17,7 +17,10 @@ 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="${MESHLIB_THIRDPARTY_ROOT_DIR:-${BASE_DIR}}" + +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" @@ -128,7 +131,7 @@ 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:-${MESHLIB_THIRDPARTY_ROOT_DIR}/thirdparty_sources}" +export CPM_SOURCE_CACHE="${CPM_SOURCE_CACHE:-${BASE_DIR}/thirdparty_sources}" # build echo "Starting build..." @@ -145,4 +148,4 @@ if [ "${MR_EMSCRIPTEN}" == "ON" ]; then fi popd -printf "\rThirdparty build script successfully finished. Required libs located in ./lib folder. You could run ./scripts/build_source.sh\n\n" +printf "\rThirdparty build script successfully finished. Required libs located in ${MESHLIB_THIRDPARTY_ROOT_DIR} folder. You could run ./scripts/build_source.sh\n\n" From bf023843100be901fb3b9b5ec284eb213aede6f5 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Fri, 4 Sep 2026 09:44:12 +0200 Subject: [PATCH 15/19] Fix libE57Format usage --- source/MRIOExtras/CMakeLists.txt | 3 +++ thirdparty/cpm/package-lock.cmake | 2 +- thirdparty/libE57Format | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/MRIOExtras/CMakeLists.txt b/source/MRIOExtras/CMakeLists.txt index 7daa71194716..04b749d7f480 100644 --- a/source/MRIOExtras/CMakeLists.txt +++ b/source/MRIOExtras/CMakeLists.txt @@ -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) diff --git a/thirdparty/cpm/package-lock.cmake b/thirdparty/cpm/package-lock.cmake index 17071df4cdc2..884fd7249f0f 100644 --- a/thirdparty/cpm/package-lock.cmake +++ b/thirdparty/cpm/package-lock.cmake @@ -93,7 +93,7 @@ set(MESHLIB_PACKAGE_laz-perf set(MESHLIB_PACKAGE_libE57Format GIT_REPOSITORY https://github.com/MeshInspector/libE57Format - GIT_TAG 46eb0d02e00a6b0aeaee3e6655328b78c7e07b5b + GIT_TAG 1816f72de58b27208a8f03c7213ba4039517402a ) set(MESHLIB_PACKAGE_libjpeg-turbo diff --git a/thirdparty/libE57Format b/thirdparty/libE57Format index 46eb0d02e00a..1816f72de58b 160000 --- a/thirdparty/libE57Format +++ b/thirdparty/libE57Format @@ -1 +1 @@ -Subproject commit 46eb0d02e00a6b0aeaee3e6655328b78c7e07b5b +Subproject commit 1816f72de58b27208a8f03c7213ba4039517402a From 744224aa544eab94db85d5e01812716ab925ddbd Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Fri, 4 Sep 2026 09:55:05 +0200 Subject: [PATCH 16/19] Add fetch script --- scripts/fetch_cpm_thirdparty.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100755 scripts/fetch_cpm_thirdparty.sh diff --git a/scripts/fetch_cpm_thirdparty.sh b/scripts/fetch_cpm_thirdparty.sh new file mode 100755 index 000000000000..b9ad72050c56 --- /dev/null +++ b/scripts/fetch_cpm_thirdparty.sh @@ -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_=` 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}" From 2aaeee577b0ec8c737064d992c76eb48755e9f40 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Fri, 4 Sep 2026 09:57:40 +0200 Subject: [PATCH 17/19] Update licenses --- thirdparty/licenses/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/licenses/manifest.json b/thirdparty/licenses/manifest.json index 03fc932ce7d3..f08f0c2de2cc 100644 --- a/thirdparty/licenses/manifest.json +++ b/thirdparty/licenses/manifest.json @@ -341,7 +341,7 @@ "type": "submodule", "path": "thirdparty/libE57Format" }, - "version": "46eb0d02e00a6b0aeaee3e6655328b78c7e07b5b" + "version": "1816f72de58b27208a8f03c7213ba4039517402a" }, { "id": "tinyxml2", From 6d3af628744531f5c98d87014c0d24134e059aa0 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Fri, 4 Sep 2026 15:46:57 +0200 Subject: [PATCH 18/19] Share base Emscripten C++ flags --- cmake/Modules/ConfigureEmscripten.cmake | 37 ++++++------------- cmake/Modules/DefaultEmscriptenOptions.cmake | 39 ++++++++++++++++++++ cmake/Modules/DefaultOptions.cmake | 13 +++---- scripts/build_cpm_thirdparty.sh | 13 ------- thirdparty/cpm/common_post_project.cmake | 8 +--- thirdparty/cpm/common_pre_project.cmake | 9 ++--- 6 files changed, 60 insertions(+), 59 deletions(-) create mode 100644 cmake/Modules/DefaultEmscriptenOptions.cmake diff --git a/cmake/Modules/ConfigureEmscripten.cmake b/cmake/Modules/ConfigureEmscripten.cmake index f7020efdfa14..b9036bcbc541 100644 --- a/cmake/Modules/ConfigureEmscripten.cmake +++ b/cmake/Modules/ConfigureEmscripten.cmake @@ -1,5 +1,5 @@ # reference: https://github.com/emscripten-core/emscripten/blob/main/src/settings.js -string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS +string(JOIN " " MESHLIB_EMSCRIPTEN_PORT_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" @@ -12,18 +12,7 @@ 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 " " MESHLIB_EMSCRIPTEN_LINK_FLAGS "-s ALLOW_MEMORY_GROWTH=1" "-s LLD_REPORT_UNDEFINED=1" "-s STACK_SIZE=1048576" # required for GDCM @@ -31,18 +20,12 @@ string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS 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(MESHLIB_EMSCRIPTEN_LINK_FLAGS "${MESHLIB_EMSCRIPTEN_LINK_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(MESHLIB_EMSCRIPTEN_LINK_FLAGS "${MESHLIB_EMSCRIPTEN_LINK_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" - ) - # uncomment to enable source map for debugging in browsers (slow) #set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gsource-map") @@ -51,7 +34,7 @@ ELSE() ELSE() set(MAXIMUM_MEMORY 4GB) ENDIF() - string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} + string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS ${MESHLIB_EMSCRIPTEN_LINK_FLAGS} "-s ENVIRONMENT=web,worker,node" #"-pthread" "-s PTHREAD_POOL_SIZE_STRICT=0" @@ -61,7 +44,7 @@ ELSE() ENDIF() IF(MESHLIB_BUILD_MRVIEWER) - string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} + string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS ${MESHLIB_EMSCRIPTEN_LINK_FLAGS} "-s EXPORTED_RUNTIME_METHODS=[ccall]" "-s USE_WEBGL2=1" "-s USE_GLFW=3" @@ -69,7 +52,7 @@ IF(MESHLIB_BUILD_MRVIEWER) ) IF(NOT MR_DISABLE_EMSCRIPTEN_ASYNCIFY) - string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} + string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS ${MESHLIB_EMSCRIPTEN_LINK_FLAGS} "-s ASYNCIFY" # FIXME: comment required "-Wno-limited-postlink-optimizations" @@ -77,5 +60,7 @@ IF(MESHLIB_BUILD_MRVIEWER) 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(JOIN " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${MESHLIB_EMSCRIPTEN_PORT_FLAGS}) +string(JOIN " " CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} ${MESHLIB_EMSCRIPTEN_LINK_FLAGS}) +string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS} ${MESHLIB_EMSCRIPTEN_PORT_FLAGS}) +string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} ${MESHLIB_EMSCRIPTEN_LINK_FLAGS}) diff --git a/cmake/Modules/DefaultEmscriptenOptions.cmake b/cmake/Modules/DefaultEmscriptenOptions.cmake new file mode 100644 index 000000000000..3e30d4d2e501 --- /dev/null +++ b/cmake/Modules/DefaultEmscriptenOptions.cmake @@ -0,0 +1,39 @@ +# 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" + # look https://github.com/emscripten-core/emscripten/issues/8287 + "-Wno-pthreads-mem-growth" + ) + 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() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}") + 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}") +endif() diff --git a/cmake/Modules/DefaultOptions.cmake b/cmake/Modules/DefaultOptions.cmake index 5e6368f3f321..880c16e843ec 100644 --- a/cmake/Modules/DefaultOptions.cmake +++ b/cmake/Modules/DefaultOptions.cmake @@ -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 "$<$:Embedded>") -ENDIF() \ No newline at end of file +ENDIF() + +if(MR_EMSCRIPTEN) + include(DefaultEmscriptenOptions) +endif() diff --git a/scripts/build_cpm_thirdparty.sh b/scripts/build_cpm_thirdparty.sh index 3054e989e20a..5c60ce2da3ce 100755 --- a/scripts/build_cpm_thirdparty.sh +++ b/scripts/build_cpm_thirdparty.sh @@ -108,19 +108,6 @@ if [ "${MR_EMSCRIPTEN}" == "ON" ]; then -D MR_EMSCRIPTEN_WASM64=${MR_EMSCRIPTEN_WASM64} \ -D MR_EMSCRIPTEN_WASM2023=${MR_EMSCRIPTEN_WASM2023} \ " - if [[ ${MR_EMSCRIPTEN_SINGLETHREAD} == 0 ]] ; then - CFLAGS="${CFLAGS} -pthread" - CXXFLAGS="${CFLAGS} -pthread" - fi - if [[ ${MR_EMSCRIPTEN_WASM64} == 1 ]] ; then - CFLAGS="${CFLAGS} -s MEMORY64=1" - CXXFLAGS="${CFLAGS} -s MEMORY64=1" - LDFLAGS="${LDFLAGS} -s MEMORY64=1" - fi - if [[ ${MR_EMSCRIPTEN_WASM2023} == 1 ]] ; then - CFLAGS="${CFLAGS} -msimd128 -mbulk-memory -mnontrapping-fptoint -msse4.2" - CXXFLAGS="${CXXFLAGS} -msimd128 -mbulk-memory -mnontrapping-fptoint -msse4.2" - fi fi if [[ $OSTYPE == 'darwin'* ]]; then diff --git a/thirdparty/cpm/common_post_project.cmake b/thirdparty/cpm/common_post_project.cmake index b716db5aed77..99472d259cf2 100644 --- a/thirdparty/cpm/common_post_project.cmake +++ b/thirdparty/cpm/common_post_project.cmake @@ -10,13 +10,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") -IF(MR_EMSCRIPTEN) +if(EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_BOOST_HEADERS=1") - IF(NOT MR_EMSCRIPTEN_SINGLETHREAD) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") - ENDIF() -ENDIF() +endif() # CPM.cmake reissues cmake_minimum_required(3.14), so include it after project() to keep that # out of the policy scope the stage files are configured under. diff --git a/thirdparty/cpm/common_pre_project.cmake b/thirdparty/cpm/common_pre_project.cmake index f4421531cdca..f16cbb72b2d5 100644 --- a/thirdparty/cpm/common_pre_project.cmake +++ b/thirdparty/cpm/common_pre_project.cmake @@ -18,9 +18,6 @@ set(MESHLIB_THIRDPARTY_INCLUDE_DIR "include") list(APPEND CMAKE_MODULE_PATH "${MESHLIB_THIRDPARTY_DIR}/../cmake/Modules") include(ConfigureVcpkg) - -IF(MR_EMSCRIPTEN_WASM64) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s MEMORY64=1") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s MEMORY64=1") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s MEMORY64=1") -ENDIF() +if(MR_EMSCRIPTEN) + include(DefaultEmscriptenOptions) +endif() From b7f37b49c92b8b4c53ad4d79b7be678125a73020 Mon Sep 17 00:00:00 2001 From: Artur Sharafutdinov Date: Fri, 4 Sep 2026 20:00:55 +0200 Subject: [PATCH 19/19] Fix Wasm build --- cmake/Modules/ConfigureEmscripten.cmake | 28 ++++++++++++-------- cmake/Modules/DefaultEmscriptenOptions.cmake | 8 +++--- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/cmake/Modules/ConfigureEmscripten.cmake b/cmake/Modules/ConfigureEmscripten.cmake index b9036bcbc541..d8901aa898bd 100644 --- a/cmake/Modules/ConfigureEmscripten.cmake +++ b/cmake/Modules/ConfigureEmscripten.cmake @@ -1,5 +1,5 @@ # reference: https://github.com/emscripten-core/emscripten/blob/main/src/settings.js -string(JOIN " " MESHLIB_EMSCRIPTEN_PORT_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" @@ -12,7 +12,7 @@ string(JOIN " " MESHLIB_EMSCRIPTEN_PORT_FLAGS "-sUSE_ZLIB" # TODO: make optional ) -string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS +string(JOIN " " EXTRA_EXE_LINKER_FLAGS "-s ALLOW_MEMORY_GROWTH=1" "-s LLD_REPORT_UNDEFINED=1" "-s STACK_SIZE=1048576" # required for GDCM @@ -20,12 +20,15 @@ string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS option(MR_EMSCRIPTEN_MIMALLOC "Use mimalloc allocator (-s MALLOC=mimalloc) for Emscripten builds" ON) IF(MR_EMSCRIPTEN_MIMALLOC) - set(MESHLIB_EMSCRIPTEN_LINK_FLAGS "${MESHLIB_EMSCRIPTEN_LINK_FLAGS} -s MALLOC=mimalloc") + set(EXTRA_EXE_LINKER_FLAGS "${EXTRA_EXE_LINKER_FLAGS} -s MALLOC=mimalloc") ENDIF() IF(MR_EMSCRIPTEN_SINGLETHREAD) - set(MESHLIB_EMSCRIPTEN_LINK_FLAGS "${MESHLIB_EMSCRIPTEN_LINK_FLAGS} -s ENVIRONMENT=web,node") + set(EXTRA_EXE_LINKER_FLAGS "${EXTRA_EXE_LINKER_FLAGS} -s ENVIRONMENT=web,node") ELSE() + # 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") @@ -34,7 +37,7 @@ ELSE() ELSE() set(MAXIMUM_MEMORY 4GB) ENDIF() - string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS ${MESHLIB_EMSCRIPTEN_LINK_FLAGS} + string(JOIN " " EXTRA_EXE_LINKER_FLAGS ${EXTRA_EXE_LINKER_FLAGS} "-s ENVIRONMENT=web,worker,node" #"-pthread" "-s PTHREAD_POOL_SIZE_STRICT=0" @@ -44,7 +47,7 @@ ELSE() ENDIF() IF(MESHLIB_BUILD_MRVIEWER) - string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS ${MESHLIB_EMSCRIPTEN_LINK_FLAGS} + string(JOIN " " EXTRA_EXE_LINKER_FLAGS ${EXTRA_EXE_LINKER_FLAGS} "-s EXPORTED_RUNTIME_METHODS=[ccall]" "-s USE_WEBGL2=1" "-s USE_GLFW=3" @@ -52,7 +55,7 @@ IF(MESHLIB_BUILD_MRVIEWER) ) IF(NOT MR_DISABLE_EMSCRIPTEN_ASYNCIFY) - string(JOIN " " MESHLIB_EMSCRIPTEN_LINK_FLAGS ${MESHLIB_EMSCRIPTEN_LINK_FLAGS} + string(JOIN " " EXTRA_EXE_LINKER_FLAGS ${EXTRA_EXE_LINKER_FLAGS} "-s ASYNCIFY" # FIXME: comment required "-Wno-limited-postlink-optimizations" @@ -60,7 +63,10 @@ IF(MESHLIB_BUILD_MRVIEWER) ENDIF() ENDIF() -string(JOIN " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${MESHLIB_EMSCRIPTEN_PORT_FLAGS}) -string(JOIN " " CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} ${MESHLIB_EMSCRIPTEN_LINK_FLAGS}) -string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS} ${MESHLIB_EMSCRIPTEN_PORT_FLAGS}) -string(JOIN " " MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS ${MESHLIB_EMSCRIPTEN_EXE_LINKER_FLAGS} ${MESHLIB_EMSCRIPTEN_LINK_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) diff --git a/cmake/Modules/DefaultEmscriptenOptions.cmake b/cmake/Modules/DefaultEmscriptenOptions.cmake index 3e30d4d2e501..744fb16326a5 100644 --- a/cmake/Modules/DefaultEmscriptenOptions.cmake +++ b/cmake/Modules/DefaultEmscriptenOptions.cmake @@ -13,8 +13,6 @@ if(MR_EMSCRIPTEN) if(NOT MR_EMSCRIPTEN_SINGLETHREAD) string(JOIN " " MESHLIB_EMSCRIPTEN_CXX_FLAGS ${MESHLIB_EMSCRIPTEN_CXX_FLAGS} "-pthread" - # look https://github.com/emscripten-core/emscripten/issues/8287 - "-Wno-pthreads-mem-growth" ) endif() @@ -33,7 +31,7 @@ if(MR_EMSCRIPTEN) ) endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MESHLIB_EMSCRIPTEN_CXX_FLAGS}") - 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_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()