Manipulation des fichiers d'en-tête dépendances avec cmake
Je suis en utilisant CMake sur un petit projet C++ et pour l'instant il fonctionne très bien... avec un twist 😡
Lorsque je modifie un fichier d'en-tête, il nécessite généralement de recompiler un certain nombre de fichiers sources (ceux qui comprennent, directement ou indirectement), mais il semble que cmake ne détecte certains des fichiers source pour être recompilé, conduisant à un état corrompu. Je peux contourner le problème en essuyant le projet et de reconstruire à partir de zéro, mais cela contourne le but de l'utilisation d'un utilitaire make: recompilant seulement ce qui est nécessaire.
Donc, je suppose que je suis en train de faire quelque chose de mal.
Mon projet est très simple, il a organisé:
- un répertoire où toutes les ressources de s'asseoir, le principal CMakeLists.txt là
- un "include" répertoire où tous les en-têtes des mensonges (dans différents sous-répertoires)
- un répertoire "src", où tous les sous-répertoires pour les fichiers sources sont, la src CMakeLists.txt là
- un CMakeLists.txt par sous-répertoire dans le répertoire "src"
Le répertoire principal a:
cmake_minimum_required(VERSION 2.8)
project(FOO)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
# Compiler Options
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++0x -Wall -Wextra -Werror")
include_directories($(FOO_SOURCE_DIR)/include)
add_subdirectory(src)
Le répertoire "src":
add_subdirectory(sub1)
add_subdirectory(sub2)
add_subdirectory(sub3)
add_subdirectory(sub4)
add_executable(foo main.cpp)
target_link_libraries(foo sub1 sub2 sub3 sub4)
Où sub4
dépend sub3
qui dépend sub2
qui dépend sub1
Et un exemple d'un sous-répertoire (sub3):
set(SUB3_SRCS
File1.cpp
File2.cpp
File3.cpp
File4.cpp
File5.cpp
File6.cpp
)
add_library(sub3 ${SUB3_SRCS})
target_link_libraries(sub3 sub1 sub2)
Je serais heureux si quelqu'un pouvait point de ma faute à moi, à la recherche ici ou sur CMake n'ai pas de produire quoi que ce soit, donc je suppose que c'est très facile ou devrait travailler hors de la boîte...
(pour référence, je suis en utilisant cmake version 2.8.2 sur MSYS)
MODIFIER:
Grâce à la Loi de la suggestion, j'ai vérifié le depend.make
fichier généré par CMake, et c'est effectivement en manque (sévèrement). Voici un exemple:
src/sub3/CMakeFiles/sub3.dir/File1.cpp.obj: ../src/sub3/File1.cpp
Yep, c'est tout, non de l'inclut étaient référencés à tous 😡
- Il serait utile d'avoir plus de détails sur les fichiers qui ne sont pas compilé correctement. Le scanner de dépendances dans CMake peut certainement passer un en-tête qui comprend un autre en-tête par exemple, et de déclencher correctement une recompilation de l'dépendante du fichier source. Pouvez-vous partager un exemple minimal où vous frappez ce comportement?
- C'est assez erratique et je suis habitude de vider mon projet ici, peu grand pour une question. De votre réponse même si je comprends que ça ne devrait pas arriver... j'ai oublié de préciser que je suis sur Windows, en invoquant de la MSYS (basé sur MinGw) shell, pourrait-il être un problème ? Aussi, j'utilise cmake pour construire le LLVM/Clang projet sur MSYS ainsi, et n'a jamais eu le problème sur elle.
- Sonne comme il pourrait être un bug dans la dépendance scanner Windows/MSYS. Je ne fais pas beaucoup de travail dans ce milieu, et je me demande si vous avez jamais vu un comportement similaire à Unix Makefiles projets sur Linux/Mac ou MSVC projets.
- Je n'ai que Windows à la maison, malheureusement, jamais vu ça sur d'autres environnements pour je ne les utilise pas.
- Avez-vous essayé de liste des en-têtes dans
set(SUB3_SRCS …)
ainsi? J'ai toujours le faire, et n'avons pas rencontré de tels problèmes.
Vous devez vous connecter pour publier un commentaire.
Vous devriez regarder la
depend.make
fichiers dans votre arbre binaire. Il sera enCMakeFiles/target.dir/depend.make
. Essayez de trouver l'un de ceux qui manque un.h
fichier que vous pensez qu'il devrait avoir. Ensuite créer un rapport de bug pour cmake ou e-mail le cmake liste de diffusion.depend.make
fondamentalement, indique qu'une".obj' ne dépend que du fichier source qui les a générés, et de ne pas parler, à propos de l'inclure des fichiers. Hum...J'ai juste touché à la même question. Après la modification des chemins d'accès dans
include_directories()
absolue relative il ajouté dépendances appropriées.Ressemble à CMake essaie de deviner qui des en-têtes du système et qui sont liées à des projets. Je soupçonne que les répertoires qui commence avec
/
passé comme-isystem /some/path
et ne sont donc pas présentées dans générés dépendances.Si vous ne pouvez pas remplacer
${FOO_SOURCE_DIR}
avec chemin d'accès relatif, vous pouvez essayer de calculer le chemin relatif à l'utilisation appropriée des CMake fonctions. I. e.:Avez-vous lancer cmake avant ou après l'ajout de l'inclut à vos fichiers cpp?
Je suis tombé sur ce problème et de ré-exécuter cmake, il fixe. J'avais ajouté le comprennent post-cmake.
Apparemment cmake supprime système d'inclure les chemins de la dépendance des arbres (merci @ony pour cette astuce). C'est probablement ce sens que la plupart du temps, mais parfois cmake ne sais pas ce que le compilateur est un chemin d'accès au système ou non. Nous sommes en utilisant une mesure de gcc construire qui ignore
/usr/include
, mais cmake pense qu'il n'a pas l'ignorer. À force de cmake pour faire/usr/include
une dépendance qui n'est PAS optimisé, essayez cette astuce: ajouter/.
le chemin.Je suis en train de faire toutes les dépendances de la bibliothèque de l'utilisation de la cmake dépendance, y compris certains "3ème" bibliothèques de tiers qui ne sont pas toujours installé par défaut sur Linux ou même disponible. Par exemple, Z-lib de compression.
L'interface suivante cible a bien fonctionné si le Z lib comprend étaient pas dans
/usr/include
, mais serait briser si elles l'étaient.J'ai changé la dernière ligne de
et cela a fonctionné. Maintenant les cibles qui dépendait
zlib_target
serait d'obtenir automatiquement-I/./usr/include
lors de la compilation.