2016-05-13 1 views
2

Avec CMake 2.8+, vous pouvez éviter de définir des répertoires d'inclusion de manière redondante en utilisant target_include_directories().SWIG et CMake: utiliser les informations fournies par `target_include_directories()`

E.g. en écrivant

add_libary(mylib SHARED ${SOURCES}) 
target_include_directories(mylib PUBLIC ./include) 

.. il vous suffit de créer un lien contre mylib pour ajouter le nécessaire inclure le dossier à votre cible. Mais comment puis-je utiliser cette information lorsque je dois utiliser des modules CMake qui n'utilisent pas encore cette fonctionnalité? (Dans mon cas SWIG)

Lorsque je configure un projet SWIG J'ai actuellement coder en dur beaucoup d'informations:

set(SWIG_MODULE_${PYTHON_MODULE_NAME}_EXTRA_DEPS 
    "../long/relative/path/1/include/some/header1.h" 
    "../long/relative/path/1/include/some/header2.h" 
    "../long/relative/path/2/include/some/header1.h" 
    "../long/relative/path/2/include/some/header2.h") 

Je dois aussi utiliser l'ancienne include_directories() pour faire le générateur swig savoir ce que il a besoin de savoir:

include_directories(
    "../long/relative/path/1/include 
    "../long/relative/path/2/include) 

Sinon, les %include instructions contenues dans les fichiers .i ne fonctionneront plus.

Bien sûr, je pourrais définir des variables contenant les chemins, mais je fournirais les informations que je voulais me débarrasser de ..

est-il un moyen soit d'extraire les informations de répertoire à partir d'une cible ou (mieux bien sûr) faire en sorte que le module SWIG CMake l'utilise correctement?

Ma solution actuelle:

Avec un peu (très beau) magie CMake vous pouvez automatiser la liste de tous les fichiers d'en-tête de la partie d'interface d'une bibliothèque et définir les inclure des répertoires:

function(swig_add_library_dependencies swig_module library_names) 
    foreach(library_name ${library_names}) 
     get_property(LIBRARY_INCLUDES 
        TARGET ${library_name} 
        PROPERTY INTERFACE_INCLUDE_DIRECTORIES) 
     foreach(INCLUDE_PATH ${LIBRARY_INCLUDES}) 
      include_directories(${INCLUDE_PATH}) 
      file(GLOB_RECURSE header_files "${INCLUDE_PATH}/*.h") 
      list(APPEND SWIG_MODULE_${swig_module}_EXTRA_DEPS ${header_files}) 
      # export variable to parent scope 
      set(SWIG_MODULE_${swig_module}_EXTRA_DEPS 
       ${SWIG_MODULE_${swig_module}_EXTRA_DEPS} PARENT_SCOPE) 
     endforeach() 
    endforeach() 
endfunction() 

à être utilisé comme ceci:

swig_add_library_dependencies(<swig_module_name> "library1;library2") 

ou comme ceci discrètement:

swig_add_library_dependencies(<swig_module_name> library1) 
swig_add_library_dependencies(<swig_module_name> library2) 

Inconvénients:

  • utilise GLOB_RECURSE
  • ne fonctionne que si target_include_directories avait été utilisé correctement
  • crée des dépendances à tous les fichiers d'en-tête trouvés dans inclure des répertoires
+1

Comme il est indiqué dans la documentation sur les 'target_include_directories ', lorsqu'il est utilisé avec le mot clé PUBLIC, il remplit [INTERFACE_INCLUDE_DIRECTORIES] (https://cmake.org/cmake/help/v3.0/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html#prop_tgt:INTERFACE_INCLUDE_DIRECTORIES) de la cible. Ainsi, vous pouvez extraire des informations en lisant cette propriété. – Tsyvarev

+0

+1 car cela aide 'include_directories' mais j'ai encore besoin d'informations redondantes pour' SWIG_MODULE _ * _ EXTRA_DEPS' – frans

Répondre

1

Avoir une regardez la documentation pour get_property:

https://cmake.org/cmake/help/v3.0/command/get_property.html?highlight=get_property

vous feriez quelque chose comme ceci:

get_property(MY_INCLUDES TARGET my_target PROPERTY INTERFACE_INCLUDE_DIRECTORIES) 

pour obtenir l'interface comprend des répertoires de la my_target cible et de les stocker dans les MY_INCLUDES variables

+0

Cela résoudrait en effet le problème avec 'include_directories' - mais il faudrait encore inventer quelque chose pour la partie' SWIG_MODULE _ * _ EXTRA_DEPS' . Mais puisque j'ai explicitement demandé comment extraire cette information, vous avez répondu à ma question bien sûr. Je vais garder la question ouverte tout en bricolant avec 'get_property' un peu .. – frans

+0

@frans ah je vois. Ces EXTRA_DEPS, peuvent-ils être acquis algorithmiquement? Par exemple en utilisant un compilateur pour exécuter un balayage de dépendance sur certains fichiers source? –

+1

actuellement j'essaye d'écrire une macro de CMake qui itère sur les INTERFACE_INCLUDE_DIRECTORIES - j'ajouterai mes résultats à ma question. – frans