Gestion des dépendances de fichiers d'en-tête avec cmake
J'utilise CMake sur un petit projet C++ et jusqu'à présent ça marche très bien... avec une torsion: x
quand je change un fichier d'en-tête, il nécessite généralement de recompiler un certain nombre de fichiers sources (ceux qui l'incluent, directement ou indirectement), mais il semble que cmake ne détecte qu'une partie des fichiers sources à recompiler, conduisant à un État corrompu. Je peux contourner cela en éliminant le projet et en reconstruisant à partir de zéro, mais ceci contourne l'objectif d'utiliser un utilitaire make: uniquement recompiler ce qui est nécessaire.
donc, je suppose que je fais quelque chose de mal.
mon projet est très simplement organisé:
- un répertoire supérieur où se trouvent toutes les ressources, les listes principales.txt se trouve 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, les listes cmakel de src.txt se trouve là
- a CMakeLists.txt par sous-répertoire dans le répertoire" src
Le répertoire principal est:
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 de sub3
qui dépend de sub2
qui dépend de sub1
Et un exemple de 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 pointer mon erreur à moi, la recherche ici ou sur CMake n'a rien donné donc je suppose que c'est très facile ou devrait travailler hors de la boîte...
(pour référence, j'utilise la version 2.8.2 de cmake sur MSYS)
MODIFIER :
grâce à la suggestion de Bill, j'ai vérifié le fichier depend.make
généré par CMake, et il est en effet manquant (sévèrement). Voici un exemple:
src/sub3/CMakeFiles/sub3.dir/File1.cpp.obj: ../src/sub3/File1.cpp
ouais, c'est tout, non de l'inclut étaient référencés à tous :x
4 réponses
vous devriez regarder les fichiers depend.make
dans votre arborescence binaire. Ce sera dans CMakeFiles/target.dir/depend.make
. Essayez de trouver l'un de ceux qui est manquant .h
le fichier que vous pensez qu'il devrait avoir. Ensuite, créez un rapport de bogue pour cmake ou envoyez un courriel à la liste de diffusion cmake.
je viens de taper le même numéro. Après avoir changé les chemins dans include_directories()
d'absolu à relatif il a ajouté des dépendances appropriées.
ressemble à CMake tente de deviner quels en-têtes sont système et qui sont liés au projet. Je soupçonne que les répertoires qui commencent par /
passent par -isystem /some/path
et ne sont donc pas présentés dans les dépendances générées.
si vous ne pouvez pas remplacer ${FOO_SOURCE_DIR}
par le chemin relatif, Vous pouvez essayer de calculer chemin relatif en utilisant les fonctions CMake appropriées. C'est-à-dire:
file(RELATIVE_PATH FOO_SOURCE_REL_DIR
${CMAKE_CURRENT_SOURCE_DIR}
${FOO_SOURCE_DIR}/.)
include_directories(${FOO_SOURCE_REL_DIR}/include)
apparemment, cmake supprime les chemins d'inclusion du système des arbres de dépendance (merci @ony pour cet indice). Cela a probablement du sens la plupart du temps, mais parfois cmake ne sait pas ce que le compilateur pense être un chemin système ou pas. Nous utilisons une construction gcc personnalisée qui ignore /usr/include
, mais cmake pense qu'elle ne l'ignore pas. Pour forcer cmake à faire de /usr/include
une dépendance qui n'est pas optimisée, essayez cette astuce: préparez /.
au chemin.
j'essaie de faire en sorte que toutes les dépendances des bibliothèques utilisent la fonctionnalité de dépendance cmake, y compris certaines bibliothèques" tierces " qui ne sont pas toujours installées par défaut sur Linux ou même disponibles. Par exemple, la compression Z-lib.
la cible d'interface suivante fonctionnait très bien si les inclusions Z lib n'étaient pas dans /usr/include
, mais se casseraient si elles l'étaient.
find_package(ZLIB REQUIRED)
message(status "found zlib ${ZLIB_LIBRARIES}")
message(status "found zlib includes ${ZLIB_INCLUDE_DIRS}")
target_link_libraries(zlib_target INTERFACE ${ZLIB_LIBRARIES})
target_include_directories(zlib_target INTERFACE ${ZLIB_INCLUDE_DIRS})
j'ai changé la dernière ligne en
target_include_directories(zlib_target INTERFACE /.${ZLIB_INCLUDE_DIRS})
et cela a fonctionné. Maintenant les cibles qui dépendaient de zlib_target
obtiendraient automatiquement -I/./usr/include
pendant la compilation.
avez-vous lancé cmake avant ou après avoir ajouté les includes à vos fichiers cpp?
j'ai rencontré ce problème et j'ai relancé cmake. J'avais ajouté le comprennent post-cmake.