130 votes

Remplacer les drapeaux de compilation pour les fichiers uniques

Je voudrais utiliser un ensemble global de drapeaux pour compiler un projet, ce qui signifie que dans mon fichier CMakeLists.txt de premier niveau, 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 veux changer les drapeaux de compilation pour ne pas appliquer -Weffc++ (inclus commercialement). de compilation pour ne pas appliquer -Weffc++ (bibliothèque commerciale incluse que je ne peux pas modifier). Pour simplifier la situation et n'utiliser que -Wall, j'ai essayé :

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

ce qui n'a pas fonctionné. J'ai également essayé

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

y

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

dans lequel aucun des deux n'a travaillé.

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

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

qui n'a pas non plus fonctionné (ce qui signifie que je reçois de nombreux avertissements de style concernant la bibliothèque commerciale). (**Note : Les avertissements sont supprimés si je ne ré-inclue pas la directive -Weffc++ après la construction de l'exécutable).

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

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

145voto

Fraser Points 20579

Vos tentatives ci-dessus ajoutent des drapeaux supplémentaires à votre fichier/cible plutôt que de l'écraser comme vous semblez l'espérer. Par exemple, dans la documentation de [Propriétés sur les fichiers sources - COMPILE_FLAGS](http://www.cmake.org/cmake/help/v3.3/prop_sf/COMPILE_FLAGS.html "CMake v3.3 documentation for "COMPILE_FLAGS" source file property") :

Ces drapeaux seront ajoutés à la liste des drapeaux de compilation lorsque ce fichier source sera construit.

Vous devriez être en mesure de contrecarrer la -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 c'est ce dernier paramètre qui l'emporte. Pour voir la commande complète et vérifier que c'est bien le cas, vous pouvez faire

make VERBOSE=1

Pour l'anecdote, l'un des mainteneurs de la bibliothèque standard GNU C++ a une opinion assez négative sur -Weffc++ en cette réponse .

Un autre point est que vous utilisez mal [add_definitions](http://www.cmake.org/cmake/help/v3.3/command/add_definitions.html "CMake v3.3 documentation for "add_definitions" command") dans le sens où vous l'utilisez pour les drapeaux du compilateur plutôt que pour les définitions prévues du préprocesseur.

Il serait préférable d'utiliser [add_compile_options](http://www.cmake.org/cmake/help/v3.3/command/add_compile_options.html "CMake v3.3 documentation for "add_compile_options" command")

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

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

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

En réponse à d'autres questions posées dans les commentaires ci-dessous, je crois qu'il est impossible d'évaluer de manière fiable la qualité de l'eau. supprimer un drapeau sur un seul dossier. La raison est que pour tout fichier source donné, il a l'indicateur [COMPILE_OPTIONS](http://www.cmake.org/cmake/help/v3.3/prop_tgt/COMPILE_OPTIONS.html "CMake v3.3 documentation for "COMPILE_OPTIONS" target property") y [COMPILE_FLAGS](http://www.cmake.org/cmake/help/v3.3/prop_tgt/COMPILE_FLAGS.html "CMake v3.3 documentation for "COMPILE_FLAGS" target property") 1 de sa cible appliquée, mais ceux-ci n'apparaissent dans aucune des propriétés de ce fichier source.

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

Cependant, bien que cette solution puisse fonctionner dans de nombreux cas, elle présente quelques problèmes.

Premièrement - propriétés des fichiers sources n'incluent pas COMPILE_OPTIONS seulement COMPILE_FLAGS . C'est un problème car le COMPILE_OPTIONS d'une cible peut inclure expressions de générateur mais COMPILE_FLAGS ne les soutient pas. Vous devrez donc tenir compte des expressions de générateur lors de la recherche de votre indicateur, et vous devrez peut-être même "analyser" les expressions de générateur si votre indicateur est contenu dans une ou plusieurs d'entre elles pour voir s'il doit être réappliqué aux autres fichiers source.

Deuxièmement - depuis CMake v3.0, les cibles peuvent spécifier [INTERFACE_COMPILE_OPTIONS](http://www.cmake.org/cmake/help/v3.3/prop_tgt/INTERFACE_COMPILE_OPTIONS.html "CMake v3.3 documentation for "INTERFACE_COMPILE_OPTIONS" target property") . Cela signifie qu'une dépendance de votre cible peut ajouter ou remplacer l'attribut COMPILE_OPTIONS via son INTERFACE_COMPILE_OPTIONS . Vous devrez donc itérer de manière récursive à travers toutes les dépendances de votre cible (ce qui n'est pas une tâche particulièrement facile puisque la liste de [LINK_LIBRARIES](http://www.cmake.org/cmake/help/v3.3/prop_tgt/LINK_LIBRARIES.html "CMake v3.3 documentation for "LINK_LIBRARIES" target property") pour la cible peut également contenir des expressions de générateur) pour trouver celles qui appliquent l'indicateur de problème, et essayer de le supprimer de ces cibles. INTERFACE_COMPILE_OPTIONS aussi.

À ce stade de complexité, je chercherais à soumettre un correctif à CMake pour fournir la fonctionnalité de supprimer un drapeau spécifique sans condition d'un fichier source.


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

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