From e131d9f974fd51d0cecb8f3e23d72f2aa8f12ec8 Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Thu, 20 Feb 2020 22:05:55 -0500 Subject: FindSWIG: Add COMPONENTS support for SWIG target languages Newer versions of SWIG drop support for some target languages, and some forks of SWIG (such as for Fortran and MATLAB) aren't supported by the mainline version of SWIG. Swig versions as old as 1.3.6 (circa 2001) and possibly older use the same format for listing available wrappers "%-15s - Generate %s wrappers", so component detection should be quite reliable. --- Help/release/dev/findswig-components.rst | 5 ++ Modules/FindSWIG.cmake | 71 +++++++++++++++++----- Tests/RunCMake/CMakeLists.txt | 1 + Tests/RunCMake/FindSWIG/CMakeLists.txt | 3 + Tests/RunCMake/FindSWIG/RunCMakeTest.cmake | 4 ++ Tests/RunCMake/FindSWIG/components-stdout.txt | 6 ++ Tests/RunCMake/FindSWIG/components.cmake | 9 +++ .../FindSWIG/missing-components-result.txt | 1 + .../FindSWIG/missing-components-stderr.txt | 1 + Tests/RunCMake/FindSWIG/missing-components.cmake | 3 + 10 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 Help/release/dev/findswig-components.rst create mode 100644 Tests/RunCMake/FindSWIG/CMakeLists.txt create mode 100644 Tests/RunCMake/FindSWIG/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/FindSWIG/components-stdout.txt create mode 100644 Tests/RunCMake/FindSWIG/components.cmake create mode 100644 Tests/RunCMake/FindSWIG/missing-components-result.txt create mode 100644 Tests/RunCMake/FindSWIG/missing-components-stderr.txt create mode 100644 Tests/RunCMake/FindSWIG/missing-components.cmake diff --git a/Help/release/dev/findswig-components.rst b/Help/release/dev/findswig-components.rst new file mode 100644 index 0000000..ce569be --- /dev/null +++ b/Help/release/dev/findswig-components.rst @@ -0,0 +1,5 @@ +findswig-components +------------------- + +* The :module:`FindSWIG` module now accepts target languages as ``COMPONENTS`` + and ``OPTIONAL_COMPONENTS`` arguments to ``find_package``. diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake index ae6ae56..2fded49 100644 --- a/Modules/FindSWIG.cmake +++ b/Modules/FindSWIG.cmake @@ -5,25 +5,49 @@ FindSWIG -------- -Find Simplified Wrapper and Interface Generator (SWIG) +Find the Simplified Wrapper and Interface Generator (SWIG_) executable. -This module finds an installed SWIG. It sets the following variables: - -:: - - SWIG_FOUND - set to "True" if SWIG is found - SWIG_DIR - the directory where swig is installed - SWIG_EXECUTABLE - the path to the swig executable - SWIG_VERSION - the version number of the swig executable +This module finds an installed SWIG and determines its version. If a +``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to ``find_package``, +it will also determine supported target languages. The module sents the +following variables: +``SWIG_FOUND`` + Whether SWIG and any required components were found on the system. +``SWIG_EXECUTABLE`` + Path to the SWIG executable. +``SWIG_DIR`` + Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``). +``SWIG_VERSION`` + SWIG executable version (result of ``swig -version``). +``SWIG__FOUND`` + If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available + target language ```` (lowercase) will be set to TRUE. -The minimum required version of SWIG can be specified using the -standard syntax, e.g. :command:`find_package(SWIG 1.1)` +Any ``COMPONENTS`` given to ``find_package`` should be the names of supported +target languages as provided to the LANGUAGE argument of ``swig_add_library``, +such as ``python`` or ``perl5``. Language names *must* be lowercase. All information is collected from the ``SWIG_EXECUTABLE``, so the version to be found can be changed from the command line by means of setting -``SWIG_EXECUTABLE`` +``SWIG_EXECUTABLE``. + +Example usage requiring SWIG 4.0 or higher and Python language support, with +optional Fortran support: + +.. code-block:: cmake + + find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran) + if(SWIG_FOUND) + message("SWIG found: ${SWIG_EXECUTABLE}") + if(NOT SWIG_fortran_FOUND) + message(WARNING "SWIG Fortran bindings cannot be generated") + endif() + endif() + +.. _`SWIG`: http://swig.org + #]=======================================================================] find_program(SWIG_EXECUTABLE NAMES swig4.0 swig3.0 swig2.0 swig) @@ -58,10 +82,29 @@ if(SWIG_EXECUTABLE) endif() endif() endif() + + if(SWIG_FIND_COMPONENTS) + execute_process(COMMAND ${SWIG_EXECUTABLE} -help + OUTPUT_VARIABLE SWIG_swighelp_output + ERROR_VARIABLE SWIG_swighelp_error + RESULT_VARIABLE SWIG_swighelp_result) + if(SWIG_swighelp_result) + message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${SWIG_swiglib_error}") + else() + string(REPLACE "\n" ";" SWIG_swighelp_output "${SWIG_swighelp_output}") + foreach(SWIG_line IN LISTS SWIG_swighelp_output) + if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers") + set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE) + endif() + endforeach() + endif() + endif() endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWIG REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR - VERSION_VAR SWIG_VERSION ) +find_package_handle_standard_args( + SWIG HANDLE_COMPONENTS + REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR + VERSION_VAR SWIG_VERSION) mark_as_advanced(SWIG_DIR SWIG_VERSION SWIG_EXECUTABLE) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index e9f8bca..d751d24 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -188,6 +188,7 @@ add_RunCMake_test(FindBoost) add_RunCMake_test(FindLua) add_RunCMake_test(FindOpenGL) if(CMake_TEST_UseSWIG) + add_RunCMake_test(FindSWIG) add_RunCMake_test(UseSWIG -DCMake_TEST_FindPython=${CMake_TEST_FindPython}) endif() if(NOT CMAKE_C_COMPILER_ID MATCHES "Watcom") diff --git a/Tests/RunCMake/FindSWIG/CMakeLists.txt b/Tests/RunCMake/FindSWIG/CMakeLists.txt new file mode 100644 index 0000000..d1b0d2c --- /dev/null +++ b/Tests/RunCMake/FindSWIG/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.10) +project(${RunCMake_TEST} C) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake b/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake new file mode 100644 index 0000000..5f5f7f5 --- /dev/null +++ b/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(components) +run_cmake(missing-components) diff --git a/Tests/RunCMake/FindSWIG/components-stdout.txt b/Tests/RunCMake/FindSWIG/components-stdout.txt new file mode 100644 index 0000000..3977b08 --- /dev/null +++ b/Tests/RunCMake/FindSWIG/components-stdout.txt @@ -0,0 +1,6 @@ +-- Found SWIG: [^ ]+ \(found version "[0-9.]+"\) found components: java python missing components: PERL +-- SWIG_VERSION='[0-9.]+' +-- SWIG_java_FOUND=TRUE +-- SWIG_python_FOUND=TRUE +-- SWIG_PERL_FOUND= +-- Configuring done diff --git a/Tests/RunCMake/FindSWIG/components.cmake b/Tests/RunCMake/FindSWIG/components.cmake new file mode 100644 index 0000000..b79a81e --- /dev/null +++ b/Tests/RunCMake/FindSWIG/components.cmake @@ -0,0 +1,9 @@ +# Note that 'perl' will not be found because it is not lowercase. +find_package(SWIG REQUIRED + COMPONENTS java + OPTIONAL_COMPONENTS python PERL) + +message(STATUS "SWIG_VERSION='${SWIG_VERSION}'") +foreach(_lang java python PERL) + message(STATUS "SWIG_${_lang}_FOUND=${SWIG_${_lang}_FOUND}") +endforeach() diff --git a/Tests/RunCMake/FindSWIG/missing-components-result.txt b/Tests/RunCMake/FindSWIG/missing-components-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/FindSWIG/missing-components-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FindSWIG/missing-components-stderr.txt b/Tests/RunCMake/FindSWIG/missing-components-stderr.txt new file mode 100644 index 0000000..c937532 --- /dev/null +++ b/Tests/RunCMake/FindSWIG/missing-components-stderr.txt @@ -0,0 +1 @@ +Could NOT find SWIG \(missing: invalid\) diff --git a/Tests/RunCMake/FindSWIG/missing-components.cmake b/Tests/RunCMake/FindSWIG/missing-components.cmake new file mode 100644 index 0000000..1d05ae4 --- /dev/null +++ b/Tests/RunCMake/FindSWIG/missing-components.cmake @@ -0,0 +1,3 @@ +find_package(SWIG REQUIRED + COMPONENTS invalid + OPTIONAL_COMPONENTS alsoinvalid) -- cgit v0.12