web-dev-qa-db-fra.com

Comment configurer des builds parallèles portables dans CMake?

Est-il possible d'une manière ou d'une autre d'avoir une construction parallèle, quel que soit l'outil de construction utilisé?

Sous Unix, nous pouvons ajouter make -jN où N est le nombre de threads, et sous Windows j'ai ajouté au CXX_FLAG "/MP" qui est ensuite utilisé dans Visual Studio pour construire en parallèle ... (?) Comment puis-je rendre ma version telle que CMAKE_MAKE_PROGRAM n'est pas toujours étendu lorsque j'exécute CMake?

Qu'est-ce qu'une solution générale?

Je suis venu avec ceci:

# 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()
39
Gabriel

Avec CMake 3.12, c'est possible. D'après les notes de version:

Le mode de l'outil de construction "cmake (1)" ("cmake –build") a obtenu les options "- parallel []" et "-j []" pour spécifier un niveau de construction parallèle. Ils correspondent aux options correspondantes de l'outil de génération natif.

Comme mentionné par dkg , vous pouvez également définir la variable d'environnement CMAKE_BUILD_PARALLEL_LEVEL.

Liens vers la documentation de CMake:

24
usr1234567

Si vous avez CMake v2.8.8 ou supérieur, vous pouvez utiliser Ninja comme alternative de GNU make :

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

ou

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

Comme vous pouvez le voir, pas besoin d'utiliser CMAKE_MAKE_PROGRAM, la construction est exécutée en parallèle par défaut, optimisant le nombre de travaux en fonction des cœurs CPU disponibles.

Ninja est basé sur une configuration JSON de bas niveau pour accélérer la phase de démarrage. Par conséquent, sa configuration JSON n'est pas facile à écrire à la main, et je la génère toujours à l'aide d'un outil/IDE de haut niveau:

Comme une génération C++ nécessite souvent beaucoup de mémoire, votre ordinateur doit fournir autant de mémoire que le nombre de cœurs de processeur.

11
olibre

Vous ne pouvez pas faire cette multiplateforme. L'option -jN est un paramètre à créer et ne fait pas partie du Makefile généré. Cependant, vous pouvez demander à CMake de générer un script Bash qui s'exécute pour votre projet à l'aide de -jN (où le script recherche le nombre de cœurs que vous avez).

3
bossbarber

J'ai décidé d'écrire un script parallelmake.sh Pour les générateurs basés sur Unix Makefiles. Cela se fait ici: https://github.com/gabyx/ApproxMVBB

Et les parties pertinentes du fichier CMake:

https://github.com/gabyx/ApproxMVBB/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()
# ========================================================================================================================================
2
Gabriel