2016-05-13 4 views
2

С CMake 2.8+ вы можете избежать избыточного резервирования каталогов с помощью target_include_directories().SWIG и CMake: используйте информацию, предоставленную `target_include_directories()`

E.g. написав

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

.. вы просто должны связать с mylib добавить необходимую папку включают в вашей цели.

Но как я могу использовать эту информацию, когда мне нужно использовать модули CMake, которые еще не используют эту возможность? (В моем случае SWIG)

Когда я настроить SWIG проект, я в настоящее время приходится много кода много информации:

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") 

Я также должен использовать старомодный include_directories() сделать swig генератор знаю, что он должен знать:

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

в противном случае %include операторы внутри .i файлы не будут работать больше.

Конечно, я мог бы установить переменные, содержащие пути, но тогда я бы предоставить информацию, которую я хотел, чтобы избавиться от ..

Есть ли способ, чтобы либо извлечь информацию каталога из мишени или (лучше, конечно,) сделать модуль SWIG CMake правильно использовать его?

Мое текущее решение:

С некоторыми (очень красивый) CMake магии вы можете автоматизировать список всех файлов заголовков из интерфейсной части библиотеки и набор включаемых каталогов:

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() 

в можно использовать следующим образом:

swig_add_library_dependencies(<swig_module_name> "library1;library2") 

или дискретно, как это:

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

Недостатки:

  • использует GLOB_RECURSE
  • работают только если target_include_directories были использованы правильно
  • создает зависимости для всех файлов заголовков, найденных в включают каталоги
+1

Как отмечается в документации о 'target_include_directories ', при использовании с ключевым словом PUBLIC он заполняет [INTERFACE_INCLUDE_DIRECTORIES] (https://cmake.org/cmake/help/v3.0/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.html#prop_tgt:INTERFACE_INCLUDE_DIRECTORIES) цели. Таким образом, вы можете извлечь информацию, прочитав это свойство. – Tsyvarev

+0

+1, потому что он помогает с 'include_directories', но мне все еще нужна избыточная информация для' SWIG_MODULE _ * _ EXTRA_DEPS' – frans

ответ

1

Имеют посмотрите документацию для get_property:

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

вы могли бы сделать что-то вроде этого:

get_property(MY_INCLUDES TARGET my_target PROPERTY INTERFACE_INCLUDE_DIRECTORIES) 

, чтобы получить интерфейс включают каталоги с целевой my_target и хранить их в переменной MY_INCLUDES

+0

Это действительно решит проблему с 'include_directories' - но вам все равно придется что-то придумывать для' SWIG_MODULE _ * _ EXTRA_DEPS' , Но поскольку я прямо спросил, как извлечь эту информацию, вы, конечно, ответили на мой вопрос. Я буду держать вопрос открытым, а возиться с 'get_property' немного. – frans

+0

@frans ah Я вижу. Эти EXTRA_DEPS могут быть получены алгоритмически? Например, используя компилятор для запуска развертки зависимостей над некоторыми исходными файлами? –

+1

В настоящее время я пытаюсь написать макрос CMake, который выполняет итерации через INTERFACE_INCLUDE_DIRECTORIES. Я добавлю свои результаты к моему вопросу. – frans

Смежные вопросы