142 votes

Répertoire de sortie/de construction de CMake

Je suis assez nouveau dans CMake, et j'ai lu quelques tutoriels sur la façon de l'utiliser, et j'ai écrit quelques 50 lignes compliquées de CMake script afin de faire un programme pour 3 compilateurs différents. Ceci conclut probablement toutes mes connaissances en CMake.

Mon problème est que j'ai du code source, dont je ne veux pas toucher/se mêler au dossier lorsque je crée le programme. Je veux que tout CMake et make les fichiers et dossiers de sortie à placer dans ../Compile/ J'ai donc modifié quelques variables dans mon script CMake pour cela, et cela a fonctionné pendant quelques temps lorsque j'ai fait quelque chose comme ça sur mon ordinateur portable :

Compile$ cmake ../src
Compile$ make

Avec cela, j'ai eu une sortie propre dans le dossier où je suis maintenant, ce qui est exactement ce que je recherche.

Maintenant, j'ai déménagé sur un autre ordinateur, et j'ai recompilé CMake 2.8.11.2, et je suis presque de retour à la case départ ! Il compile toujours la chose dans le src où mon CMakeLists.txt est situé.

La partie où je choisis le répertoire dans mon CMake script est la suivante :

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

Et maintenant, ça se termine toujours par :

-- Build files have been written to: /.../src

Est-ce que j'ai manqué quelque chose ?

137voto

Adam Bowen Points 3633

On dirait que vous voulez un construction à partir de la source . Il y a plusieurs façons de créer un build out of source.

  1. Fais ce que tu faisais, cours

    cd /path/to/my/build/folder
    cmake /path/to/my/source/folder

    ce qui amènera cmake à générer un construire l'arbre en /path/to/my/build/folder pour le arbre source en /path/to/my/source/folder .

    Une fois que vous l'avez créé, cmake se souvient de l'endroit où se trouve le dossier source - vous pouvez donc réexécuter cmake sur l'arbre de construction avec

    cmake /path/to/my/build/folder

    ou même

    cmake .

    si votre répertoire courant est déjà le dossier de construction.

  2. Pour CMake 3.13 ou plus, utilisez ces options pour définir les dossiers source et de construction

    cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
  3. Pour les anciens CMake, utilisez des options non documentées pour définir les dossiers source et de construction :

    cmake -B/path/to/my/build/folder -H/path/to/my/source/folder

    qui fera exactement la même chose que (1), mais sans se baser sur le répertoire de travail actuel.

CMake place toutes ses sorties dans le répertoire construire l'arbre par défaut, donc à moins que vous n'utilisiez libéralement ${CMAKE_SOURCE_DIR} o ${CMAKE_CURRENT_SOURCE_DIR} dans vos fichiers cmake, il ne devrait pas toucher votre arbre source .

Le plus gros problème qui peut survenir est que vous avez précédemment généré un arbre de construction dans votre arbre source (c'est-à-dire que vous avez un fichier dans la source construire). Une fois que vous avez fait cela, la deuxième partie de (1) ci-dessus entre en jeu, et cmake ne fait aucun changement aux emplacements des sources ou de la compilation. Ainsi, vous ne pouvez pas créer un build hors-source pour un répertoire source avec un build in-source . Vous pouvez résoudre ce problème assez facilement en supprimant (au minimum) CMakeCache.txt à partir du répertoire source. Il y a quelques autres fichiers (principalement dans le répertoire CMakeFiles ) que CMake génère et que vous devriez également supprimer, mais ceux-ci ne feront pas en sorte que cmake traite l'arbre des sources comme un arbre de construction.

Puisque les compilations hors source sont souvent plus souhaitables que les compilations dans les sources, vous pourriez vouloir modifier votre cmake pour exiger des compilations hors source :

# Ensures that we do an out of source build

MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${CMAKE_BINARY_DIR}" insource)
     GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${PARENTDIR}" insourcesubdir)
    IF(insource OR insourcesubdir)
        MESSAGE(FATAL_ERROR "${MSG}")
    ENDIF(insource OR insourcesubdir)
ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
    "${CMAKE_PROJECT_NAME} requires an out of source build."
)

La macro ci-dessus provient d'un module couramment utilisé appelé MacroOutOfSourceBuild . Il existe de nombreuses sources pour MacroOutOfSourceBuild.cmake sur google mais je n'arrive pas à trouver l'original et c'est assez court pour être inclus ici en entier.

Malheureusement, cmake a généralement écrit quelques fichiers au moment où la macro est invoquée, donc bien que cela vous empêche de réaliser la construction, vous devrez toujours supprimer CMakeCache.txt y CMakeFiles .

Vous pouvez trouver utile de définir les chemins dans lesquels les binaires, les bibliothèques partagées et statiques sont écrites - dans ce cas voir Comment faire pour que la sortie de cmake soit dans un répertoire 'bin' ? (avis de non-responsabilité, j'ai la réponse la plus votée à cette question... mais c'est ainsi que je suis au courant).

78voto

Angew Points 53063

Il n'est pas nécessaire de définir toutes les variables que vous définissez. CMake les définit par des valeurs par défaut raisonnables. Vous devriez définitivement no modifier CMAKE_BINARY_DIR o CMAKE_CACHEFILE_DIR . Traitez-les comme étant en lecture seule.

Tout d'abord, supprimez le fichier de cache problématique existant dans le répertoire src :

cd src
rm CMakeCache.txt
cd ..

Puis retirez tous les set() commande et fait :

cd Compile && rm -rf *
cmake ../src

Tant que vous êtes en dehors du répertoire source lorsque vous exécutez CMake, il ne modifiera pas le répertoire source à moins que votre CMakeList lui demande explicitement de le faire.

Une fois que cela fonctionne, vous pouvez regarder où CMake place les choses par défaut, et seulement si vous n'êtes pas satisfait des emplacements par défaut (comme la valeur par défaut de l'option EXECUTABLE_OUTPUT_PATH ), ne modifiez que ceux dont vous avez besoin. Et essayez de les exprimer par rapport à CMAKE_BINARY_DIR , CMAKE_CURRENT_BINARY_DIR , PROJECT_BINARY_DIR etc.

Si vous regardez la documentation de CMake, vous verrez des variables partitionnées en sections sémantiques. Sauf pour très Dans des circonstances spéciales, vous devriez traiter toutes les variables listées sous "Variables qui fournissent des informations" comme étant en lecture seule dans CMakeLists.

11voto

Avi Tevet Points 568

Transformer mon commentaire en réponse :

Au cas où quelqu'un aurait fait comme moi, c'est-à-dire commencer par mettre tous les fichiers de construction dans le répertoire source :

cd src
cmake .

cmake va mettre un tas de fichiers de construction et de fichiers de cache ( CMakeCache.txt , CMakeFiles , cmake_install.cmake etc.) dans le src dir.

Pour passer à un build out of source, j'ai dû supprimer tous ces fichiers. Ensuite, j'ai pu faire ce que @Angew a recommandé dans sa réponse :

mkdir -p src/build
cd src/build
cmake ..

8voto

damkrat Points 327

A partir de Wiki CMake :

CMAKE_BINARY_DIR si vous construisez en source, c'est le même que CMAKE_SOURCE_DIR, sinon c'est le répertoire de premier niveau de votre arbre de construction

Comparez ces deux variables pour déterminer si la construction hors source a été lancée.

6voto

Michał Walenciak Points 1079

Vous ne devriez pas compter sur un nom de répertoire de construction codé en dur dans votre script, ainsi la ligne avec ../Compile doit être modifié.

C'est parce que l'utilisateur devrait pouvoir décider où compiler.

Au lieu de cela, utilisez l'une des variables prédéfinies : http://www.cmake.org/Wiki/CMake_Useful_Variables (cherchez CMAKE_BINARY_DIR y CMAKE_CURRENT_BINARY_DIR )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X