Utilisation de cmake pour créer principal et des sous-projets, et être en mesure de compiler séparément
AVERTISSEMENT: je suis nouvelle CMakeLists.txt j'ai un travail de mise en œuvre et souhaite améliorer et de renforcer, problème décrit ci-dessous:
Si je veux root/sub-directories/
comme sous-projets distincts, qui peut être compilé à l'aide de la personne CMakeLists.txts
dans leurs dossiers, je me retrouve littéralement le copier-coller presque la totalité de fichiers racine CMakeLists.txt
par sous-répertoire.
Je me demandais si il ya une meilleure façon d'avoir un projet principal et ensuite des sous-projets partagés dépendances de projet principal et peut être compilé sans cmake
-ing la racine CMakeLists.txt
. Ma structure de répertoire est;
CMakeLists.txt (racine du projet)
| __ sub_dir-1
| __ | __ CMakeLists.txt (sous-projet)
| __ sub_dir-2
| __ | __ CMakeLists.txt (sous-projet)
| __ sub_dir-3
| __ | __ CMakeLists.txt (sous-projet)
...
Essentiellement, je veux être en mesure de:
cmake root/CMakeLists.txt
, ce qui crée un ensemble du projet qui comprend les sous-projets (j'ai déjà cette mise en œuvre à l'aide des CMakeLists.txts à l'intérieur des sous-répertoires.cmake root/sub-dir/CMakeLists.txt
et seulement compiler le sous-projet, qui, pour l'essentiel retrouve aussi les dépendances nécessaires et comprend de peut-être.cmake
comprend ouroot/CMakeLists.txt
. Quelle est la meilleure façon d'aborder cette structure;- tout en conservant le premier point d'avoir la capacité de le compiler en tant que l'ensemble d'un projet.
- Et aussi de ne pas encombrement la
sub-dir/CMakeLists.txt
trop avec le code redondant?
Apprécier toutes les suggestions! Merci.
include()
, function()
/macro()
, variables. Vous pouvez avoir des sous-projet conscient, qu'ils soient construire seul ou en tant que partie de la racine d'un projet via la vérification des variables/cibles/fonctions et prendre les mesures appropriées. Juste essayer de programmer ce que vous voulez.Il y a une grande différence entre être capable de configurer (cmake) projet individuellement et être en mesure de compiler (make) individuellement. Mon expérience est que vous pouvez obtenir assez loin par l'exécution de cmake om le répertoire supérieur, puis spécifiez ce que vous voulez construire avec faire:
cmake <root-dir>; make sub-project1
. Ce qui est le plus important pour vous?les deux sont important, vraiment, je veux être en mesure de les configurer à l'aide de
cmake
et puis compiler à l'aide de make
comme des sous-projets ainsi que d'un projet principal.Je sais qu'il y a de nombreuses façons, j'espérais que quelqu'un pourrait m'indiquer un moyen efficace, comme je l'ai répertorié quelques restrictions, que j'aimerais vous satisfaire. Vous n'auriez pas un exemple de ce dont je pourrais suivre?
Efficacité de l'une ou l'autre approche hautement dépend de la situation concrète vous avez. L'approche la plus efficace pour une situation serait trop compliqué dans d'autres situations. Fournir certains (simplifié) du code, qui est similaire entre la racine de votre projet et de sous-projet, et je (ou quelqu'un d'autre) vous montrent le chemin, vous pouvez réduire la duplication de code.
OriginalL'auteur Blizzard | 2016-03-01
Vous devez vous connecter pour publier un commentaire.
Il y a quelques stratégies qui peuvent travailler, dont certaines pourraient être combinés.
STRATÉGIE 1:
Si vous utilisez le
Unix Makefiles
générateur avec CMake, puis simplement en invoquantmake
de la sortie de la construction dir qui correspond à la sous-répertoire que vous voulez construire devrait largement accomplir ce que vous décrivez. Les cibles à partir d'autres répertoires ne se construit que si elles sont nécessaires par une cible pour le sous-répertoire que vous construisez dans (ou un sous-répertoire ci-dessous). Ainsi, alors que vous n'lancer CMake à partir du répertoire racine, il vous reste qu'à construire le sous-répertoire(s) que vous souhaitez.Pour: Facile, ne nécessite aucune modification de votre
CMakeLists.txt
fichiers.Contre: ne fonctionne qu'avec
Unix Makefiles
générateur, exige de toutes les parties de l'arbre source de traitement par CMake si vous voulez construire ou non.STRATÉGIE 2:
Comme mentionné par @Emil dans son commentaire à votre question, vous pouvez simplement construire la cible spécifique(s) que vous voulez à partir du niveau supérieur de construire votre répertoire de sortie. Cela suppose que vous savez les objectifs pertinents que vous voulez construire ou de mettre une autre manière, il vous oblige à avoir une bonne compréhension de ce que les cibles sont fournis par qui les sous-répertoires.
Pour: Souple, fonctionne avec n'importe quel CMake générateur, ne nécessite aucune modification de votre
CMakeLists.txt
fichiers.Contre: Exige une certaine connaissance de ce que chaque sous-répertoire fournit, exige de toutes les parties de l'arbre source de traitement par CMake si vous voulez construire ou non.
STRATÉGIE 3:
Dans le haut niveau
CMakeLists.txt
fichier, vous pourriez faire leadd_subdirectory()
appel pour chaque sous-répertoire dépendent d'une option variable. Cela vous permettrait de transformer l'inclusion de chaque sous-répertoire ou désactivés individuellement, vous donnant un contrôle précis sur ce qui se construit. Vous pouvez construire tout, juste un sous-répertoire ou un ensemble de sous-répertoires (plus souple que vos exigences, mais potentiellement utile).Conditionnellement y compris un sous-répertoire avec une option variable serait généralement faire quelque chose comme ceci:
Si certains sous-répertoires dépendre des autres, alors la logique d'ajouter un sous-répertoire ou de ne pas le besoin de tenir compte de cela (c'est à dire mettre en œuvre des dépendances entre les options). Il ne devrait pas être difficile à faire si nécessaire.
Pour: de Flexibilité pour construire précisément ce que un ensemble de sous-répertoires que vous voulez dans une construction, CMake n'a qu'à traiter les sous-répertoires qui vous intéressent (gain de temps énorme pour projet d'arbres et vous permet de sauter les parties problématiques de l'arborescence du projet) et fonctionne pour tout CMake générateur.
Contre: Vous avez besoin de séparer les répertoires de construction si vous souhaitez créer des sous-répertoires différents individuellement. Vous ne pouvez pas simplement
cd
à une partie différente de votre sortie de la construction de structure de répertoire et de lancer un construire à partir de là, par exemple. Vous avez toujours seulement un arbre source, mais vous avez plusieurs la sortie de la construction des arbres. Dans la pratique, cela peut ne pas être un problème selon ce que vous voulez finalement à être en mesure de le faire (j'ai régulièrement construire plusieurs dirs pour une source donnée de l'arbre, mais c'est généralement pour Debug et Release, plutôt que de différents ensembles de CMake options). Nécessite aussi de comprendre les dépendances entre les sous-répertoires. Nécessite que de légers changements à haut niveauCMakeLists.txt
fichier.Nous espérons que l'une des options ci-dessus ou une combinaison de ceux-ci vous donne quelques idées pour savoir comment obtenir ce que vous visez. J'ai eu un coup d'oeil rapide au plus haut niveau
CMakeLists.txt
dans le github du projet est lié à et on dirait qu'il fait déjà l'utilisation d'options comme dans la stratégie 3, pas tout à fait pour activer/désactiver individuels sous-répertoires.cmake -option=project2
ou quelque chose comme ça? Au lieu de changer deCMakeLists.txt
chaque fois qu'ils veulent construire un projet distinct?Le point de l'ensemble de la
option()
commande est précisément pour cela. Vous pouvez définir cette option lorsque vous appelez cmake comme suit:cmake -DBUILD_SUBDIR1=ON
. CMake se souviendront que, dans son cache, de sorte que vous n'avez pas à garder de le spécifier par la suite, lors de la ré-exécution de cmake ou de faire construire votre avec faire. Leoption()
commande prend une valeur par défaut qui est utilisé si vous ne définissez pas l'option sur la ligne de commande de cmake.Du sens. Encore une fois, merci beaucoup @Craig Scott!
OriginalL'auteur Craig Scott