Skip to content

Commit

Permalink
Merge pull request #20 from swig-fortran/useswig-new
Browse files Browse the repository at this point in the history
Backport upcoming FindSWIG/UseSWIG
  • Loading branch information
sethrj authored Feb 25, 2020
2 parents 0d1b919 + 85cf9c6 commit c2a138a
Show file tree
Hide file tree
Showing 29 changed files with 816 additions and 583 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/build/
/build-*/
/install/
/install-*/
# Prerequisites
*.d

Expand Down
32 changes: 18 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,26 +75,30 @@ endif()
#---------------------------------------------------------------------------#

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
if (CMAKE_VERSION VERSION_LESS 3.18)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/backport-cmake-318")
endif()

if (FLIBCPP_USE_SWIG)
find_package(SWIG)
endif()
find_package(SWIG COMPONENTS fortran REQUIRED)

if (FLIBCPP_USE_SWIG AND SWIG_FOUND)
# SWIG is requested and available; make sure it's the Fortran fork.
include(CheckSWIGFortran)
if (CMAKE_VERSION VERSION_LESS 3.99)
# TODO: This is until Fortran support gets added to the upstream cmake script
include(UseSWIGFortran)
else()
if (CMAKE_VERSION VERSION_LESS 3.12)
message(FATAL_ERROR "CMake 3.12 or higher is required to regenerate the "
"Fortran bindings using SWIG. Set FLIBCPP_USE_SWIG to OFF "
"and reconfigure.")
endif()

if (CMAKE_VERSION GREATER_EQUAL 3.13)
cmake_policy(SET CMP0078 "NEW")
else()
set(FLIBCPP_CMP0078 "NEW")
endif()
if (CMAKE_VERSION GREATER_EQUAL 3.14)
cmake_policy(SET CMP0086 "NEW")
include(UseSWIG)
else()
set(FLIBCPP_CMP0086 "NEW")
endif()
set(FLIBCPP_SWIG_EXECUTABLE "${SWIG_EXECUTABLE}")
set(FLIBCPP_SWIG_DIR "${SWIG_DIR}")
else()
set(FLIBCPP_USE_SWIG FALSE)
include(UseSWIG)
endif()

# Enable testing based on BUILD_TESTING flag
Expand Down
23 changes: 0 additions & 23 deletions cmake/CheckSWIGFortran.cmake

This file was deleted.

110 changes: 110 additions & 0 deletions cmake/backport-cmake-318/FindSWIG.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
FindSWIG
--------

Find the Simplified Wrapper and Interface Generator (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_<lang>_FOUND``
If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available
target language ``<lang>`` (lowercase) will be set to TRUE.

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``.

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)

if(SWIG_EXECUTABLE)
execute_process(COMMAND ${SWIG_EXECUTABLE} -swiglib
OUTPUT_VARIABLE SWIG_swiglib_output
ERROR_VARIABLE SWIG_swiglib_error
RESULT_VARIABLE SWIG_swiglib_result)

if(SWIG_swiglib_result)
if(SWIG_FIND_REQUIRED)
message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}")
else()
message(STATUS "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}")
endif()
else()
string(REGEX REPLACE "[\n\r]+" ";" SWIG_swiglib_output ${SWIG_swiglib_output})
find_path(SWIG_DIR swig.swg PATHS ${SWIG_swiglib_output} NO_CMAKE_FIND_ROOT_PATH)
if(SWIG_DIR)
set(SWIG_USE_FILE ${CMAKE_CURRENT_LIST_DIR}/UseSWIG.cmake)
execute_process(COMMAND ${SWIG_EXECUTABLE} -version
OUTPUT_VARIABLE SWIG_version_output
ERROR_VARIABLE SWIG_version_output
RESULT_VARIABLE SWIG_version_result)
if(SWIG_version_result)
message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -version\" failed with output:\n${SWIG_version_output}")
else()
string(REGEX REPLACE ".*SWIG Version[^0-9.]*\([0-9.]+\).*" "\\1"
SWIG_version_output "${SWIG_version_output}")
set(SWIG_VERSION ${SWIG_version_output} CACHE STRING "Swig version" FORCE)
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(FindPackageHandleStandardArgs)
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)
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,31 @@ as well as ``SWIG``:
set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
#]=======================================================================]

if (CMAKE_VERSION GREATER_EQUAL 3.13)
cmake_policy(GET CMP0078 target_name_policy)
endif()
if (CMAKE_VERSION GREATER_EQUAL 3.14)
cmake_policy(GET CMP0086 module_name_policy)
endif()

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 "")

set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py")
set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java")
set(SWIG_CSHARP_EXTRA_FILE_EXTENSIONS ".cs" "PINVOKE.cs")
set(SWIG_FORTRAN_EXTRA_FILE_EXTENSIONS ".f90")

set(SWIG_MANAGE_SUPPORT_FILES_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/UseSWIG/ManageSupportFiles.cmake")

Expand Down Expand Up @@ -322,15 +338,30 @@ function(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
set(extra_file "${generatedpath}/${module_basename}${it}")
if (extra_file MATCHES "\\.cs$" AND CMAKE_CSharp_COMPILER_LOADED)
set_source_files_properties(${extra_file} PROPERTIES LANGUAGE "CSharp")
elseif (extra_file MATCHES "\\.f90$" AND CMAKE_Fortran_COMPILER_LOADED)
set_source_files_properties(${extra_file} PROPERTIES LANGUAGE "Fortran")
else()
# Treat extra outputs as plain files regardless of language.
set_source_files_properties(${extra_file} PROPERTIES LANGUAGE "")
endif()
list(APPEND files "${extra_file}")
endforeach()

if (language STREQUAL "FORTRAN" AND CMAKE_Fortran_COMPILER_LOADED)
# Process possible user-supplied extension in flags (obtained via parent
# scope variable) to determine the source file name.
list(FIND SWIG_COMPILATION_FLAGS "-fext" fext_idx)
if (fext_idx EQUAL -1)
# Default Fortran generated extension
set(fext "f90")
else()
# Get extension from user-provided flag
math(EXPR fext_idx "${fext_idx} + 1")
list(GET SWIG_COMPILATION_FLAGS "${fext_idx}" fext)
endif()
set(extra_file "${generatedpath}/${module_basename}.${fext}")
set_source_files_properties("${extra_file}" PROPERTIES LANGUAGE "Fortran")
list(APPEND files "${extra_file}")
endif()

set (${outfiles} ${files} PARENT_SCOPE)
endfunction()

Expand Down Expand Up @@ -405,6 +436,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)

if (NOT SWIG_MODULE_${name}_NOPROXY)
set(SWIG_COMPILATION_FLAGS ${swig_source_file_flags})
SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
swig_extra_generated_files
"${outdir}"
Expand Down Expand Up @@ -438,20 +470,39 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
list (APPEND swig_special_flags "-c++")
endif()

set(module_name_policy "NEW")

if (CMAKE_VERSION GREATER_EQUAL 3.14)
cmake_policy(GET CMP0086 module_name_policy)
elseif(FLIBCPP_CMP0086)
set(module_name_policy ${FLIBCPP_CMP0086})
else()
set(module_name_policy OLD)
endif()
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))
# This makes sure that the name used in the generated DllImport
# matches the library name created by CMake
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "${name}")
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
endif()
endif()
if (SWIG_MODULE_${name}_LANGUAGE STREQUAL "PYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
if(NOT ("-interface" IN_LIST swig_source_file_flags OR "-interface" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
# This makes sure that the name used in the proxy code
# matches the library name created by CMake
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-interface" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
endif()
endif()
list (APPEND swig_extra_flags ${SWIG_MODULE_${name}_EXTRA_FLAGS})
Expand Down Expand Up @@ -576,11 +627,18 @@ function(SWIG_ADD_LIBRARY name)
unset(_SAM_TYPE)
endif()

set(target_name_policy "NEW")
if (CMAKE_VERSION GREATER_EQUAL 3.13)
cmake_policy(GET CMP0078 target_name_policy)
elseif(FLIBCPP_CMP0078)
set(target_name_policy ${FLIBCPP_CMP0078})
else()
set(target_name_policy OLD)
endif()
if (target_name_policy STREQUAL "NEW")
set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)
else()
if (NOT target_name_policy)
cmake_policy(GET_WARNING CMP0078 _cmp0078_warning)
message(AUTHOR_WARNING "${_cmp0078_warning}\n")
endif()
if (NOT DEFINED UseSWIG_TARGET_NAME_PREFERENCE)
Expand Down Expand Up @@ -685,9 +743,9 @@ function(SWIG_ADD_LIBRARY name)
endif()
endforeach()
set_property (DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
ADDITIONAL_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${outputdir}")
set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${outputdir}")
endif()

add_library(${target_name}
Expand All @@ -706,8 +764,6 @@ function(SWIG_ADD_LIBRARY name)
if (swig_lowercase_language STREQUAL "octave")
set_target_properties(${target_name} PROPERTIES PREFIX "")
set_target_properties(${target_name} PROPERTIES SUFFIX ".oct")
elseif (swig_lowercase_language STREQUAL "fortran")
# XXX
elseif (swig_lowercase_language STREQUAL "go")
set_target_properties(${target_name} PROPERTIES PREFIX "")
elseif (swig_lowercase_language STREQUAL "java")
Expand Down Expand Up @@ -766,6 +822,8 @@ function(SWIG_ADD_LIBRARY name)
if (APPLE)
set_target_properties (${target_name} PROPERTIES SUFFIX ".dylib")
endif ()
elseif (swig_lowercase_language STREQUAL "fortran")
# Do *not* override the target's library prefix
else()
# assume empty prefix because we expect the module to be dynamically loaded
set_target_properties (${target_name} PROPERTIES PREFIX "")
Expand Down
31 changes: 31 additions & 0 deletions cmake/backport-cmake-318/UseSWIG/ManageSupportFiles.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.


if (ACTION STREQUAL "CLEAN")
# Collect current list of generated files
file (GLOB files LIST_DIRECTORIES FALSE RELATIVE "${SUPPORT_FILES_WORKING_DIRECTORY}" "${SUPPORT_FILES_WORKING_DIRECTORY}/*")

if (files)
# clean-up the output directory
## compute full paths
list (TRANSFORM files PREPEND "${SUPPORT_FILES_OUTPUT_DIRECTORY}/")
## remove generated files from the output directory
file (REMOVE ${files})

# clean-up working directory
file (REMOVE_RECURSE "${SUPPORT_FILES_WORKING_DIRECTORY}")
endif()

file (MAKE_DIRECTORY "${SUPPORT_FILES_WORKING_DIRECTORY}")
endif()

if (ACTION STREQUAL "COPY")
# Collect current list of generated files
file (GLOB files LIST_DIRECTORIES FALSE "${SUPPORT_FILES_WORKING_DIRECTORY}/*")

if (files)
# copy files to the output directory
file (COPY ${files} DESTINATION "${SUPPORT_FILES_OUTPUT_DIRECTORY}")
endif()
endif()
Loading

0 comments on commit c2a138a

Please sign in to comment.