web-dev-qa-db-fra.com

Ignorer les indicateurs de compilation pour des fichiers uniques

J'aimerais utiliser un ensemble global d'indicateurs pour compiler un projet, ce qui signifie que, dans mon fichier CMakeLists.txt de niveau supérieur, j'ai spécifié:

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

Cependant, pour un fichier spécifique (disons "foo.cpp") dans un sous-répertoire, je souhaite faire basculer les indicateurs de compilation pour ne pas appliquer -Weffc ++ (la bibliothèque commerciale incluse ne peut pas être modifiée). Pour simplifier la situation en utilisant uniquement -Wall, j'ai essayé:

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

, qui n'a pas fonctionné. J'ai aussi essayé

SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )

et

ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )

, dans lequel ni a fonctionné.

Enfin, j'ai essayé de supprimer cette définition:

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

, ce qui n’a pas non plus fonctionné (c’est-à-dire que je reçois beaucoup de mises en garde concernant la style de la bibliothèque commerciale). (** Remarque: les avertissements sont supprimés si je ne réinclus pas la directive -Weffc ++ après la création de l'exécutable.)

J'ai aussi essayé d'enlever temporairement les drapeaux de compilation: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , mais cela n'a pas aidé.

N'y a-t-il pas une solution élégante à cela?

93
J.B. Brown

Vos tentatives ci-dessus ajoutent des indicateurs supplémentaires à votre fichier/cible plutôt que de les écraser comme vous semblez l’attendre. Par exemple, à partir de la documentation pour Propriétés sur les fichiers source - COMPILE_FLAGS :

Ces indicateurs seront ajoutés à la liste des indicateurs de compilation lors de la création de ce fichier source.

Vous devriez pouvoir contrer le drapeau -Weffc++ Pour foo.cpp en faisant

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

Cela devrait avoir pour effet d'ajouter -Wno-effc++ Après -Weffc++ Dans la commande du compilateur et ce dernier paramètre l'emporte. Pour voir la commande complète et vérifier que c'est bien le cas, vous pouvez faire

make VERBOSE=1

En passant, l’un des responsables de la GNU La bibliothèque standard C++ présente un avis assez négatif sur -Weffc++ Dans cette réponse .

Un autre point est que vous utilisez abusivement add_definitions dans le sens où vous utilisez ceci pour les indicateurs du compilateur plutôt que pour les définitions de pré-traitement prévues.

Il serait préférable d'utiliser add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

ou pour les versions de CMake <3.0 faire quelque chose de plus semblable à:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

En réponse à d'autres questions dans les commentaires ci-dessous, je pense qu'il est impossible de supprimer de manière fiable un indicateur sur un seul fichier. La raison en est que pour tout fichier source donné, il a le COMPILE_OPTIONS et COMPILE_FLAGS1 de sa cible appliquée, mais celles-ci n'apparaissent dans aucune des propriétés de ce fichier source.

Vous pouvez supprimer l'indicateur de problème du COMPILE_OPTIONS De la cible, puis l'appliquer individuellement à chacune des sources de la cible, en l'omettant du fichier source spécifique, si nécessaire.

Cependant, bien que cela puisse fonctionner dans de nombreux scénarios, cela pose quelques problèmes.

Premier - propriétés des fichiers sources n'incluez pas COMPILE_OPTIONS, Seulement COMPILE_FLAGS. C'est un problème car le COMPILE_OPTIONS D'une cible peut inclure expressions du générateur , mais COMPILE_FLAGS Ne les prend pas en charge. Vous devez donc adapter les expressions du générateur lors de la recherche de votre drapeau. Vous devrez peut-être même "analyser" les expressions du générateur si votre drapeau est contenu dans un ou plusieurs pour voir s'il doit être appliqué de nouveau au reste. fichiers source.

Deuxièmement - depuis CMake v3.0, les cibles peuvent spécifier INTERFACE_COMPILE_OPTIONS . Cela signifie qu'une dépendance de votre cible peut ajouter ou remplacer le COMPILE_OPTIONS De votre cible via son INTERFACE_COMPILE_OPTIONS. Il vous faudra donc parcourir de manière récursive toutes les dépendances de votre cible (tâche particulièrement ardue, car la liste de LINK_LIBRARIES pour la cible peut également contenir des expressions de générateur) pour rechercher celles qui appliquez l'indicateur de problème et essayez également de le supprimer de la cible INTERFACE_COMPILE_OPTIONS de ces cibles.

À ce stade de complexité, je souhaiterais soumettre un correctif à CMake afin de fournir la fonctionnalité permettant de supprimer un indicateur spécifique sans condition d'un fichier source.


1: Notez que contrairement à la propriété COMPILE_FLAGS Sur les fichiers source, la propriété COMPILE_FLAGS Sur les cibles est obsolète.

112
Fraser

En ajoutant simplement à la bonne réponse de @ Fraser.

Si vous souhaitez ajouter l'indicateur spécial à des dossiers spécifiques, procédez comme suit:

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

ou

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

Notez que ce n’est pas recommandé d’utiliser GLOB comme indiqué ci-dessus ici

3
Levon