UseSWIG: add support of target property INCLUDE_DIRECTORIES consumption

Fixes: #18003
diff --git a/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst b/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst
new file mode 100644
index 0000000..2a2721f
--- /dev/null
+++ b/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES
+--------------------------------------
+
+* Module ``UseSWIG`` gains capability to manage target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` for ``SWIG`` compilation.
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 7127b8f..851101b 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -96,6 +96,13 @@
   :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
   :prop_sf:`COMPILE_OPTIONS`.
 
+``USE_TARGET_INCLUDE_DIRECTORIES``
+  If set to ``TRUE``, contents of target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` will be forwarded to ``SWIG`` compiler.
+  If set to ``FALSE`` target property :prop_tgt:`INCLUDE_DIRECTORIES` will be
+  ignored. If not set, target property ``SWIG_USE_TARGT_INCLUDE_DIRECTORIES``
+  will be considered.
+
 ``GENERATED_INCLUDE_DIRECTORIES``, ``GENERATED_COMPILE_DEFINITIONS`` and ``GENERATED_COMPILE_OPTIONS``
   Add custom flags to the C/C++ generated source. They will fill, respectively,
   properties :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
@@ -127,6 +134,13 @@
     set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2)
     set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb)
 
+``SWIG_USE_TARGET_INCLUDE_DIRECTORIES``
+  If set to ``TRUE``, contents of target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` will be forwarded to ``SWIG`` compiler.
+  If set to ``FALSE`` or not defined, target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` will be ignored. This behavior can be
+  overridden by specifying source property ``USE_TARGET_INCLUDE_DIRECTORIES``.
+
 ``SWIG_GENERATED_INCLUDE_DIRECTORIES``, ``SWIG_GENERATED_COMPILE_DEFINITIONS`` and ``SWIG_GENERATED_COMPILE_OPTIONS``
   These properties will populate, respectively, properties
   :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
@@ -310,6 +324,14 @@
   endif()
   set (property "$<TARGET_PROPERTY:${name},SWIG_INCLUDE_DIRECTORIES>")
   list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:$<TARGET_GENEX_EVAL:${name},${property}>,$<SEMICOLON>-I>>")
+  set (property "$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>")
+  get_source_file_property(use_target_include_dirs "${infile}" USE_TARGET_INCLUDE_DIRECTORIES)
+  if (use_target_include_dirs)
+    list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
+  elseif(use_target_include_dirs STREQUAL "NOTFOUND")
+    # not defined at source level, rely on target level
+    list (APPEND swig_source_file_flags "$<$<AND:$<BOOL:$<TARGET_PROPERTY:${name},SWIG_USE_TARGET_INCLUDE_DIRECTORIES>>,$<BOOL:${property}>>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
+  endif()
 
   set (property "$<TARGET_PROPERTY:${name},SWIG_COMPILE_DEFINITIONS>")
   list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:$<TARGET_GENEX_EVAL:${name},${property}>,$<SEMICOLON>-D>>")
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index cc29b77..4c3d901 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -88,3 +88,14 @@
   --build-options ${build_options}
   --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
   )
+
+
+add_test(NAME UseSWIG.UseTargetINCLUDE_DIRECTORIES COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES"
+  "${CMake_BINARY_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES"
+  ${build_generator_args}
+  --build-project TestModuleVersion2
+  --build-options ${build_options}
+  )
diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
new file mode 100644
index 0000000..3e266c3
--- /dev/null
+++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestUseTargetINCLUDE_DIRECTORIES CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+
+unset(CMAKE_SWIG_FLAGS)
+
+set_property(SOURCE "example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "example.i" PROPERTY COMPILE_OPTIONS -includeall)
+
+swig_add_library(example1
+                 LANGUAGE python
+                 OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/example1"
+                 SOURCES example.i ../example.cxx)
+set_target_properties (example1 PROPERTIES
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.."
+  SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE
+  OUTPUT_NAME example1
+  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
+  ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
+  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1")
+target_link_libraries(example1 PRIVATE Python3::Python)
+
+
+# Check that source property override target property
+set_property(SOURCE "example.i" PROPERTY USE_TARGET_INCLUDE_DIRECTORIES TRUE)
+
+swig_add_library(example2
+                 LANGUAGE python
+                 OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/example2"
+                 SOURCES example.i ../example.cxx)
+set_target_properties (example2 PROPERTIES
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.."
+  SWIG_USE_TARGET_INCLUDE_DIRECTORIES FALSE
+  OUTPUT_NAME example2
+  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2"
+  ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2"
+  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2")
+target_link_libraries(example2 PRIVATE Python3::Python)
diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i
new file mode 100644
index 0000000..fbdf724
--- /dev/null
+++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i
@@ -0,0 +1,9 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"