Bläddra i källkod

UseSWIG: add management of SWIG option -module

When file property SWIG_MODULE_NAME is specified, provide option -module
to SWIG compiler.

Fixes: #18374
Marc Chevrier 7 år sedan
förälder
incheckning
dff28141dc

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.14
 .. toctree::
    :maxdepth: 1
 
+   CMP0086: UseSWIG honors SWIG_MODULE_NAME via -module flag. </policy/CMP0086>
    CMP0085: IN_LIST generator expression handles empty list items. </policy/CMP0085>
    CMP0084: The FindQt module does not exist for find_package(). </policy/CMP0084>
    CMP0083: Add PIE options when linking executable. </policy/CMP0083>

+ 20 - 0
Help/policy/CMP0086.rst

@@ -0,0 +1,20 @@
+CMP0086
+-------
+
+:module:`UseSWIG` honors ``SWIG_MODULE_NAME`` via ``-module`` flag.
+
+Starting with CMake 3.14, :module:`UseSWIG` passes option
+``-module <module_name>`` to ``SWIG`` compiler if the file property
+``SWIG_MODULE_NAME`` is specified. This policy provides compatibility with
+projects that expect the legacy behavior.
+
+The ``OLD`` behavior for this policy is to never pass ``-module`` option.
+The ``NEW`` behavior is to pass ``-module`` option to ``SWIG`` compiler if
+``SWIG_MODULE_NAME`` is specified.
+
+This policy was introduced in CMake version 3.14.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt

+ 6 - 0
Help/release/dev/UseSWIG-CMP0086.rst

@@ -0,0 +1,6 @@
+UseSWIG-CMP0086
+---------------
+
+* The :module:`UseSWIG` module passes option ``-module <module_name>`` to
+  ``SWIG`` compiler if the file property ``SWIG_MODULE_NAME`` is defined.
+  See policy :policy:`CMP0086`.

+ 25 - 0
Modules/UseSWIG.cmake

@@ -142,6 +142,11 @@ ensure generated files will receive the required settings.
 
     set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname)
 
+  .. note::
+
+    If policy :policy:`CMP0086` is set to ``NEW``, ``-module <module_name>``
+    is passed to ``SWIG`` compiler.
+
 Target library properties can be set to apply same configuration to all SWIG
 input files.
 
@@ -220,12 +225,19 @@ as well as ``SWIG``:
 #]=======================================================================]
 
 cmake_policy(GET CMP0078 target_name_policy)
+cmake_policy(GET CMP0086 module_name_policy)
+
 cmake_policy (VERSION 3.12)
 if (target_name_policy)
   # respect user choice regarding CMP0078 policy
   cmake_policy(SET CMP0078 ${target_name_policy})
 endif()
+if (module_name_policy)
+  # respect user choice regarding CMP0086 policy
+  cmake_policy(SET CMP0086 ${module_name_policy})
+endif()
 unset(target_name_policy)
+unset(module_name_policy)
 
 set(SWIG_CXX_EXTENSION "cxx")
 set(SWIG_EXTRA_LIBRARIES "")
@@ -426,6 +438,19 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
     list (APPEND swig_special_flags "-c++")
   endif()
 
+  cmake_policy(GET CMP0086 module_name_policy)
+  if (module_name_policy STREQUAL "NEW")
+    get_source_file_property(module_name "${infile}" SWIG_MODULE_NAME)
+    if (module_name)
+      list (APPEND swig_special_flags "-module" "${module_name}")
+    endif()
+  else()
+    if (NOT module_name_policy)
+      cmake_policy(GET_WARNING CMP0086 _cmp0086_warning)
+      message(AUTHOR_WARNING "${_cmp0086_warning}\n")
+    endif()
+  endif()
+
   set (swig_extra_flags)
   if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "CSHARP")
     if(NOT ("-dllimport" IN_LIST swig_source_file_flags OR "-dllimport" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))

+ 4 - 1
Source/cmPolicies.h

@@ -251,7 +251,10 @@ class cmMakefile;
          "The FindQt module does not exist for find_package().", 3, 14, 0,    \
          cmPolicies::WARN)                                                    \
   SELECT(POLICY, CMP0085, "$<IN_LIST:...> handles empty list items.", 3, 14,  \
-         0, cmPolicies::WARN)
+         0, cmPolicies::WARN)                                                 \
+  SELECT(POLICY, CMP0086,                                                     \
+         "UseSWIG honors SWIG_MODULE_NAME via -module flag.", 3, 14, 0,       \
+         cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -159,7 +159,7 @@ add_RunCMake_test(FindBoost)
 add_RunCMake_test(FindLua)
 add_RunCMake_test(FindOpenGL)
 if(CMake_TEST_UseSWIG)
-  add_RunCMake_test(UseSWIG)
+  add_RunCMake_test(UseSWIG -DCMake_TEST_FindPython=${CMake_TEST_FindPython})
 endif()
 if(NOT CMAKE_C_COMPILER_ID MATCHES "Watcom")
   add_RunCMake_test(GenerateExportHeader)

+ 1 - 1
Tests/RunCMake/UseSWIG/CMP0078-WARN-stderr.txt

@@ -4,7 +4,7 @@ CMake Warning \(dev\) at .*/Modules/UseSWIG\.cmake:[0-9]+ \(message\):
   command to set the policy and suppress this warning\.
 
 Call Stack \(most recent call first\):
-  CMP0078-common\.cmake:6 \(swig_add_library\)
+  CMP0078-common\.cmake:8 \(swig_add_library\)
   CMP0078-WARN\.cmake:1 \(include\)
   CMakeLists\.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.$

+ 2 - 0
Tests/RunCMake/UseSWIG/CMP0078-common.cmake

@@ -1,4 +1,6 @@
 
+cmake_policy(SET CMP0086 NEW)
+
 set(SWIG_EXECUTABLE "swig")
 set(SWIG_DIR "/swig")
 include(UseSWIG)

+ 4 - 0
Tests/RunCMake/UseSWIG/CMP0086-NEW-nuild-check.cmake

@@ -0,0 +1,4 @@
+
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/new_example.py")
+  set (RunCMake_TEST_FAILED "Not found expected file: '${RunCMake_TEST_BINARY_DIR}/new_example.py'.")
+endif()

+ 2 - 0
Tests/RunCMake/UseSWIG/CMP0086-NEW.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0086 NEW)
+include(CMP0086-common.cmake)

+ 4 - 0
Tests/RunCMake/UseSWIG/CMP0086-OLD-build-check.cmake

@@ -0,0 +1,4 @@
+
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/example.py")
+  set (RunCMake_TEST_FAILED "Not found expected file: '${RunCMake_TEST_BINARY_DIR}/example.py'.")
+endif()

+ 2 - 0
Tests/RunCMake/UseSWIG/CMP0086-OLD.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0086 OLD)
+include(CMP0086-common.cmake)

+ 11 - 0
Tests/RunCMake/UseSWIG/CMP0086-WARN-stderr.txt

@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at .*/Modules/UseSWIG.cmake:[0-9]+ \(message\):
+  Policy CMP0086 is not set: UseSWIG honors SWIG_MODULE_NAME via -module
+  flag.  Run "cmake --help-policy CMP0086" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+Call Stack \(most recent call first\):
+  .*/Modules/UseSWIG.cmake:[0-9]+ \(SWIG_ADD_SOURCE_TO_MODULE\)
+  CMP0086-common\.cmake:[0-9]+ \(swig_add_library\)
+  CMP0086-WARN\.cmake:1 \(include\)
+  CMakeLists\.txt:3 \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$

+ 1 - 0
Tests/RunCMake/UseSWIG/CMP0086-WARN.cmake

@@ -0,0 +1 @@
+include(CMP0086-common.cmake)

+ 11 - 0
Tests/RunCMake/UseSWIG/CMP0086-common.cmake

@@ -0,0 +1,11 @@
+
+cmake_policy(SET CMP0078 NEW)
+
+find_package(Python REQUIRED COMPONENTS Development)
+find_package (SWIG REQUIRED)
+include(UseSWIG)
+
+set_property (SOURCE example.i PROPERTY SWIG_MODULE_NAME "new_example")
+
+swig_add_library(example LANGUAGE python TYPE MODULE SOURCES example.i)
+target_link_libraries(example PRIVATE Python::Python)

+ 20 - 0
Tests/RunCMake/UseSWIG/RunCMakeTest.cmake

@@ -3,3 +3,23 @@ include(RunCMake)
 run_cmake(CMP0078-WARN)
 run_cmake(CMP0078-OLD)
 run_cmake(CMP0078-NEW)
+
+run_cmake(CMP0086-WARN)
+
+if (CMake_TEST_FindPython)
+
+  macro(run_cmake_target test subtest target)
+    set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+    set(RunCMake_TEST_NO_CLEAN 1)
+    run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN})
+
+    unset(RunCMake_TEST_BINARY_DIR)
+    unset(RunCMake_TEST_NO_CLEAN)
+  endmacro()
+
+  run_cmake(CMP0086-OLD)
+  run_cmake_target(CMP0086-OLD build example)
+  run_cmake(CMP0086-NEW)
+  run_cmake_target(CMP0086-NEW build example)
+
+endif()

+ 13 - 1
Tests/UseSWIG/CMakeLists.txt

@@ -96,6 +96,18 @@ add_test(NAME UseSWIG.UseTargetINCLUDE_DIRECTORIES COMMAND
   "${CMake_SOURCE_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES"
   "${CMake_BINARY_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES"
   ${build_generator_args}
-  --build-project TestModuleVersion2
+  --build-project TestUseTargetINCLUDE_DIRECTORIES
   --build-options ${build_options}
   )
+
+
+add_test(NAME UseSWIG.ModuleName COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/UseSWIG/ModuleName"
+  "${CMake_BINARY_DIR}/Tests/UseSWIG/ModuleName"
+  ${build_generator_args}
+  --build-project TestModuleName
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )

+ 42 - 0
Tests/UseSWIG/ModuleName/CMakeLists.txt

@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 3.1...3.14)
+
+project(TestModuleName CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+cmake_policy(SET CMP0086 NEW)
+include(${SWIG_USE_FILE})
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
+
+# Path separator
+if (WIN32)
+  set (PS "$<SEMICOLON>")
+else()
+  set (PS ":")
+endif()
+
+unset(CMAKE_SWIG_FLAGS)
+
+set_property(SOURCE "example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "example.i" PROPERTY COMPILE_OPTIONS -includeall)
+set_property(SOURCE "example.i" PROPERTY SWIG_MODULE_NAME new_example)
+
+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 new_example
+  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 Python2::Python)
+
+
+add_test (NAME ModuleName.example1
+  COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}/Python2${PS}$<TARGET_FILE_DIR:example1>"
+  "${Python2_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/runme.py")

+ 9 - 0
Tests/UseSWIG/ModuleName/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"

+ 52 - 0
Tests/UseSWIG/ModuleName/runme.py

@@ -0,0 +1,52 @@
+# file: runme.py
+
+# This file illustrates the shadow-class C++ interface generated
+# by SWIG.
+
+from __future__ import print_function
+
+import new_example
+
+# ----- Object creation -----
+
+print ("Creating some objects:")
+c = new_example.Circle(10)
+print ("    Created circle", c)
+s = new_example.Square(10)
+print ("    Created square", s)
+
+# ----- Access a static member -----
+
+print ("\nA total of", new_example.cvar.Shape_nshapes,"shapes were created")
+
+# ----- Member data access -----
+
+# Set the location of the object
+
+c.x = 20
+c.y = 30
+
+s.x = -10
+s.y = 5
+
+print ("\nHere is their current position:")
+print ("    Circle = (%f, %f)" % (c.x,c.y))
+print ("    Square = (%f, %f)" % (s.x,s.y))
+
+# ----- Call some methods -----
+
+print ("\nHere are some properties of the shapes:")
+for o in [c,s]:
+      print ("   ", o)
+      print ("        area      = ", o.area())
+      print ("        perimeter = ", o.perimeter())
+
+print ("\nGuess I'll clean up now")
+
+# Note: this invokes the virtual destructor
+del c
+del s
+
+s = 3
+print (new_example.cvar.Shape_nshapes,"shapes remain")
+print ("Goodbye")