Skip to content

CMake: Replace the Visual Studio project#14475

Open
JoshuaVandaele wants to merge 10 commits intodolphin-emu:masterfrom
JoshuaVandaele:cmake-replaces-vs
Open

CMake: Replace the Visual Studio project#14475
JoshuaVandaele wants to merge 10 commits intodolphin-emu:masterfrom
JoshuaVandaele:cmake-replaces-vs

Conversation

@JoshuaVandaele
Copy link
Copy Markdown
Contributor

@JoshuaVandaele JoshuaVandaele commented Mar 16, 2026

The Visual Studio project is currently used to compile Dolphin on Windows, while CMake is used for all other platforms.

This difference has become a maintenance burden when introducing new dependencies, as it effectively doubles the amount of work and requires the developer to be familiar with both CMake and Visual Studio projects. Additionally, most dependencies do not provide Visual Studio projects, which means they need to be created and maintained by us, something that is very time-consuming and error-prone.

The situation has become cumbersome enough that the Visual Studio project now invokes CMake to configure and build larger dependencies, such as glslang.

Changes

Unification of the Output, Sys, and Translation Directories

Previously, on Windows the output directory was located in the /Binary/<architecture>/ directory, whereas the output directory is located under build/Binaries for other platforms. Both platforms now output to /build/<architecture>/Binaries.

On Non-Windows and non-Apple platforms, the Sys directory had a set location unless the LINUX_LOCAL_DEV flag was set, in which case Dolphin used a location relative to the executable. This is no longer the case, Dolphin will now first check for the existence of a Sys folder next to the Dolphin executable, before falling back to the defined SYSDATA directory. During build time, the Sys directory is now unconditionally Symlinked next to the executable, similar to the behavior on Windows, which copied the required files.
With this change, the LINUX_LOCAL_DEV flag is no longer required, and therefore has been removed.

Warning

Because creating symbolic links on Windows normally require a special permission, we fall back to copying with a warning unless Developer Mode is enabled.

The translation directories have also been merged on both platforms, in a similar fashion to the Sys directory.

Introducing CMakePresets, Replacing the Old CMakeSettings

It adds presets for Debug and Release profiles for both x64 and ARM64 architectures, as well as Generic builds.
Presets can be used using Visual Studio's built-in CMakePresets support, or Visual Studio Code's CMake Tools extension.

They can also be used from the command line, like so:

  • x64/Unix-like/Ninja:
    • Configure: cmake --preset ninja-release-x64
    • Build: cmake --build --preset ninja-build-release-x64
    • Configure + Build: cmake --workflow --preset ninja-release-x64
  • ARM64/Windows/Visual Studio:
    • Configure: cmake --preset visualstudio-release-arm64
    • Build: cmake --build --preset visualstudio-build-release-arm64
    • Configure + Build: cmake --workflow --preset visualstudio-release-arm64

The Ninja generator is available to both Windows and Unix-likes, while the Visual Studio Generator is only available on Windows.

Cross-Compiling

On Windows, the Visual Studio generator automatically takes care of everything, you just need to select an ARM64 preset.

On Unix-likes, to cross-compile you need to install a cross-compiler and (optionally) a sysroot of the target system.
Here is an example to compile from x64 to ARM64 with a sysroot:

  • cmake --preset ninja-release-arm64 -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_SYSROOT=/opt/sysroots/aarch64-linux-gnu
  • cmake --build --preset ninja-build-release-arm64

You will need a sysroot to link against Qt, since we do not vendor it in on platforms other than Windows.

User Presets

A CMakeUserPresets.json file may be created locally at the root of the project to further customize your presets.

Example: User Presets used to test this PR on Arch Linux with a generic Arch Linux ARM sysroot
{
  "version": 10,
  "configurePresets": [
    {
      "name": "gcc-debug-arm64",
      "inherits": "ninja-debug-arm64",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "aarch64-linux-gnu-gcc",
        "CMAKE_CXX_COMPILER": "aarch64-linux-gnu-g++",
        "CMAKE_EXE_LINKER_FLAGS": "-L/opt/sysroots/ArchLinuxARM/lib",
        "CMAKE_SYSROOT": "/opt/sysroots/ArchLinuxARM"
      }
    },
    {
      "name": "clang-debug-arm64",
      "inherits": "ninja-debug-arm64",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "clang",
        "CMAKE_CXX_COMPILER": "clang++",
        "CMAKE_C_FLAGS": "-target aarch64-linux-gnu",
        "CMAKE_CXX_FLAGS": "-target aarch64-linux-gnu",
        "CMAKE_SYSROOT": "/opt/sysroots/ArchLinuxARM"
      }
    },
    {
      "name": "clang-debug-x64",
      "inherits": "ninja-debug-x64",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "clang",
        "CMAKE_CXX_COMPILER": "clang++"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "gcc-build-debug-arm64",
      "configurePreset": "gcc-debug-arm64"
    },
    {
      "name": "clang-build-debug-arm64",
      "configurePreset": "clang-debug-arm64"
    },
    {
      "name": "clang-build-debug-x64",
      "configurePreset": "clang-debug-x64"
    }
  ],
  "workflowPresets": [
    {
      "name": "gcc-debug-arm64",
      "steps": [
        { "type": "configure", "name": "gcc-debug-arm64" },
        { "type": "build", "name": "gcc-build-debug-arm64" }
      ]
    },
    {
      "name": "clang-debug-arm64",
      "steps": [
        { "type": "configure", "name": "clang-debug-arm64" },
        { "type": "build", "name": "clang-build-debug-arm64" }
      ]
    },
    {
      "name": "clang-debug-x64",
      "steps": [
        { "type": "configure", "name": "clang-debug-x64" },
        { "type": "build", "name": "clang-build-debug-x64" }
      ]
    }
  ]
}

They are then used like so:
Configure + Build with GCC: cmake --workflow --preset gcc-debug-arm64
Configure + Build with Clang: cmake --workflow --preset clang-debug-arm64
Configure + Build with Clang (x64): cmake --workflow --preset clang-debug-x64

Addendum: It should also now be possible to cross-compile from Windows to Unix-likes, and Unix-like to other Unix-like (e.g. Linux -> FreeBSD), however this is untested.

Pre-Merge Requirements

@JoshuaVandaele JoshuaVandaele force-pushed the cmake-replaces-vs branch 2 times, most recently from 06a4492 to 1692381 Compare March 28, 2026 01:09
@BhaaLseN
Copy link
Copy Markdown
Member

Because creating symbolic links on Windows normally require a special permission, CMake will fail unless "Developer Mode" is enabled under System > Advanced.

Can't you just do the fallback if the symlink fails? Or test if the setting is on/symlinks are ok to make this more pleasant to use?
(For reference, I don't think I have developer mode on; probably because I'm not on the most recent version either...I don't have System > Advanced.)

It might just be me though, if everyone else is ok with that, feel free to ignore me.

Generic builds have never been supported on Windows.
This introduces a CMakePresets file for both Unix-likes and Windows that replace the old CMakeSettings.

It adds presets for **Debug** and **Release** profiles for both **x64** and **ARM64** architectures, as well as **Generic builds**.
Presets can be used using[ Visual Studio's built-in CMakePresets support](https://learn.microsoft.com/en-us/cpp/build/cmake-presets-vs?view=msvc-170), or [Visual Studio Code's CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) extension.

They can also be used from the command line, like so:

- x64/Unix-like/Ninja:
  - Configure: `cmake --preset ninja-release-x64`
  - Build: `cmake --build --preset ninja-build-release-x64`
  - Configure + Build: `cmake --workflow --preset ninja-release-x64`
- ARM64/Windows/Visual Studio:
  - Configure: `cmake --preset visualstudio-release-arm64`
  - Build: `cmake --build --preset visualstudio-build-release-arm64`
  - Configure + Build: `cmake --workflow --preset visualstudio-release-arm64`

The Ninja generator is available to both Windows and Unix-likes, while the Visual Studio Generator is only available on Windows.

**Cross-compiling**

On **Windows**, the Visual Studio generator automatically takes care of everything, you just need to select an ARM64 preset.

On **Unix-likes**, to cross-compile you need to install a cross-compiler and (optionally) a sysroot of the target system.
Here is an example to compile from x64 to ARM64 with a sysroot:

- `cmake --preset ninja-release-arm64 -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ -DCMAKE_SYSROOT=/opt/sysroots/aarch64-linux-gnu`
- `cmake --build --preset ninja-build-release-arm64`

You will need a sysroot to link against Qt, since we do not vendor it in on platforms other than Windows.

**User presets**

A `CMakeUserPresets.json` file may be created locally at the root of the project to further customize your presets.
For example, here are the user presets I used to test this PR on Arch Linux with a generic Arch Linux ARM sysroot:

```json
{
  "version": 10,
  "configurePresets": [
    {
      "name": "gcc-debug-arm64",
      "inherits": "ninja-debug-arm64",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "aarch64-linux-gnu-gcc",
        "CMAKE_CXX_COMPILER": "aarch64-linux-gnu-g++",
        "CMAKE_EXE_LINKER_FLAGS": "-L/opt/sysroots/ArchLinuxARM/lib",
        "CMAKE_SYSROOT": "/opt/sysroots/ArchLinuxARM"
      }
    },
    {
      "name": "clang-debug-arm64",
      "inherits": "ninja-debug-arm64",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "clang",
        "CMAKE_CXX_COMPILER": "clang++",
        "CMAKE_C_FLAGS": "-target aarch64-linux-gnu",
        "CMAKE_CXX_FLAGS": "-target aarch64-linux-gnu",
        "CMAKE_SYSROOT": "/opt/sysroots/ArchLinuxARM"
      }
    },
    {
      "name": "clang-debug-x64",
      "inherits": "ninja-debug-x64",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "clang",
        "CMAKE_CXX_COMPILER": "clang++"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "gcc-build-debug-arm64",
      "configurePreset": "gcc-debug-arm64"
    },
    {
      "name": "clang-build-debug-arm64",
      "configurePreset": "clang-debug-arm64"
    },
    {
      "name": "clang-build-debug-x64",
      "configurePreset": "clang-debug-x64"
    }
  ],
  "workflowPresets": [
    {
      "name": "gcc-debug-arm64",
      "steps": [
        { "type": "configure", "name": "gcc-debug-arm64" },
        { "type": "build", "name": "gcc-build-debug-arm64" }
      ]
    },
    {
      "name": "clang-debug-arm64",
      "steps": [
        { "type": "configure", "name": "clang-debug-arm64" },
        { "type": "build", "name": "clang-build-debug-arm64" }
      ]
    },
    {
      "name": "clang-debug-x64",
      "steps": [
        { "type": "configure", "name": "clang-debug-x64" },
        { "type": "build", "name": "clang-build-debug-x64" }
      ]
    }
  ]
}
```

They are then used like so:
Configure + Build with GCC: `cmake --workflow --preset gcc-debug-arm64`
Configure + Build with Clang: `cmake --workflow --preset clang-debug-arm64`
Configure + Build with Clang (x64): `cmake --workflow --preset clang-debug-x64`

*Addendum: It should also now be possible to cross-compile from Windows to Unix-likes, and Unix-like to other Unix-like (e.g. Linux -> FreeBSD), however this is untested.*
@JoshuaVandaele JoshuaVandaele force-pushed the cmake-replaces-vs branch 2 times, most recently from 1692381 to 22d7c01 Compare March 28, 2026 15:42
@JoshuaVandaele
Copy link
Copy Markdown
Contributor Author

Can't you just do the fallback if the symlink fails? Or test if the setting is on/symlinks are ok to make this more pleasant to use?

There is now a copy fallback if the symlink cannot be created, and a warning will appear asking the user to enable Developer Mode alongside a link to official Microsoft docs on how to do so on different versions of Windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants