Skip to content

macOS: Add vcpkg build support - #6913

Merged
oitel merged 28 commits into
masterfrom
feature/vcpkg_macos
Oct 1, 2026
Merged

oitel merged 28 commits into
masterfrom
feature/vcpkg_macos

Conversation

@oitel

@oitel oitel commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@oitel
oitel marked this pull request as ready for review September 24, 2026 07:45
@oitel oitel changed the title macOS: Add vcpkg build macOS: Add vcpkg build support Sep 24, 2026
-DPYBIND11_NONLIMITEDAPI_INTERNALS_VERSION=5
-DPYBIND11_NONLIMITEDAPI_COMPILER_TYPE_STRING=_meshlib
-DPYBIND11_NONLIMITEDAPI_BUILD_ABI_STRING=_meshlib
-DPYBIND11_NONLIMITEDAPI_SHIM_INSTALL_DIR=lib/meshlib

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PYBIND11_NONLIMITEDAPI_SHIM_INSTALL_DIR doesn't exist in mrbind-pybind11 at the pinned REF f11e5ce81 (which is also the current head of non-limited-api and the submodule commit): the shim's install(TARGETS ...) in source/non_limited_api/CMakeLists.txt hardcodes LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} / RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}. So this option is silently ignored (only an unused-variable warning), the shim still lands in lib/ (bin/ on Windows) rather than lib/meshlib, and the port-version 1 -> 3 bump just invalidates the binary caches. Looks like the mrbind-pybind11 change adding this option is missing, and REF/SHA512 + the submodule need bumping to it.

Comment thread meshlib-config.cmake.in Outdated
@PACKAGE_INIT@

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Modules")
list(PREPEND CMAKE_PREFIX_PATH "${PACKAGE_PREFIX_DIR}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This runs in the consumer's scope for every MeshLib install (not only the macOS vcpkg framework), and PREPEND puts the MeshLib prefix ahead of the consumer's own CMAKE_PREFIX_PATH for all subsequent find_package calls. E.g. with the .deb (prefix /usr/local), a consumer configured with -DCMAKE_PREFIX_PATH=/opt/mydeps that calls find_package(MeshLib) and then find_package(fmt) will now get the /usr/local fmt instead of /opt/mydeps. Checked with a minimal config + consumer: PREPEND picks the package under the MeshLib prefix, APPEND picks the consumer's. Could this be APPEND (or limited to the Apple/vcpkg package)?

@Grantim Grantim left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ia there a way to unify build_source + build_vcpkg_source and build_thirdparty + build_vcpkg_thirdparty? to have two scripts instead of four? (does this unification make sense at all?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this script support windows too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shell scripts aren't called on Windows. Also, on Windows uname -s might return a wide variety of values.

@MaxRayskiy MaxRayskiy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on Apple Silicon: developer build and consumer .pkg

Environment

Machine Apple M4, 24 GB, macOS 15.7.1
Compiler Apple clang 17.0.0 (clang-1700.0.13.5) from Command Line Tools, SDK 15.5, no Xcode.app
CMake / Ninja 4.4.0 / Homebrew ninja
vcpkg tag 2026.07.29, tool 2026-07-27, triplet arm64-osx-meshlib, manifest mode
Python 3.12.13 from vcpkg, picked up automatically by FindPython
Homebrew arm64 at /opt/homebrew, plus an Intel Homebrew at /usr/local
Not built MRBind Python bindings, generated C bindings

What I ran

  1. scripts/build_vcpkg_thirdparty.sh with VCPKG_MAX_CONCURRENCY=5
  2. MESHLIB_BUILD_RELEASE=ON scripts/build_vcpkg_source.sh: 699 targets in 3 min. See the note below, it did not pass as-is.
  3. MRTest: 420 passed. MeshViewer -tryHidden -noEventLoop -unloadPluginsAtEnd exits clean; DYLD_PRINT_LIBRARIES shows all 82 third-party libraries coming from vcpkg_installed, none from Homebrew.
  4. scripts/distribution_vcpkg_macos.sh v0.0.0.0: 90 MiB installer. The current Homebrew-based arm64 package is 73 MiB.
  5. installer -pkg MeshLib_.pkg -target CurrentUserHomeDirectory, then meshconv and MeshViewer from the framework: both load only framework and system libraries. All 318 shipped binaries verify as ad hoc signed. Minimum OS is 12.0 for the vcpkg libraries and 12.7 for ours.
  6. examples/cpp-examples with a plain find_package(MeshLib CONFIG REQUIRED): all 30 build and run. Every *_DIR resolves inside the framework even though Homebrew's boost, tbb, fmt, spdlog and jsoncpp are installed here. It also passes with -DCMAKE_IGNORE_PREFIX_PATH="/opt/homebrew;/usr/local", so the package really needs no brew step. C examples are not applicable to my build.
  7. MESHLIB_USE_VCPKG=ON VCPKG_MANIFEST_MODE=ON scripts/build_source.sh on the same build directory: no rebuild at all, so the two source scripts are equivalent. That supports Grantim's question about collapsing them.

Warning

Step 2 as committed failed for me linking libMRVoxels with undefined openvdb::v13_0abi13 symbols.
Apple clang searches /usr/local/include before every -isystem path when no -isysroot is given, CMake 4 leaves CMAKE_OSX_SYSROOT empty, and my Intel Homebrew has OpenVDB 13 under /usr/local. This fixed it:

MR_CMAKE_OPTIONS="-D CMAKE_OSX_SYSROOT=$(xcrun --show-sdk-path)" scripts/build_vcpkg_source.sh

Anyone with an Intel Homebrew or anything else in /usr/local/include will hit this. Suggest setting the sysroot in CMakeLists.txt next to the deployment target, and VCPKG_OSX_SYSROOT in the two osx triplets so the ports get it too.

Package content

distribution_vcpkg_macos.sh copies the entire vcpkg tree and only removes pkgconfig, tools and __pycache__. What ends up in the framework:

Location Finding
include/, 171 MB 16,173 third-party headers, including 5,622 OpenCASCADE, 469 Xerces, 142 OpenSSL and 214 Python headers that are private dependencies
share/, 31 MB 523 CMake config files we need, plus 141 vcpkg_abi_info.txt, 141 vcpkg.spdx.json, 134 vcpkg-spdx-resources.json and 104 usage files that are vcpkg bookkeeping
src/, etc/ gtest sources, and an OpenSSL config skeleton that libcrypto never reads (OPENSSLDIR is /etc/ssl)
AppleDouble sidecars a ._name entry per file, because cp -a keeps the com.apple.provenance xattr and pkgbuild encodes it
Build paths 63 modules in lib/python3.12/lib-dynload carry an LC_RPATH pointing at the builder's vcpkg_installed path; vcpkg's rpath fixup skips this directory. No functional impact (imports still resolve through libpython's @loader_path rpath), but it is a foreign absolute path in a shipped product. 70 of 303 vcpkg dylibs also embed the builder's buildtrees paths via assert macros.

Summary

  • Step 2 link failure (headers from /usr/local shadowing vcpkg's, not a dependency conflict): I will fix it on my side in #6448
  • Package contents: mb create a separate issue to determine explicitly what do we ship in our macos pkgs?

@oitel
oitel merged commit aa31ab6 into master Oct 1, 2026
32 checks passed
@oitel
oitel deleted the feature/vcpkg_macos branch October 1, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants