CMake for cross-compiling but using VS Code/VS Studio

I use CMake 3.31.6 for building a 2 applications for 2 microcontrollers in the project.

Unfortunately, they are two different microcontrollers and required two different toolchain setups.

Currently we essentially have created a VS Studio project by hand, and two makefile project to actually build the project. We have been unsuccessful in generating a VS Studio project that correctly builds the ELF/HEX output file.

2 Questions:

  1. is there a way to build a VS Studio project that uses a toolchain?
  2. Is there away to have a “root/master” project that has two subprojects that are for different tool chains?

If I have to move to CMake 4 for this, I will gladly :slight_smile:

Dear Scott,

I am not an expert on this, but I am also using visual studio 2022 in combination with cmake to cross compile on embedded hardware.

Have you looked into toolchain files? In my case, I create a toolchain file with the specific cross-compilation information for a specific scenario (so yes, I have multiple toolchain files).
Then it depends on how you use Visual studio in combination with cmake. As far as I understand you have 3 options:

  • Either you use cmake on commandline to create your solution file for visual studio
  • Or you use visual studio in folder mode and it will use cmake to generate and build. For this you use the build in CMakeSettings configuration of visual studio.
  • Or you use visual studio in folder mode and it will use cmake, but you use the CMakePresets.json way of configuration.

I used to work with the second option, but I migrated to the third option.
When using the CMakeSettings from visual studio, you can define multiple configurations (with the IP address and ssh information and all. see: https://learn.microsoft.com/en-us/cpp/build/customize-cmake-settings?view=msvc-170. In there you can define your cmake toolchain file.

The CMakePresets is the currently advised way. So, you should make a preset for each embedded target and indicate the correct toolchain file (see https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html#configure-preset) In this case the IP and ssh information is stored separatly, so it is still possible that your developers connect the wrong device with the wrong preset. If there is some variable or environment variable on which you can differentiate the devices, then you can use the conditions to prevent this.

If you are using the commandline to generate solution files. then I believe you can still use the CMakePresets method, but you need to provide the preset during the configuration phase on the commandline. In other words. In that case you will need to generate different solution files for each scenario. But my knowledge of this option is limited so I am not certain.

As for the ‘root/master’ question: I don’t know if you mean that there is 1 shared code base for both options, or just two completely seperate projects in the same folders.
But using options in cmake and CMakePresets, you can completely change the targets and all aspects of your builds depending on the selected preset. That does require you to do quite some work in the cmake. Wherever the projects are different you need an if else cmake statement to capture the difference.
In the book on ‘Professional cmake’ there is a chapter on superbuilds, but I still have to read that :wink:

I hope this helps to get you going on the path to an answer.

The superbuild structure seems to be the way to go for this.

Both subsystems use the same tool chain but with different parameters, cause each to have their own gcc to use. that is the root cause of the problem in having them both under the same umbrella.

But the superbuild system seems to be a solution for this

Thanks for the tip

We also just resolved to ourselves, that toolchain based builds do not use visual studio. It just works easier to create a makefile.

@scottaronbloom, What do you mean with ‘toolchain based builds do not use visual studio’?

For the cross compiling (tool chain based builds) we simply use “Unix Makefiles” for the target, as opposed to trying to cross compile inside Visual Studio

Sorry I wasnt clear.

I propose using Ninja instead of Make.

First, Visual Studio also ships it and uses it when you open a CMakeLists.txt in VS. It’s also faster and Make sometimes hangs on Windows with parallel builds.

Also with Windows paths, you should not use Unix Makefiles generator but MinGW Makefiles generator.