1

I have a (simplified) CMAKE file like so:

cmake_minimum_required( VERSION 3.6 )

function(BUILD_SIMULINK model)

   set(OUTPUT_FILE ${model}.dll)
   set(SOURCE_FILE ${model}.slx)
   set(EXECUTE_COMMAND 
      matlab -nojvm -nodisplay -nodesktop -nosplash -wait -r "rtwbuild(${model})"
   )

   add_custom_target( 
      ${model}  ALL  
      DEPENDS  ${OUTPUT_FILE} 
   )

   add_custom_command( 
      COMMAND    ${EXECUTE_COMMAND}
      DEPENDS    ${SOURCE_FILE}
      OUTPUT     ${OUTPUT_FILE}
   )

   install( TARGETS ${OUTPUT_FILE} 
            DESTINATION lib 
   )

endfunction(BUILD_SIMULINK)

project(SimulinkBuild VERSION 1.0.0)
build_simulink( model1 )
build_simulink( model2 )
build_simulink( model3 )
...
build_simulink( modeln )  # Arbitrarily large number of models

My problem is that it takes several hours to do a clean build because I am calling one command at a time, using only one core at a time. I'd like to build my files in parallel, taking advantage of the multiple cores on my machine. How can we achieve executing parallel commands from cmake?

When I build I do this:

cmake ..
cmake --build . --target install
Stewart
  • 4,356
  • 2
  • 27
  • 59
  • 1
    *Build* is fully controlled by the build tool, against which you *configure* the CMake project. So it depends whether your **build tool** supports parallel builds. E.g., `make` has `-j` option for that case. – Tsyvarev Jun 08 '17 at 11:56
  • I use `cmake --build` to invoke the build too. I think I just pass `cmake --build . --target install --j4` when using make. However, I'm using visual studio to test this right now which requires a `/MP` directive in the command-line options. I'm hoping that there is a tool-independent way to do both. – Stewart Jun 08 '17 at 12:14
  • Possible duplicate of [Generic rule from makefile to cmake](https://stackoverflow.com/questions/38293535/generic-rule-from-makefile-to-cmake) – Florian Jun 08 '17 at 12:20
  • Visual Studio (the generator) doesn't appear to support one of these options. The closest thing is MSVC supports a `/MP` switch, but I'm not using MSVC, I'm executing my own commands so this doesn't really work. – Stewart Jun 08 '17 at 12:25
  • Nevermind, I'm wrong. You're a genius! The solution is to run: `cmake --build . --target install -- /m` for visual studio and `cmake --build . --target install -- j` for make/ninja. This solves my issue. Though it would still be nice to have a generator-independant solution. – Stewart Jun 08 '17 at 12:37
  • @Stewart Sorry, I misunderstood your question. Just a note about `ninja`: it uses all cores by default (no need for an additional option). – Florian Jun 08 '17 at 14:32

2 Answers2

1

The solution is how to invoke cmake, and isn't part of the cmake file itself.

cmake ..
cmake --build . -- /m  # Visual Studio
cmake --build . -- -j  # Gnu make
Stewart
  • 4,356
  • 2
  • 27
  • 59
1

In CMake 3.12 support was added so that regardless of what generator you used, you can still kick off parallel builds (if supported) with:

cmake --build . --target install -j <number of threads>

But for earlier versions of cmake, any arguments after -- are passed to the build system being used. So for Makefiles:

cmake --build . --target install -- -j <number of threads>

Or for msvc builds:

cmake --build . --target install -- /m <number of threads>
johnb003
  • 1,821
  • 16
  • 30