Pregunta

¿Es de alguna manera posible tener una compilación paralela sin importar qué herramienta de compilación se utilice?

En Unix podemos agregar make -jN donde N es el número de subprocesos, y en Windows agregué al CXX_FLAG "/MP" que luego se usa en Visual Studio para compilar en paralelo...(?) ¿Cómo puedo hacer que mi versión sea tal que CMAKE_MAKE_PROGRAM ¿No siempre está extendido cuando ejecuto CMake?

¿Qué es una solución general?

Se me ocurrió esto:

# Add some multithreaded build support
MARK_AS_ADVANCED(MULTITHREADED_BUILD)
set(MULTITHREADED_BUILD 12 CACHE STRING "How many threads are used to build the project")
if(MULTITHREADED_BUILD)
    if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
            message(STATUS ${CMAKE_BUILD_TOOL})
            set(CMAKE_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM} -j${MULTITHREADED_BUILD}")
            message(STATUS "Added arguments to CMAKE_BUILD_TOOL: ${CMAKE_MAKE_PROGRAM}")
    elseif(MSVC)
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
      message(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
    endif()
endif()
¿Fue útil?

Solución

Con CMake 3.12 esto es posible.De las notas de la versión:

El modo de herramienta de construcción "CMake (1)" ("CMake –Build") obtuvo opciones "-Paralelo [] y "-J [] para especificar un nivel de construcción paralelo.Se asignan a las opciones correspondientes de la herramienta de compilación nativa.

Como lo menciona dkg, también puedes configurar la variable de entorno CMAKE_BUILD_PARALLEL_LEVEL.

Enlaces a la documentación de CMake:

Otros consejos

Si tiene CMake v2.8.8 o superior, puede usar ninja como alternativa de ÑU make:

mkdir build
cd    build
cmake -G Ninja ..
ninja              # Parallel build (no need -j12)

o

mkdir build
cd    build
cmake -G Ninja ..
cmake --build .    # Parallel build using Ninja

Como puedes ver, no es necesario utilizar CMAKE_MAKE_PROGRAM, la compilación se ejecuta en paralelo de forma predeterminada, optimizando la cantidad de trabajos según los núcleos de CPU disponibles.

Ninja se basa en una configuración JSON de bajo nivel para acelerar la fase de inicio.Por lo tanto, su configuración JSON no es fácil de escribir a mano y siempre la genero usando una herramienta/IDE de alto nivel:

Como una compilación de C++ a menudo requiere mucha memoria, su computadora debe proporcionar tanta memoria como número de núcleos de CPU.

Como lo señala Ruslán, Chacer 3.12 (2018) tiene un nueva opción cmake --build -j <N> para limitar la construcción a <N> núcleos (trabajos) limitando así el consumo de memoria (ver también el documentación).Si usa una versión anterior de CMake, aún puede usar cmake --build -- -j <N>.La opción -- le dice a CMake que pase el resto directamente a la herramienta de creación subyacente, aquí está Ninja.

No puedes hacer esto multiplataforma.La opción -jN es un parámetro a crear y no forma parte del Makefile generado.Sin embargo, puede hacer que CMake genere un script Bash que ejecute make para su proyecto usando -jN (donde el script busca la cantidad de núcleos que tiene).

Me he decidido a escribir un parallelmake.sh guión para Unix Makefiles-generadores basados ​​en.Esto se hace aquí: https://github.com/gabyx/AproxMVBB

Y las partes relevantes en el archivo CMake:

https://github.com/gabyx/AproxMVBB/blob/master/CMakeLists.txt#L89

# Add some multithreaded build support =====================================================================================================
MARK_AS_ADVANCED(MULTITHREADED_BUILD)
SET(MULTITHREADED_BUILD ON CACHE BOOL "Parallel build with as many threads as possible!")
if(MULTITHREADED_BUILD)
    if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
            file(COPY ${ApproxMVBB_ROOT_DIR}/cmake/parallelmake.sh DESTINATION ${PROJECT_BINARY_DIR}
                FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
                NO_SOURCE_PERMISSIONS
            )
            SET(CMAKE_MAKE_PROGRAM "${PROJECT_BINARY_DIR}/parallelmake.sh")
            MESSAGE(STATUS "Set make program to ${PROJECT_BINARY_DIR}/parallelmake.sh")
    elseif(MSVC)
      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" "/MP")
      MESSAGE(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
    endif()
endif()
# ========================================================================================================================================
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top