Merge topic 'find_program-conditional-cwd'

c76c1ea208 find_program: Consider CWD only for paths with separator

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2120
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/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 2486bdf..0413faa 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 12)
-set(CMake_VERSION_PATCH 20180614)
+set(CMake_VERSION_PATCH 20180618)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index cfe62b4..7545ec7 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -3495,7 +3495,7 @@
 
   // Chip Model Name
   this->ChipID.ModelName =
-    this->ExtractValueFromCpuInfoFile(buffer, "model name").c_str();
+    this->ExtractValueFromCpuInfoFile(buffer, "model name");
 
   // L1 Cache size
   // Different architectures may show different names for the caches.
@@ -4613,7 +4613,7 @@
 std::string SystemInformationImplementation::RunProcess(
   std::vector<const char*> args)
 {
-  std::string buffer = "";
+  std::string buffer;
 
   // Run the application
   kwsysProcess* gp = kwsysProcess_New();
@@ -4668,11 +4668,7 @@
 std::string SystemInformationImplementation::ParseValueFromKStat(
   const char* arguments)
 {
-  std::vector<const char*> args;
-  args.clear();
-  args.push_back("kstat");
-  args.push_back("-p");
-
+  std::vector<std::string> args_string;
   std::string command = arguments;
   size_t start = std::string::npos;
   size_t pos = command.find(' ', 0);
@@ -4691,35 +4687,35 @@
     }
 
     if (!inQuotes) {
-      std::string arg = command.substr(start + 1, pos - start - 1);
+      args_string.push_back(command.substr(start + 1, pos - start - 1));
+      std::string& arg = args_string.back();
 
       // Remove the quotes if any
-      size_t quotes = arg.find('"');
-      while (quotes != std::string::npos) {
-        arg.erase(quotes, 1);
-        quotes = arg.find('"');
-      }
-      args.push_back(arg.c_str());
+      arg.erase(std::remove(arg.begin(), arg.end(), '"'), arg.end());
       start = pos;
     }
     pos = command.find(' ', pos + 1);
   }
-  std::string lastArg = command.substr(start + 1, command.size() - start - 1);
-  args.push_back(lastArg.c_str());
+  args_string.push_back(command.substr(start + 1, command.size() - start - 1));
 
+  std::vector<const char*> args;
+  args.reserve(3 + args_string.size());
+  args.push_back("kstat");
+  args.push_back("-p");
+  for (size_t i = 0; i < args_string.size(); ++i) {
+    args.push_back(args_string[i].c_str());
+  }
   args.push_back(KWSYS_NULLPTR);
 
   std::string buffer = this->RunProcess(args);
 
-  std::string value = "";
+  std::string value;
   for (size_t i = buffer.size() - 1; i > 0; i--) {
     if (buffer[i] == ' ' || buffer[i] == '\t') {
       break;
     }
     if (buffer[i] != '\n' && buffer[i] != '\r') {
-      std::string val = value;
-      value = buffer[i];
-      value += val;
+      value.insert(0u, 1, buffer[i]);
     }
   }
   return value;
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 0079da2..b87b6b5 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -686,7 +686,7 @@
     for (iterator i = this->begin(); i != this->end(); ++i) {
 #  if defined(_WIN32)
       const std::string s = Encoding::ToNarrow(*i);
-      kwsysUnPutEnv(s.c_str());
+      kwsysUnPutEnv(s);
 #  else
       kwsysUnPutEnv(*i);
 #  endif
@@ -1973,7 +1973,7 @@
   }
   // escape spaces and () in the path
   if (ret.find_first_of(" ") != std::string::npos) {
-    std::string result = "";
+    std::string result;
     char lastch = 1;
     for (const char* ch = ret.c_str(); *ch != '\0'; ++ch) {
       // if it is already escaped then don't try to escape it again
@@ -3140,7 +3140,7 @@
 void SystemTools::AddKeepPath(const std::string& dir)
 {
   std::string cdir;
-  Realpath(SystemTools::CollapseFullPath(dir).c_str(), cdir);
+  Realpath(SystemTools::CollapseFullPath(dir), cdir);
   SystemTools::AddTranslationPath(cdir, dir);
 }
 
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 0385a3d..ef87436 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -77,7 +77,7 @@
   int some_int_variable = 10;
   double some_double_variable = 10.10;
   char* some_string_variable = KWSYS_NULLPTR;
-  std::string some_stl_string_variable = "";
+  std::string some_stl_string_variable;
   bool some_bool_variable = false;
   bool some_bool_variable1 = false;
   bool bool_arg1 = false;
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index e6f9701..0477d59 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -206,7 +206,7 @@
     res = false;
   }
 
-  if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true)) {
+  if (!kwsys::SystemTools::Touch(testNewFile, true)) {
     std::cerr << "Problem with Touch for: " << testNewFile << std::endl;
     res = false;
   }
@@ -415,7 +415,7 @@
     res = false;
   }
 
-  kwsys::SystemTools::Touch(testNewFile.c_str(), true);
+  kwsys::SystemTools::Touch(testNewFile, true);
   if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) {
     std::cerr << "Problem with RemoveADirectory for: " << testNewDir
               << std::endl;
@@ -806,7 +806,7 @@
   const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/" +
                                  testFindFileName);
 
-  if (!kwsys::SystemTools::Touch(testFindFile.c_str(), true)) {
+  if (!kwsys::SystemTools::Touch(testFindFile, true)) {
     std::cerr << "Problem with Touch for: " << testFindFile << std::endl;
     // abort here as the existence of the file only makes the test meaningful
     return false;
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"