Skip to content

Re-add support for macOS#2019

Merged
servantftransperfect merged 47 commits intoalicevision:developfrom
philippremy:bits/macos-infra
Apr 20, 2026
Merged

Re-add support for macOS#2019
servantftransperfect merged 47 commits intoalicevision:developfrom
philippremy:bits/macos-infra

Conversation

@philippremy
Copy link
Copy Markdown
Contributor

@philippremy philippremy commented Oct 30, 2025

Project support for macOS

This is now ready to be merged ^^.

I know that these look like some heavy changes, but I believe that I did not break any Windows/Linux infrastructure. I tried my best to do CI on both Windows and Linux, and at least with the official GitHub CI, they appeared to work. Compiling embedded dependencies on Linux works as expected, if you don't attempt to build an embedded Assimp - but that issue was already present before (on recent GCCs, one header is missing a #include <cstdint>, which is a one-line fix).

Overview of changes

Each commit has its own description on what changed and why that change is required in my opinion. But as a quick overview:

  • OFA: The whole OptimizeForArchitecture infrastructure has been reworked. Previously, only x86_64 was properly supported, now there is very solid arm/arm64, expanded x86_64 and rudimentary ppc support.
  • Dependencies: Various embedded dependency version liftings - all changes here appear ABI and API compatible, but mainly solve build issues on macOS present in the older versions (see the individual commit messages). This does not raise the minimum versions required globally, so the current minimum dependency rules still apply.
  • macOS bundler: I wrote a small Python tool for creating a standalone bundle on macOS. This allows to create fully redistributable packages that do not depend on libraries other than those provided by macOS itself.
  • Configuration variables: When building embedded dependencies, only a small subset of CMake variables was passed through to the actual AliceVision subproject (/src). Now the user can overwrite all variables properly by passing them on the CMake CLI (backwards-comparible).
  • Remove BLAS/LAPACK and Suitesparse on macOS: Apple provides Accelerate.framework, which Ceres can use instead of Suitesparse. This lifts the requirement for a Fortran compiler on macOS and drastically reduces compilation times and bundle size. When running the unit tests I did not notice any performance differences.
  • CUDA: As CUDA is completely unsupported on Apple platforms, all related functionality is properly guarded behind conditional checks in the build infrastructure.
  • Cross-compiling: As cross-compiling on macOS is usually a matter of passing -arch <ARCH> to the compiler, the project fully supports cross-compiling from arm64 to x86_64 on macOS - including all required dependencies. The target architecture can be set by specifying CMAKE_OSX_ARCHITECTURES=<arm64|x86_64> on the CMake CLI. Note that compiling universal binaries is not supported at this point, because some dependencies do not have the required logic to do this in one step.
  • Build manual: A special INSTALL_macOS.md provides specific instructions on how to compile this project successfully on macOS.
  • OpenMP: Using OpenMP with AppleClang is now supported - this requires that OpenMP is installed as an external dependency (enabled by default on macOS), as the Apple SDK does not ship it. Furthermore, the project now uses the unified CMake targets OpenMP::OpenMP_C and OpenMP::OpenMP_CXX respectively instead of setting the required flags manually.

Open questions

Drawbacks

Because AliceVision has so many dependencies - some with very specific configurations - I think we cannot officially support building the project with package-manager provided dependencies. I just stumbled from roadblock to roadblock when attempting to standardize the required dependencies for the different package managers. So currently the only option is to build the project with ALICEVISION_BUILD_DEPENDENCIES=ON. However, this matches the recommendation for Linux, so I think this should be fine. If someone wants to attempt to build it with Homebrew/MacPorts/Nix anyway, that might or might not work. But at least we don't have the obligation to ensure compatibility for these cases.

There is no CI yet. I decided against CI, because it currently requires to rebuild all dependencies over and over again - the GitHub runners usually only have 3 threads available, so this is quite slow. I tested pre-built dependencies, but that currently does not work because there are some dependencies hard-code absolute paths into their CMake config modules - making them not portable.

There are no unit tests yet. I ran the unit tests on my Mac, and two are currently failing:

  1. acRansac_test.cpp: I think there is some undefined behavior here, which caused a segfault on macOS. See this gist for a detailed description and proposed solution.
  2. fundamental10PSolver_test.cpp: The check on line 184 fails. I have no idea why and I don't know anywhere near enough to solve this. Help is much appreciated. For the results see this gist.

Future plans

This is the first step to make macOS a fully supported platform for this project again. The next steps would be to add the Apple Metal DepthMap backend and maybe generally abstract the DepthMap library to allow for multiple backends with a unified interface.

Also: Add a proper CI solution and ensure that all unit tests pass.

Feedback is appreciated!

These patches are the result of weeks of debugging, investigating and rebasing - but I am sure that there are still issues and edge cases that I completely missed. So fresh viewpoints and remarks are much appreciated. If anyone has the chance to test this out, please do so and let me know if there are any issues.

@servantftransperfect
Copy link
Copy Markdown
Contributor

Sorry for the long time to answer, i'm still figuring on how to get access to a mac.

@philippremy
Copy link
Copy Markdown
Contributor Author

No worries, I'll be busy with exams until the end of February anyways, so I won't be able to work on this full time until then. Just wanted to get this out, so at least the RFC period can start :).

@philippremy
Copy link
Copy Markdown
Contributor Author

A quick follow up on the Boost/LLVM issue:

This appears to be a known upstream problem, which (as of the time of writing) can only be fixed by overwriting LLVM headers, see here and here.

So there are essentially three options to approach this (imho):

  1. Patch the header during the configure step (horrible idea, not reproducible, tampering with foreign system-wide headers should never be an option)

  2. Explicitly restrict usage of package manager LLVM/Clang on macOS to known working versions (not good either, because I don't want to force users to uninstall LLVM just to build the project)

  3. Wait until we can drop b2 as the build system for Boost (I like this one :D, b2 really is annoying at times):

    The blocking factor currently is CCTag, which relies on the legacy Boost::math_c99 module to be present, which the CMake build system of Boost cannot build. So we need to wait for either option:

    3.1. Wait until Remove unnecessary Boost dependencies and update documentation CCTag#232 is merged, which removes the module as a dependency.
    3.2. Wait until the Boost.Math maintainer adds the CMake infrastructure for the legacy modules. I've opened an issue and they are willing to add this, although there is no specific timeline yet.

I strongly prefer option 3.1. (as it is the most controllable from the organization's pov), but if you have other ideas: Please let me know ^^.

@NeverGET
Copy link
Copy Markdown

NeverGET commented Mar 7, 2026

Hi @music-dsp-collection — thank you so much for the incredible work on MTL-AliceVision! 🎉

I've been testing the Meshroom 3D viewer with your macOS Metal bundle on Apple Silicon (M4 Max, macOS 26.3) and it's working great. We ran into some Meshroom-side issues where the 3D viewer crashed due to Metal RHI's strict vertex descriptor validation — custom Qt3D geometries (Grid3D, BoundingBox, Locator3D) and loaded meshes didn't always provide the vertexNormal attribute that built-in materials expect.

We've put together fixes in a Meshroom PR: alicevision/Meshroom#3030

Key fixes on the Meshroom side:

  • Remove vertexNormal dependency from SphericalHarmonics shaders (compute flat normals via derivatives instead)
  • Add default normal attributes to custom geometries
  • Add ensureNormals() for dynamically loaded meshes
  • OpenGL 3.2 Core fallback shader techniques
  • macOS platform support in setupEnvironment() (DYLD paths, Metal RHI backend)
  • QML plugin path discovery for qtAliceVision

Everything is running stable now — the full Meshroom pipeline (camera init → feature extraction → matching → structure from motion → texturing) works end-to-end, and the 3D viewer renders loaded meshes with textures via EXR support from QtAliceVisionImageIO.

Happy to help with any additional macOS testing! Thanks again for making this possible. 🙏

@philippremy
Copy link
Copy Markdown
Contributor Author

Happy to hear that :D! I finished my exams and will be able to start working on this again shortly. Hopefully I'll be able to iron out the last blockers and turn this into a proper pull request soon :).

@philippremy
Copy link
Copy Markdown
Contributor Author

philippremy commented Mar 9, 2026

Update: One step closer

3. 3.2. Wait until the Boost.Math maintainer adds the CMake infrastructure for the legacy modules. I've opened an issue and they are willing to add this, although there is no specific timeline yet.

It seems like this is now the most probable option. A PR in the Boost.Math repo is in the process of being merged, so this could actually be resolved very soon. I'll work on switching to the CMake build system for Boost as soon as the interface is stable (i.e., the PR is merged). Once this is done, I think the infrastructure changes are ready to be merged 🚀.

AFAIK the required changes for Boost should land in v1.91.0, which is scheduled to be released on April 8th!

@philippremy
Copy link
Copy Markdown
Contributor Author

CCTag merged the required PR, so this technically has no blockers left - except that it needs a huge rebase/rework because of the PR that changed the dependency handling.
I will start working on that asap :D.

@servantftransperfect
Copy link
Copy Markdown
Contributor

CCTag merged the required PR, so this technically has no blockers left - except that it needs a huge rebase/rework because of the PR that changed the dependency handling. I will start working on that asap :D.

My bad, sorry for that. I forgot you had made changes to those files.

@philippremy
Copy link
Copy Markdown
Contributor Author

No worries, that was something I wanted to tackle anyways. It is muuuch cleaner now and transferring the changes should be as simple as cherrypicking or copy-pasting. I don't expect that to take long :).

@philippremy
Copy link
Copy Markdown
Contributor Author

philippremy commented Apr 16, 2026

I reworked everything onto the new infrastructure and even found some bugs on my side along the way. I tested compilation on my Mac (clean, only required tools per INSTALL_macOS.md installed) for arm64 and x86_86 with Unix Makefiles and with Ninja. If CI passes, I will convert this into a proper PR. Bundling also works for both architectures and the bundle now includes the headers, the share/aliceVision and the share/meshroom folders.

Thanks for the patience everyone ^^!

EDIT: Woops, didn't mean to rewrite that much history. Commits are now back with their owners :D.

@philippremy philippremy changed the title [RFC] Re-add support for macOS Re-add support for macOS Apr 16, 2026
@philippremy philippremy marked this pull request as ready for review April 16, 2026 19:26
@servantftransperfect servantftransperfect self-requested a review April 20, 2026 09:02
@servantftransperfect servantftransperfect added this to the 3.4.0 milestone Apr 20, 2026
Comment thread src/cmake/deps/xercesc.cmake Outdated
)

set(XERCESC_CMAKE_FLAGS
# TODO
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.

status ?

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.

My bad, this should contain -DXercesC_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/XercesC.

Should I add a new commit for this or rebase? You can add it, if you want to, of course.

Comment thread src/cmake/Helpers.cmake Outdated
set_target_properties(${software_name}_exe
PROPERTIES SOVERSION ${ALICEVISION_SOFTWARE_VERSION_MAJOR}
VERSION "${ALICEVISION_SOFTWARE_VERSION_MAJOR}.${ALICEVISION_SOFTWARE_VERSION_MINOR}"
VERSION "${ALICEVISION_SOFTWARE_VERSION_MAJOR}_${ALICEVISION_SOFTWARE_VERSION_MINOR}"
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.

Why ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Yes, I have seen the dot notation in many places actually, but so far only for shared libraries. And for these it is not an issue, because they always have the .dylib file extension. For Mach-O executables (on macOS) the system went to interpret the last version number as a file extension, because they usually don't have a file extension at all (see the image as an example). While not the biggest issue, e.g. Xcode refuses to load the executable for debugging, because it only checked the file extension (bad practice, I know).

And I thought it would be fine because we created symlinks anyways and as far as I can tell, Meshroom for example will invoke the non-versioned symlinks.

But feel free to reverse, if it breaks stuff I did not notice. Invoking them via the CLI works fine, as far as I know...

file-extension-bug

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.

can't we just do that for mac os ?

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.

Sounds good to me!

@servantftransperfect
Copy link
Copy Markdown
Contributor

I can't compile docker images with the updated boost-1.90. Any reason not to stick with 1.86 ? (Except cmake archive)

@servantftransperfect servantftransperfect force-pushed the bits/macos-infra branch 2 times, most recently from c5421f2 to 5487257 Compare April 20, 2026 14:23
philippremy and others added 6 commits April 20, 2026 16:23
The previous OptimizeForArchitecture only included proper support for x86(_64). The new implementation supports x86(_64), arm(64), ppc and adds newer CPU families.

Furthermore, it adapts OFA to account for cross-compilation on Apple targets. When targeting arm64, it selects apple-m1 as the baseline architecture (making it compatible with all Mac Apple Silicon Chips). When targeting x86_64, it selects skylake as the baseline architecture (making it compatible with all Intel Macs not older than 2015). All of this can be manually overridden by sepcifying TARGET_ARCHITECTURE on the command line.

The code is derived/copied from https://gitlab.inria.fr/gismo/gismo, which is licensed under MPL-2.

Signed-off-by: Philipp Remy <philipp.remy@law-school.de>
Instead of setting CFLAGS or CXXFLAGS manually, simply use the CMake targets OpenMP::OpenMP_C and OpenMP::OpenMP_CXX respectively. This applies to dependencies (MeshSD), nonfree (VLSift) and the AliceVision targets itself.

Signed-off-by: Philipp Remy <philipp.remy@law-school.de>
This commit adds support for compiling library targets into Apple Frameworks on macOS. Embedding resources into the bundle is supported as well.

It is checked early if the user attempts to build a universal binary, which is currently unsuppprted due to missing support in the dependency building code.

Signed-off-by: Philipp Remy <philipp.remy@law-school.de>
Executable file names are suffixed with their respective versions in the format "MAJOR.MINOR". This is fine as long as the executable (as on Windows) has a proper file extension. On macOS (and other Unix OSes as well), the appended version suffix could be falsely interpreted as a file extension. Change "MAJOR.MINOR" to "MAJOR_MINOR" formatting.

Signed-off-by: Philipp Remy <philipp.remy@law-school.de>
philippremy and others added 20 commits April 20, 2026 16:23
This commit introduces several changes to the general build infrastructure. Given CMAKE_OSX_ARCHITECTURES, it is now possible to cross-compile the whole project and its dependencies from x86_64 to aarch64 and vice versa on macOS. This is easily achievable because Apple can compile for both architectures with the same sysroot. Choosing the correct flags depends on the underlying build system:

    (1) CMake: In CMake, one can just set CMAKE_OSX_ARCHITECTURES to either arm64 or x86_86.
    (2) libVPX: A target must be specified using the --target flag (includes the major Darwin version number).
    (3) ffmpeg: Must pass the additional CFLAGS, CXXFLAGS and LDFLAGS (with "-arch x86_64/arm64") and the --arch (with x86_64 or aarch64(!)), --enable-cross-compile and --sysroot (xcrun --sdk macosx --show-sdk-path) flags.
    (4) Boost: For Boost, it is essentially the same as for CMake, but
Boost.Context requires some special handling for its assembly files.

SWIG will not be cross-compiled, because it is a compile-time tool that
must match the host CPU of the machine performing the build.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
…rpath

If ALICEVISION_USE_RPATH is set, explicitly set the install name directory for the ffmpeg libraries to @rpath using the available autoconf CLI argument.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
…pple targets where necessary

As it might be desirable to later change the embedded rpaths of a binary, "install_name_tool" expects enough padding between the header and the first data section of a Mach-O file. This caused issues when changing the rpaths of the following dependencies, which added little to no padding to the Mach-O header:

- ffmpeg

Pass "-headerpad_max_install_names" explicitly as linker flags to these dependencies when building them on Apple platforms. This adds the maximum amount of padding to the header (per ld man page: "Automatically adds space for future expansion of load commands such that all paths could expand to MAXPATHLEN.").

Signed-off-by: Philipp Remy <philipp@philippremy.net>
As we do not build Ceres with SuiteSparse support on Apple platforms by default (Ceres can utilize Accelerate.framework), do not ask for SuiteSparse on Apple platforms. As an equivalent, make sure to find a Ceres with AccelerateSparse (can be disabled in the same manner as Ceres with SuiteSparse).

Signed-off-by: Philipp Remy <philipp@philippremy.net>
…ries for AliceVision

Currently, the name is set by CMAKE_SYSTEM_PROCESSOR. However, this does not always match the target architecture, as users can cross-compile on Apple targets. On Apple, use CMAKE_OSX_ARCHITECTURES instead.

Signed-off-by: Philipp Remy <philipp.remy@law-school.de>
This commit adds a Python script (darwin_bundle.py) which takes several Mach-O files (or Framework folders) as input and attempts to resolve all required dependencies to create a standalone (i.e, self-contained) bundle.

A CMake target for use after the AliceVision build is added to automatically invoke the script with all targets of the project (can be invoked with make darwin-bundle). This works somewhat similar to what the regular bundle target does, but the CMake implementation did not appear to work for Apple targets (out of the box).

Signed-off-by: Philipp Remy <philipp@philippremy.net>
Due to the additional requirements and the unique build process of this platform (cross-compiling, environment, ...) move the build instructions to a custom file.

This commit also introduces a list of available target architectures in the OFA system, available at src/cmake/OFA/SupportedArchitectures.md.

Signed-off-by: Philipp Remy <philipp.remy@law-school.de>
Adapt linker flags to the Apple linker (ld), which does not allow
undefined symbols in shared objects (.so) by default, see SWIG issue 2469.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
Respect the user's choice to use static libraries for the dependencies

Signed-off-by: Philipp Remy <philipp@philippremy.net>
Fixes some configuration errors introduced by rebasing onto the new
CMake infrastructure.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
Bump version of OpenImageIO from v3.0.9.1 to v3.0.17.0 (appears to be ABI and API compatible), because v3.0.9.1 uses a version of fmt which causes consteval errors on newer Clang compilers.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
When building an embedded PXR and these flags are not set, the CMake
build system of USD does a funny thing and overwrites
PXR_BUILD_GPU_SUPPORT, causing several libraries to link to a
non-existent GPU target of OpenSubdiv (which we explicitly build
*without* GPU backends, see opensubdiv.cmake).

Signed-off-by: Philipp Remy <philipp@philippremy.net>
CCTag merged a patch which removed several Boost dependencies (including
boost::math_c99, which we currently cannot build with Boost's CMake
build system).

FIXME: Switch to a proper release tag once CCTag gets a new release
which includes these changes.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
liblemon always assumes a static library in its CMake configuration
template and therefore cannot be used as a dynamic library.

It also still uses the C++17 deprecated "register" keyword, so force it
to build with C++14 to avoid a compilation error.

FIXME: Remove when upstream liblemon is updated accordingly.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
As all other dependencies are built using
AV_BUILD_DEPENDENCIES_PARALLEL, this should also be applied to
AliceVision in this case to avoid eternal compilation times.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
This caused cross-compilation to fail on Apple platforms, because it did
not receive the baseline CMAKE_CORE_BUILD_FLAGS we pass to each
dependency build.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
This commit adds some information about how to correctly build
AliceVision for use with Meshroom, as this poses some specific
requirements regarding Python, NumPy and the SWIG bindings.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
If the user disabled the SWIG bindings, Python might not have been found
for the bundler. MacOS always has a (somewhat old) Python 3.9 available,
so we can safely use this. Add an explicit search step if Python is not
yet available.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
We also need to make sure that any SWIG generated .so files are entirely
self contained in the bundle. As they cannot rely on more libraries than
their respective main library, we can simply remove all rpaths and add a
single new one "@loader_path/../../", which directly resolves to the lib
folder in the bundle containing all bundled dependencies.

That can be done with a simple shell script.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
Simplify some of the functions in darwin_bundle.py.

DISCLAIMER: This was done using AI assistance.

Signed-off-by: Philipp Remy <philipp@philippremy.net>
@philippremy
Copy link
Copy Markdown
Contributor Author

I can't compile docker images with the updated boost-1.90. Any reason not to stick with 1.86 ? (Except cmake archive)

No, not really - I guess I was still thinking about the math_c99 which was only introduced very recently for the CMake build system. But because CCTag removed the dependency we could just revert to 1.86 (it has a CMake archive as well and I would really prefer to switch to CMake :D...).

What exactly is causing the build failure in Docker (just out of personal curiosity)?

@servantftransperfect servantftransperfect self-requested a review April 20, 2026 14:25
@servantftransperfect
Copy link
Copy Markdown
Contributor

I can't compile docker images with the updated boost-1.90. Any reason not to stick with 1.86 ? (Except cmake archive)

No, not really - I guess I was still thinking about the math_c99 which was only introduced very recently for the CMake build system. But because CCTag removed the dependency we could just revert to 1.86 (it has a CMake archive as well and I would really prefer to switch to CMake :D...).

What exactly is causing the build failure in Docker (just out of personal curiosity)?

I'm getting a weird compilation error in boost maths numeric_limits.hpp. BOOST_STATIC_something contains constexpr which generate a constexpr constexpr function(...).

@philippremy
Copy link
Copy Markdown
Contributor Author

philippremy commented Apr 20, 2026

I'm getting a weird compilation error in boost maths numeric_limits.hpp. BOOST_STATIC_something contains constexpr which generate a constexpr constexpr function(...).

Uh oh, that doesn't sound good. I think I had the same issue at some point and just forgot about it because I patched it manually. I'll see if I it already fixed upstream and if not, I will open a bug report. The maintainer over there is super helpful and maybe that'll make us future-proof :D.

EDIT: Apparently has been fixed two weeks ago, but that will probably only land in Boost 1.91, because it didn't make it into master in time: boostorg/math#1383.

So if it wasn't a problem in 1.86, we should definitely revert! Using the develop branch for all Boost stuff doesn't seem a good idea imho :).

Copy link
Copy Markdown
Contributor

@servantftransperfect servantftransperfect left a comment

Choose a reason for hiding this comment

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

That was a pretty long review to do !

So first of all, thanks for this large PR. I am sure many people will be happy to see this available.

I reviewed the changes mostly for non regression.

As it is focused on cmake changes, I checked that our docker containers are still building correctly. The CI is still working correctly.

I am NOT able to validate the APPLE part as we have no access to hardware.

I did some updates related to the comment i did, and i added some changes for the dockerFiles.

@philippremy
Copy link
Copy Markdown
Contributor Author

Thank YOU for this awesome project!

The containers are something that I cannot reliably test, so thanks for that as well. For any future PRs, I will try to keep them way smaller.

Everything seems fine to me - but as I mentioned over in my proposal in the discussion section, the build will probably always be somewhat brittle (at least for the mac users under us). And that isn't even our fault, but CMake just really gets to its limits with so many dependencies. I will try to do regular testing for macOS, if possible. And maybe I'll be able to spin up some CI for macOS as well.

@servantftransperfect servantftransperfect merged commit 33b6e27 into alicevision:develop Apr 20, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants