From the CMake "make" setting, use the -j option by default

I want the CMake project to be created by make -j N when I call make from the terminal. I do not want to set the -j option manually each time.

To do this, I set the CMAKE_MAKE_PROGRAM variable to a specific command line. I use the ProcessorCount() function, which gives the number of processors for parallel assembly.

When I do make , I do not see any speed. However, if I do make -j N , then it will be built definitely faster.

Could you help me in this matter? (I am developing this on Linux.)

Here is the code snippet that I use in CMakeList.txt :

 include(ProcessorCount) ProcessorCount(N) message("number of processors: " ${N}) if(NOT N EQUAL 0) set(CTEST_BUILD_FLAGS -j${N}) set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N}) set(CMAKE_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM} -j ${N}") endif() message("cmake make program" ${CMAKE_MAKE_PROGRAM}) 

Thank you very much.

+11
source share
5 answers

By setting the variable CMAKE_MAKE_PROGRAM, you want to influence the build process. But:

  1. This variable affects only the build via cmake --build , and not on the native call of the tool ( make ):

    The variable CMAKE_MAKE_PROGRAM set for use by project code. This value is also used by the cmake (1) --build and ctest (1) --build-and-test to start the native build process.

  2. This variable must be CACHEd. It is used this way in generators similar to make:

    These generators store CMAKE_MAKE_PROGRAM in the CMake cache so that the user can edit it.

    That is, you need to set this variable with

     set(CMAKE_MAKE_PROGRAM <program> CACHE PATH "Path to build tool" FORCE) 
  3. This variable should refer to the executable file itself , and not to the program with arguments:

    The value can be the full path to the executable, or just the name of the tool if it is expected to be in PATH.

    That is, the value of "make -j 2" cannot be used for this variable (separation of arguments as a list

     set(CMAKE_MAKE_PROGRAM make -j 2 CACHE PATH "Path to build tool" FORCE) 

    also does not help).

Thus, you can override the behavior of cmake --build calls by setting the CMAKE_MAKE_PROGRAM variable to the script that invokes make with parallel parameters. But you cannot influence the behavior of direct make calls.

+2
source

If you want to speed up the build, you can run several make processes in parallel, but not cmake. To complete each assembly with a predetermined number of parallel processes, you can define this in MAKEFLAGS .

Install MAKEFLAGS in your environment script, for example ~ / .bashrc, as you want:

 export MAKEFLAGS=-j8 

The following CPU-1 number is installed on Linux for MAKEFLAGS: (leave one CPU free for other tasks during build) and is useful in environments with dynamic resources, such as VMware:

 export MAKEFLAGS=-j$(($(grep -c ^processor /proc/cpuinfo) - 0)) 
+6
source

You can set the MAKEFLAGS env variable with this command

 export MAKEFLAGS=-j$(nproc) 
+2
source

Can this method be used to call multiple functions? a similar function 1,2,3 is parallel rather consistent, any other ideas are appreciated.

Example:

  if(FLAG1) #some variables/options settings function1(${OPTIONS}) function2(${OPTIONS}) function3(${OPTIONS}) .... endif() function(fucntion1) #some variables/options parsing and passed to command. execute_process(COMMAND COMMAND1 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE res TIMEOUT 60) endfunction() function(fucntion2) #some variables/options parsing and passed to command. execute_process(COMMAND COMMAND2 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE res TIMEOUT 60) endfunction() 
0
source

My solution is to have a small script that will execute make, which includes all kinds of other functions, not just the number of processors.

I call my mk script and run ./mk chmod 755 mk to run it from ./mk in the root of my project. I also have several flags so that you can run various things with a simple command line. For example, when working on code and getting a lot of errors, I prefer to direct less output. I can do this with ./mk -l without having to ./mk -l all the heavy stuff of Unix ...

As you can see, I have -j4 in several places where it makes sense. For the -l option, I don't want to, because in this case it will eventually lead to printing several errors at the same time (I tried this before!)

 #!/bin/sh -e # # Execute make case "$1" in "-l") make -C ../BUILD/Debug 2>&1 | less -R ;; "-r") make -j4 -C ../BUILD/Release ;; "-d") rm -rf ../BUILD/Debug/doc/lpp-doc-?.*.tar.gz \ ../BUILD/Debug/doc/lpp-doc-?.* make -C ../BUILD/Debug ;; "-t") make -C ../BUILD/Debug ../BUILD/Debug/src/lpp tests/suite/syntax-print.logo g++ -std=c++14 -I rt l.cpp rt/*.cpp ;; *) make -j4 -C ../BUILD/Debug ;; esac # From the https://github.com/m2osw/lpp project 

With CMake, this will not work if, as Tsivarev mentioned, you do not create your own script. But I personally do not think it makes sense to call make from your make script. Plus, this can disrupt the build process, which will not expect this strange script. Finally, my script, as I already mentioned, allows me to change the settings depending on the situation.

0
source

Source: https://habr.com/ru/post/1262895/


All Articles