cmake --build: --parallel when used with msbuild does not enable parallelism within a project

I went through the below already-opened tickets here

issues/20564

Tried everything mentioned there and nothing worked. I am using Visual Studio Generator .

I tried below commands and nothing worked.

cmake --build --preset=Windows-x64-Debug --parallel --target Lib1 Lib2 Lib3 Lib4

cmake --build --preset=Windows-x64-Debug --parallel --target Lib1 Lib2 Lib3 Lib4 – /p:CL_MPCount=16

I am only able to achieve multiple source file compilation within a project and it never compiles all my targets in parallel. Here targets Lib1 Lib2 Lib3 Lib4 targets and they do not dependent on each other. So ideally they should build in parallel.

I opened generate .sln (by cmake for Visual Studio Generator for project) and from there if I select multiple target and bulild them they get build fine.

NOTE: This issue is only present in Visual Studio Generator. For Ninja/xcode it works fine.

Please help me here. Am I doing anything wrong here ? How I can enable multiple projects compiles in parallel using cmake for msbuild prjects?

Any help is greatly appreciated.

I have a vague recollection that if you list multiple targets in the cmake --build ... --target command line, it actually builds each target one at a time, not all of them in the one invocation. I could be wrong about that, but please check it. For testing purposes, you could try adding a custom target to your project which depends on Lib1, Lib2, Lib3 and Lib4, then list just that custom target after the --target command line option. If you see a difference in parallelism, that would answer this question.

The other thing I’d recommend is to try the Multi-Tool Task scheduler. It should give you the behavior you’re looking for if my recollection as discussed in the previous paragraph turns out to be incorrect. Re-run the CMake configure step, adding the following to the cmake command line (including the quotes):

"-DCMAKE_VS_GLOBALS=UseMultiToolTask=true;EnforceProcessCountAcrossBuilds=true"

Then, when you run the build, add the /m option. For example:

cd path/to/source/dir
cmake --preset whatever "-DCMAKE_VS_GLOBALS=UseMultiToolTask=true;EnforceProcessCountAcrossBuilds=true"
cmake --build --preset=Windows-x64-Debug --target Lib1 Lib2 Lib3 Lib4 -- /m

That should give you behavior close to how Ninja works.

I tried these as you suggested but still, it builds sequentially.

cmake --preset Windows-x64 “-DCMAKE_VS_GLOBALS=UseMultiToolTask=true;EnforceProcessCountAcrossBuilds=true”

D:\TW\Workspace>cmake --build --preset=Windows-x64-Debug --target Lib1 Lib2 Lib3 Lib4 – /m /nologo

Checking Build System
Building Custom Rule D:/TW/Workspace/CMakeLists.txt
TWSample.cpp
RegularLib.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib1.lib

Building Custom Rule D:/TW/Workspace/CMakeLists.txt
TWSample.cpp
RegularLib1.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib2.lib

Building Custom Rule D:/TW/Workspace/CMakeLists.txt
TWSample.cpp
RegularLib2.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib3.lib

Building Custom Rule D:/TW/Workspace/CMakeLists.txt
TWSample.cpp
RegularLib2.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib4.lib
D:\TW\Workspace>

If I build a custom target which depends on all these libs then it works. But we can not use custom targets approach.

add_custom_target(SampleCustomTarget COMMENT “Building custom target”)
add_dependencies(SampleCustomTarget Lib1 Lib2 Lib3 Lib4)

D:\TW\Workspace>cmake --build --preset=Windows-x64-Debug --target SampleCustomTarget – /m
MSBuild version 17.5.1+f6fdcf537 for .NET Framework
MSBuild logs and debug information will be at “D:\TW\Builds\TWInt\Windows-x64\MSBuild_Logs”

Checking Build System
Building Custom Rule D:/TW/Workspace/CMakeLists.txt
Building Custom Rule D:/TW/Workspace/CMakeLists.txt
Building Custom Rule D:/TW/Workspace/CMakeLists.txt
Building Custom Rule D:/TW/Workspace/CMakeLists.txt
TWWinUIApp.cpp
TWWinUIApp.cpp
Lib1.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib1.lib
Lib2.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib2.lib
TWWinUIApp.cpp
Lib3.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib3.lib
TWWinUIApp.cpp
Lib4.vcxproj → D:\TW\Builds\TWLib\Windows-x64\Debug\Lib4.lib
Building Custom Rule D:/TW/Workspace/CMakeLists.txt

D:\TW\Workspace>

Hi @craig.scott . Please let me know if I am doing something wrong.

My earlier comment explained what is likely happening:

If that’s indeed the case, then you will need to avoid listing multiple targets after --target on the command line. My suggestion was to create a custom target that depends on the ones you want built, but you said you are not willing/able to do that. So you’re either stuck with the serial behavior, or you’ll need to find a way to allow you to add such a custom target.