Browse Source

UseSWIG: Add OUTPUT_DIR and OUTFILE_DIR source file properties

These properties enable to manage output directories on
per source file basis.

Fixes: #21250
Marc Chevrier 5 years ago
parent
commit
4a81a0ce3d

+ 5 - 0
Help/release/dev/UseSWIG-output-source-properties.rst

@@ -0,0 +1,5 @@
+UseSwig-output-source-properties
+--------------------------------
+
+* :module:`UseSWIG` module gains new source file properties ``OUTPUT_DIR`` and
+  ``OUTFILE_DIR`` to manage output directories on per source basis.

+ 42 - 9
Modules/UseSWIG.cmake

@@ -76,8 +76,8 @@ Defines the following command for use with ``SWIG``:
 
   ``OUTFILE_DIR``
     Specify an output directory name where the generated source file will be
-    placed (swig -o option). If not specified, the ``SWIG_OUTFILE_DIR`` variable
-    will be used. If neither is specified, ``OUTPUT_DIR`` or
+    placed (swig ``-o`` option). If not specified, the ``SWIG_OUTFILE_DIR``
+    variable will be used. If neither is specified, ``OUTPUT_DIR`` or
     ``CMAKE_SWIG_OUTDIR`` is used instead.
 
   ``SOURCES``
@@ -156,6 +156,19 @@ ensure generated files will receive the required settings.
     If policy :policy:`CMP0086` is set to ``NEW``, ``-module <module_name>``
     is passed to ``SWIG`` compiler.
 
+``OUTPUT_DIR``
+  Specify where to write the language specific files (swig ``-outdir`` option)
+  for the considered source file. If not specified, the other ways to define
+  the output directory applies (see ``OUTPUT_DIR`` option of
+  ``swig_add_library()`` command).
+
+``OUTFILE_DIR``
+  Specify an output directory where the generated source file will be placed
+  (swig ``-o`` option) for the considered source file. If not specified,
+  ``OUTPUT_DIR`` source property will be used. If neither are specified, the
+  other ways to define output file directory applies (see ``OUTFILE_DIR``
+  option of ``swig_add_library()`` command).
+
 Target library properties can be set to apply same configuration to all SWIG
 input files.
 
@@ -209,6 +222,11 @@ information about support files generated by ``SWIG`` interface compilation.
   This output property specifies the directory where support files will be
   generated.
 
+  .. note::
+
+    When source property ``OUTPUT_DIR`` is defined, multiple directories can be
+    specified as part of ``SWIG_SUPPORT_FILES_DIRECTORY``.
+
 Some variables can be set to customize the behavior of ``swig_add_library``
 as well as ``SWIG``:
 
@@ -375,15 +393,24 @@ endfunction()
 function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
   get_filename_component(swig_source_file_name_we "${infile}" NAME_WE)
   get_source_file_property(swig_source_file_cplusplus "${infile}" CPLUSPLUS)
-
-  # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
-  if(CMAKE_SWIG_OUTDIR)
+  get_source_file_property(swig_source_file_outdir "${infile}" OUTPUT_DIR)
+  get_source_file_property(swig_source_file_outfiledir "${infile}" OUTFILE_DIR)
+
+  if (swig_source_file_outdir)
+    # use source file property
+    set(outdir "${swig_source_file_outdir}")
+    if (NOT swig_source_file_outfiledir)
+      set (swig_source_file_outfiledir "${outdir}")
+    endif()
+  elseif(CMAKE_SWIG_OUTDIR)
     set(outdir ${CMAKE_SWIG_OUTDIR})
   else()
     set(outdir ${CMAKE_CURRENT_BINARY_DIR})
   endif()
 
-  if(SWIG_OUTFILE_DIR)
+  if (swig_source_file_outfiledir)
+    set (outfiledir "${swig_source_file_outfiledir}")
+  elseif(SWIG_OUTFILE_DIR)
     set(outfiledir ${SWIG_OUTFILE_DIR})
   else()
     set(outfiledir ${outdir})
@@ -725,6 +752,7 @@ function(SWIG_ADD_LIBRARY name)
 
   set(swig_generated_sources)
   set(swig_generated_timestamps)
+  set(swig_generated_outdirs "${outputdir}")
   list(LENGTH swig_dot_i_sources swig_sources_count)
   if (swig_sources_count GREATER "1")
     # option -interface cannot be used
@@ -740,11 +768,16 @@ function(SWIG_ADD_LIBRARY name)
         "${workingdir}" swig_timestamp)
       list (APPEND swig_generated_timestamps "${swig_timestamp}")
     endif()
+    get_source_file_property(swig_source_file_outdir "${swig_it}" OUTPUT_DIR)
+    if (swig_source_file_outdir)
+      list (APPEND swig_generated_outdirs "${swig_source_file_outdir}")
+    endif()
   endforeach()
+  list(REMOVE_DUPLICATES swig_generated_outdirs)
   set_property (DIRECTORY APPEND PROPERTY
     ADDITIONAL_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
   if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
-    set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${outputdir}")
+    set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${swig_generated_outdirs})
   endif()
 
   add_library(${target_name}
@@ -828,8 +861,8 @@ function(SWIG_ADD_LIBRARY name)
     set_target_properties (${target_name} PROPERTIES PREFIX "")
   endif ()
 
-  # target property SWIG_SUPPORT_FILES_DIRECTORY specify output directory of support files
-  set_property (TARGET ${target_name} PROPERTY SWIG_SUPPORT_FILES_DIRECTORY "${outputdir}")
+  # target property SWIG_SUPPORT_FILES_DIRECTORY specify output directories of support files
+  set_property (TARGET ${target_name} PROPERTY SWIG_SUPPORT_FILES_DIRECTORY ${swig_generated_outdirs})
   # target property SWIG_SUPPORT_FILES lists principal proxy support files
   if (NOT SWIG_MODULE_${name}_NOPROXY)
     string(TOUPPER "${_SAM_LANGUAGE}" swig_uppercase_language)

+ 12 - 0
Tests/UseSWIG/CMakeLists.txt

@@ -169,3 +169,15 @@ add_test(NAME UseSWIG.AlternateLibraryName COMMAND
   --build-options ${build_options}
   --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
   )
+
+
+add_test(NAME UseSWIG.SwigSrcOUTPUT_DIR COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/UseSWIG/SwigSrcOUTPUT_DIR"
+  "${CMake_BINARY_DIR}/Tests/UseSWIG/SwigSrcOUTPUT_DIR"
+  ${build_generator_args}
+  --build-project TestSwigSrcOUTPUT_DIR
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )

+ 1 - 1
Tests/UseSWIG/NamespaceCsharp/CMakeLists.txt

@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.12...3.13)
 
-project(TestNamsespaceCsharp CXX)
+project(TestNamespaceCsharp CXX)
 
 include(CTest)
 

+ 61 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/CMakeLists.txt

@@ -0,0 +1,61 @@
+cmake_minimum_required(VERSION 3.12...3.19)
+
+project(TestSwigSrcOUTPUT_DIR CXX)
+
+include(CTest)
+
+
+set(CMAKE_CXX_STANDARD 11)
+
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+set(UseSWIG_MODULE_VERSION 2)
+
+
+file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/Foo"
+                    "${CMAKE_CURRENT_BINARY_DIR}/FooSupport"
+                    "${CMAKE_CURRENT_BINARY_DIR}/FooFile"
+                    "${CMAKE_CURRENT_BINARY_DIR}/Bar"
+                    "${CMAKE_CURRENT_BINARY_DIR}/BarSupport"
+                    "${CMAKE_CURRENT_BINARY_DIR}/BarFile")
+
+
+set_property (SOURCE foo.i PROPERTY COMPILE_OPTIONS -namespace Foo)
+set_property (SOURCE foo.i PROPERTY OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Foo")
+set_property (SOURCE foo.i PROPERTY CPLUSPLUS ON)
+
+set_property (SOURCE bar.i PROPERTY COMPILE_OPTIONS -namespace Bar)
+set_property (SOURCE bar.i PROPERTY OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/Bar")
+set_property (SOURCE bar.i PROPERTY CPLUSPLUS ON)
+
+swig_add_library(outdir_test LANGUAGE csharp SOURCES foo.i bar.i cs.cpp
+                             OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/NotUsed1"
+                             OUTFILE_DIR "${CMAKE_CURRENT_BINARY_DIR}/NotUsed2")
+target_include_directories(outdir_test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+set_property(TARGET outdir_test PROPERTY USE_TARGET_INCLUDE_DIRECTORIES ON)
+
+
+get_target_property(SUPPORT_FILES_DIRS outdir_test SWIG_SUPPORT_FILES_DIRECTORY)
+
+add_test(NAME SwigSrcOUTPUT_DIR COMMAND "${CMAKE_COMMAND}" "-DBASE_DIRECTORY=${CMAKE_CURRENT_BINARY_DIR}" "-DSUPPORT_FILES_DIRECTORY=${SUPPORT_FILES_DIRS}" -P "${CMAKE_CURRENT_SOURCE_DIR}/ValidateSupportFiles.cmake")
+
+
+
+set_property (SOURCE foo.i PROPERTY OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/FooSupport")
+set_property (SOURCE foo.i PROPERTY OUTFILE_DIR "${CMAKE_CURRENT_BINARY_DIR}/FooFile")
+
+set_property (SOURCE bar.i PROPERTY OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/BarSupport")
+set_property (SOURCE bar.i PROPERTY OUTFILE_DIR "${CMAKE_CURRENT_BINARY_DIR}/BarFile")
+
+swig_add_library(outfiledir_test LANGUAGE csharp SOURCES foo.i bar.i cs.cpp
+                                 OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/NotUsed1"
+                                 OUTFILE_DIR "${CMAKE_CURRENT_BINARY_DIR}/NotUsed2")
+target_include_directories(outfiledir_test PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
+set_property(TARGET outfiledir_test PROPERTY USE_TARGET_INCLUDE_DIRECTORIES ON)
+
+
+get_target_property(SUPPORT_FILES_DIRS outfiledir_test SWIG_SUPPORT_FILES_DIRECTORY)
+
+add_test(NAME SwigSrcOUTFILE_DIR COMMAND "${CMAKE_COMMAND}" "-DBASE_DIRECTORY=${CMAKE_CURRENT_BINARY_DIR}" "-DSUPPORT_FILES_DIRECTORY=${SUPPORT_FILES_DIRS}" -DOUTFILE_DIR=ON -P "${CMAKE_CURRENT_SOURCE_DIR}/ValidateSupportFiles.cmake")

+ 17 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/ValidateSupportFiles.cmake

@@ -0,0 +1,17 @@
+
+foreach (support_dir IN LISTS SUPPORT_FILES_DIRECTORY)
+  file (GLOB_RECURSE files LIST_DIRECTORIES TRUE RELATIVE "${BASE_DIRECTORY}" "${support_dir}/*")
+  list (APPEND support_files ${files})
+endforeach()
+
+list(SORT support_files)
+
+if (OUTFILE_DIR)
+  set (expected_files "BarSupport/Bar.cs;BarSupport/BarPINVOKE.cs;BarSupport/Math.cs;FooSupport/Foo.cs;FooSupport/FooPINVOKE.cs;FooSupport/Math.cs")
+else()
+  set (expected_files "Bar/Bar.cs;Bar/BarPINVOKE.cs;Bar/Math.cs;Bar/barCSHARP_wrap.cxx;Foo/Foo.cs;Foo/FooPINVOKE.cs;Foo/Math.cs;Foo/fooCSHARP_wrap.cxx")
+endif()
+
+if (NOT support_files STREQUAL expected_files)
+  message (FATAL_ERROR "Support files not correctly collected.")
+endif()

+ 15 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/bar.hpp

@@ -0,0 +1,15 @@
+#pragma once
+
+namespace Bar {
+
+class Math
+{
+public:
+  void add(int value);
+  int get_sum() const;
+
+private:
+  int sum_ = 0;
+};
+
+} // namespace cs

+ 8 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/bar.i

@@ -0,0 +1,8 @@
+%module Bar
+
+%{
+#include <bar.hpp>
+%}
+
+// %nspace cs::my_class_in_namespace;
+%include <bar.hpp>

+ 29 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/cs.cpp

@@ -0,0 +1,29 @@
+#include <bar.hpp>
+#include <foo.hpp>
+
+namespace Foo {
+
+void Math::add(int value)
+{
+  sum_ += value;
+}
+
+int Math::get_sum() const
+{
+  return sum_;
+}
+}
+
+namespace Bar {
+
+void Math::add(int value)
+{
+  sum_ += value;
+}
+
+int Math::get_sum() const
+{
+  return sum_;
+}
+
+} // namespace cs

+ 15 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/foo.hpp

@@ -0,0 +1,15 @@
+#pragma once
+
+namespace Foo {
+
+class Math
+{
+public:
+  void add(int value);
+  int get_sum() const;
+
+private:
+  int sum_ = 0;
+};
+
+} // namespace cs

+ 8 - 0
Tests/UseSWIG/SwigSrcOUTPUT_DIR/foo.i

@@ -0,0 +1,8 @@
+%module Foo
+
+%{
+#include <foo.hpp>
+%}
+
+// %nspace cs::my_class_in_namespace;
+%include <foo.hpp>