浏览代码

Merge branch 'swig_src_file_ext' into 'master'

UseSWIG: Add support for custom Swig source file extensions

Closes #18727

See merge request cmake/cmake!2764
Marc Chevrier 6 年之前
父节点
当前提交
e7a88ce482

+ 5 - 0
Help/release/dev/UseSWIG-source-file-ext.rst

@@ -0,0 +1,5 @@
+UseSWIG-source-file-ext
+-----------------------
+
+* The :module:`UseSWIG` module gains capability to specify
+  ``SWIG`` source file extensions.

+ 24 - 2
Modules/UseSWIG.cmake

@@ -75,7 +75,8 @@ Defines the following command for use with ``SWIG``:
   ``SOURCES``
     List of sources for the library. Files with extension ``.i`` will be
     identified as sources for the ``SWIG`` tool. Other files will be handled in
-    the standard way.
+    the standard way. This behavior can be overriden by specifying the variable
+    ``SWIG_SOURCE_FILE_EXTENSIONS``.
 
   .. note::
 
@@ -222,6 +223,15 @@ as well as ``SWIG``:
 
 ``SWIG_MODULE_<name>_EXTRA_DEPS``
   Specify extra dependencies for the generated module for ``<name>``.
+
+``SWIG_SOURCE_FILE_EXTENSIONS``
+  Specify a list of source file extensions to override the default
+  behavior of considering only ``.i`` files as sources for the ``SWIG``
+  tool. For example:
+
+  .. code-block:: cmake
+
+    set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
 #]=======================================================================]
 
 cmake_policy(GET CMP0078 target_name_policy)
@@ -659,8 +669,20 @@ function(SWIG_ADD_LIBRARY name)
   set(CMAKE_SWIG_OUTDIR "${outputdir}")
   set(SWIG_OUTFILE_DIR "${outfiledir}")
 
+  # See if the user has specified source extensions for swig files?
+  if (NOT DEFINED SWIG_SOURCE_FILE_EXTENSIONS)
+    # Assume the default (*.i) file extension for Swig source files
+    set(SWIG_SOURCE_FILE_EXTENSIONS ".i")
+  endif()
+
+  # Generate a regex out of file extensions.
+  string(REGEX REPLACE "([$^.*+?|()-])" "\\\\\\1" swig_source_ext_regex "${SWIG_SOURCE_FILE_EXTENSIONS}")
+  list (JOIN swig_source_ext_regex "|" swig_source_ext_regex)
+  string (PREPEND swig_source_ext_regex "(")
+  string (APPEND swig_source_ext_regex ")$")
+
   set(swig_dot_i_sources ${_SAM_SOURCES})
-  list(FILTER swig_dot_i_sources INCLUDE REGEX "\\.i$")
+  list(FILTER swig_dot_i_sources INCLUDE REGEX ${swig_source_ext_regex})
   if (NOT swig_dot_i_sources)
     message(FATAL_ERROR "SWIG_ADD_LIBRARY: no SWIG interface files specified")
   endif()

+ 12 - 0
Tests/UseSWIG/CMakeLists.txt

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

+ 28 - 0
Tests/UseSWIG/SwigSrcFileExtension/CMakeLists.txt

@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.1...3.14)
+
+project(SwigSrcFileExtension C)
+
+include(CTest)
+find_package(SWIG REQUIRED)
+find_package(Python COMPONENTS Interpreter Development REQUIRED)
+
+include(${SWIG_USE_FILE})
+
+# Use the newer target name preference
+set(UseSWIG_TARGET_NAME_PREFERENCE "STANDARD")
+
+# Set the custom source file extension to both .i and .swg
+set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
+
+# Generate a Python module out of `.i`
+swig_add_library(my_add LANGUAGE python SOURCES my_add.i)
+target_link_libraries(my_add Python::Python)
+
+# Generate a Python module out of `.swg`
+swig_add_library(my_sub LANGUAGE python SOURCES my_sub.swg)
+target_link_libraries(my_sub Python::Python)
+
+# Add a test
+add_test(NAME SwigSrcFileExtension
+  COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}"
+  "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py")

+ 9 - 0
Tests/UseSWIG/SwigSrcFileExtension/my_add.i

@@ -0,0 +1,9 @@
+%module my_add
+
+%{
+int add(int a, int b) {
+    return a + b;
+}
+%}
+
+int add(int a, int b);

+ 9 - 0
Tests/UseSWIG/SwigSrcFileExtension/my_sub.swg

@@ -0,0 +1,9 @@
+%module my_sub
+
+%{
+int sub(int a, int b) {
+    return a - b;
+}
+%}
+
+int sub(int a, int b);

+ 24 - 0
Tests/UseSWIG/SwigSrcFileExtension/runme.py

@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+import random
+
+import my_add
+import my_sub
+
+
+# These can be changed, but make sure not to overflow `int`
+a = random.randint(1, 1024)
+b = random.randint(1, 1024)
+
+if my_add.add(a, b) == a + b:
+    print ("Test 1 Passed for SWIG custom source file extension")
+else:
+    print ("Test 1 FAILED for SWIG custom source file extension")
+    exit(1)
+
+if my_sub.sub(a, b) == a - b:
+    print ("Test 2 Passed for SWIG custom source file extension")
+else:
+    print ("Test 2 FAILED for SWIG custom source file extension")
+    exit(1)