title: SWIG and CMake: make use of information provided by `target_include_directories()`
body: <p>With CMake 2.8+ you can avoid setting include directories redundantly by using <a href="https://cmake.org/cmake/help/v3.0/command/target_include_directories.html" rel="nofollow">target_include_directories()</a>. </p>
  
  <p>E.g. by writing</p>
  
  <pre><code>add_libary(mylib SHARED ${SOURCES})
  target_include_directories(mylib PUBLIC ./include)
  </code></pre>
  
  <p>.. you just have to link against <code>mylib</code> to add the needed include folder to your target.</p>
  
  <p>But how can I make use of this information when I have to use CMake modules which don't make use of this capability yet? (in my case SWIG)</p>
  
  <p>When I configure a SWIG project I currently have to hard code a lot of information:</p>
  
  <pre><code>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")
  </code></pre>
  
  <p>I also have to use the old fashioned <code>include_directories()</code> to make the <code>swig</code> generator know what it needs to know:</p>
  
  <pre><code>include_directories(
      "../long/relative/path/1/include
      "../long/relative/path/2/include)
  </code></pre>
  
  <p>Otherwise the <code>%include</code> statements inside <code>.i</code> files won't work any more.</p>
  
  <p>Of course I could set variables containing the paths but then I would provide the information I wanted to get rid of..</p>
  
  <p>Is there a way to either extract the directory information from a target or (better of course) make the SWIG CMake module correctly use it?</p>
  
  <p><strong>My current solution:</strong></p>
  
  <p>With some (very beautiful) CMake magic you can automate listing all header files from the interface part of a library and set the include directories:</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>to be used like this:</p>
  
  <pre><code>swig_add_library_dependencies(&lt;swig_module_name&gt; "library1;library2")
  </code></pre>
  
  <p>or discretely like this:</p>
  
  <pre><code>swig_add_library_dependencies(&lt;swig_module_name&gt; library1)
  swig_add_library_dependencies(&lt;swig_module_name&gt; library2)
  </code></pre>
  
  <p>Disadvantages:</p>
  
  <ul>
  <li>uses <code>GLOB_RECURSE</code></li>
  <li>only works if target_include_directories had been used correctly</li>
  <li>creates dependencies to <em>all</em> header files found in include directories</li>
  </ul>