Skip to content

Commit 3825e40

Browse files
committed
Backport FindSWIG and UseSWIG from upstream
1 parent f3842c9 commit 3825e40

File tree

5 files changed

+193
-34
lines changed

5 files changed

+193
-34
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ if (CMAKE_VERSION VERSION_LESS 3.18)
8080
endif()
8181

8282
if (FLIBCPP_USE_SWIG)
83-
find_package(SWIG REQUIRED)
83+
find_package(SWIG COMPONENTS fortran REQUIRED)
8484

8585
if (CMAKE_VERSION VERSION_LESS 3.12)
8686
message(FATAL_ERROR "CMake 3.12 or higher is required to regenerate the "

cmake/CheckSWIGFortran.cmake

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2+
# file Copyright.txt or https://cmake.org/licensing for details.
3+
4+
#[=======================================================================[.rst:
5+
FindSWIG
6+
--------
7+
8+
Find the Simplified Wrapper and Interface Generator (SWIG_) executable.
9+
10+
11+
This module finds an installed SWIG and determines its version. If a
12+
``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to ``find_package``,
13+
it will also determine supported target languages. The module sents the
14+
following variables:
15+
16+
``SWIG_FOUND``
17+
Whether SWIG and any required components were found on the system.
18+
``SWIG_EXECUTABLE``
19+
Path to the SWIG executable.
20+
``SWIG_DIR``
21+
Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``).
22+
``SWIG_VERSION``
23+
SWIG executable version (result of ``swig -version``).
24+
``SWIG_<lang>_FOUND``
25+
If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available
26+
target language ``<lang>`` (lowercase) will be set to TRUE.
27+
28+
Any ``COMPONENTS`` given to ``find_package`` should be the names of supported
29+
target languages as provided to the LANGUAGE argument of ``swig_add_library``,
30+
such as ``python`` or ``perl5``. Language names *must* be lowercase.
31+
32+
All information is collected from the ``SWIG_EXECUTABLE``, so the version
33+
to be found can be changed from the command line by means of setting
34+
``SWIG_EXECUTABLE``.
35+
36+
Example usage requiring SWIG 4.0 or higher and Python language support, with
37+
optional Fortran support:
38+
39+
.. code-block:: cmake
40+
41+
find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran)
42+
if(SWIG_FOUND)
43+
message("SWIG found: ${SWIG_EXECUTABLE}")
44+
if(NOT SWIG_fortran_FOUND)
45+
message(WARNING "SWIG Fortran bindings cannot be generated")
46+
endif()
47+
endif()
48+
49+
.. _`SWIG`: http://swig.org
50+
51+
#]=======================================================================]
52+
53+
find_program(SWIG_EXECUTABLE NAMES swig4.0 swig3.0 swig2.0 swig)
54+
55+
if(SWIG_EXECUTABLE)
56+
execute_process(COMMAND ${SWIG_EXECUTABLE} -swiglib
57+
OUTPUT_VARIABLE SWIG_swiglib_output
58+
ERROR_VARIABLE SWIG_swiglib_error
59+
RESULT_VARIABLE SWIG_swiglib_result)
60+
61+
if(SWIG_swiglib_result)
62+
if(SWIG_FIND_REQUIRED)
63+
message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}")
64+
else()
65+
message(STATUS "Command \"${SWIG_EXECUTABLE} -swiglib\" failed with output:\n${SWIG_swiglib_error}")
66+
endif()
67+
else()
68+
string(REGEX REPLACE "[\n\r]+" ";" SWIG_swiglib_output ${SWIG_swiglib_output})
69+
find_path(SWIG_DIR swig.swg PATHS ${SWIG_swiglib_output} NO_CMAKE_FIND_ROOT_PATH)
70+
if(SWIG_DIR)
71+
set(SWIG_USE_FILE ${CMAKE_CURRENT_LIST_DIR}/UseSWIG.cmake)
72+
execute_process(COMMAND ${SWIG_EXECUTABLE} -version
73+
OUTPUT_VARIABLE SWIG_version_output
74+
ERROR_VARIABLE SWIG_version_output
75+
RESULT_VARIABLE SWIG_version_result)
76+
if(SWIG_version_result)
77+
message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -version\" failed with output:\n${SWIG_version_output}")
78+
else()
79+
string(REGEX REPLACE ".*SWIG Version[^0-9.]*\([0-9.]+\).*" "\\1"
80+
SWIG_version_output "${SWIG_version_output}")
81+
set(SWIG_VERSION ${SWIG_version_output} CACHE STRING "Swig version" FORCE)
82+
endif()
83+
endif()
84+
endif()
85+
86+
if(SWIG_FIND_COMPONENTS)
87+
execute_process(COMMAND ${SWIG_EXECUTABLE} -help
88+
OUTPUT_VARIABLE SWIG_swighelp_output
89+
ERROR_VARIABLE SWIG_swighelp_error
90+
RESULT_VARIABLE SWIG_swighelp_result)
91+
if(SWIG_swighelp_result)
92+
message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${SWIG_swiglib_error}")
93+
else()
94+
string(REPLACE "\n" ";" SWIG_swighelp_output "${SWIG_swighelp_output}")
95+
foreach(SWIG_line IN LISTS SWIG_swighelp_output)
96+
if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers")
97+
set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE)
98+
endif()
99+
endforeach()
100+
endif()
101+
endif()
102+
endif()
103+
104+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
105+
find_package_handle_standard_args(
106+
SWIG HANDLE_COMPONENTS
107+
REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
108+
VERSION_VAR SWIG_VERSION)
109+
110+
mark_as_advanced(SWIG_DIR SWIG_VERSION SWIG_EXECUTABLE)

cmake/UseSWIGFortran.cmake renamed to cmake/backport-cmake-318/UseSWIG.cmake

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,15 +234,27 @@ as well as ``SWIG``:
234234
set(SWIG_SOURCE_FILE_EXTENSIONS ".i" ".swg")
235235
#]=======================================================================]
236236

237+
cmake_policy(GET CMP0078 target_name_policy)
238+
cmake_policy(GET CMP0086 module_name_policy)
239+
237240
cmake_policy (VERSION 3.12)
241+
if (target_name_policy)
242+
# respect user choice regarding CMP0078 policy
243+
cmake_policy(SET CMP0078 ${target_name_policy})
244+
endif()
245+
if (module_name_policy)
246+
# respect user choice regarding CMP0086 policy
247+
cmake_policy(SET CMP0086 ${module_name_policy})
248+
endif()
249+
unset(target_name_policy)
250+
unset(module_name_policy)
238251

239252
set(SWIG_CXX_EXTENSION "cxx")
240253
set(SWIG_EXTRA_LIBRARIES "")
241254

242255
set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py")
243256
set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java")
244257
set(SWIG_CSHARP_EXTRA_FILE_EXTENSIONS ".cs" "PINVOKE.cs")
245-
set(SWIG_FORTRAN_EXTRA_FILE_EXTENSIONS ".f90")
246258

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

@@ -322,15 +334,30 @@ function(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
322334
set(extra_file "${generatedpath}/${module_basename}${it}")
323335
if (extra_file MATCHES "\\.cs$" AND CMAKE_CSharp_COMPILER_LOADED)
324336
set_source_files_properties(${extra_file} PROPERTIES LANGUAGE "CSharp")
325-
elseif (extra_file MATCHES "\\.f90$" AND CMAKE_Fortran_COMPILER_LOADED)
326-
set_source_files_properties(${extra_file} PROPERTIES LANGUAGE "Fortran")
327337
else()
328338
# Treat extra outputs as plain files regardless of language.
329339
set_source_files_properties(${extra_file} PROPERTIES LANGUAGE "")
330340
endif()
331341
list(APPEND files "${extra_file}")
332342
endforeach()
333343

344+
if (language STREQUAL "FORTRAN" AND CMAKE_Fortran_COMPILER_LOADED)
345+
# Process possible user-supplied extension in flags (obtained via parent
346+
# scope variable) to determine the source file name.
347+
list(FIND SWIG_COMPILATION_FLAGS "-fext" fext_idx)
348+
if (fext_idx EQUAL -1)
349+
# Default Fortran generated extension
350+
set(fext "f90")
351+
else()
352+
# Get extension from user-provided flag
353+
math(EXPR fext_idx "${fext_idx} + 1")
354+
list(GET SWIG_COMPILATION_FLAGS "${fext_idx}" fext)
355+
endif()
356+
set(extra_file "${generatedpath}/${module_basename}.${fext}")
357+
set_source_files_properties("${extra_file}" PROPERTIES LANGUAGE "Fortran")
358+
list(APPEND files "${extra_file}")
359+
endif()
360+
334361
set (${outfiles} ${files} PARENT_SCOPE)
335362
endfunction()
336363

@@ -405,6 +432,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
405432
get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)
406433

407434
if (NOT SWIG_MODULE_${name}_NOPROXY)
435+
set(SWIG_COMPILATION_FLAGS ${swig_source_file_flags})
408436
SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
409437
swig_extra_generated_files
410438
"${outdir}"
@@ -438,20 +466,32 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
438466
list (APPEND swig_special_flags "-c++")
439467
endif()
440468

441-
set(module_name_policy "NEW")
469+
cmake_policy(GET CMP0086 module_name_policy)
442470
if (module_name_policy STREQUAL "NEW")
443471
get_source_file_property(module_name "${infile}" SWIG_MODULE_NAME)
444472
if (module_name)
445473
list (APPEND swig_special_flags "-module" "${module_name}")
446474
endif()
475+
else()
476+
if (NOT module_name_policy)
477+
cmake_policy(GET_WARNING CMP0086 _cmp0086_warning)
478+
message(AUTHOR_WARNING "${_cmp0086_warning}\n")
479+
endif()
447480
endif()
448481

449482
set (swig_extra_flags)
450483
if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "CSHARP")
451484
if(NOT ("-dllimport" IN_LIST swig_source_file_flags OR "-dllimport" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
452485
# This makes sure that the name used in the generated DllImport
453486
# matches the library name created by CMake
454-
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "${name}")
487+
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
488+
endif()
489+
endif()
490+
if (SWIG_MODULE_${name}_LANGUAGE STREQUAL "PYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
491+
if(NOT ("-interface" IN_LIST swig_source_file_flags OR "-interface" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
492+
# This makes sure that the name used in the proxy code
493+
# matches the library name created by CMake
494+
list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-interface" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
455495
endif()
456496
endif()
457497
list (APPEND swig_extra_flags ${SWIG_MODULE_${name}_EXTRA_FLAGS})
@@ -576,11 +616,12 @@ function(SWIG_ADD_LIBRARY name)
576616
unset(_SAM_TYPE)
577617
endif()
578618

579-
set(target_name_policy "NEW")
619+
cmake_policy(GET CMP0078 target_name_policy)
580620
if (target_name_policy STREQUAL "NEW")
581621
set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)
582622
else()
583623
if (NOT target_name_policy)
624+
cmake_policy(GET_WARNING CMP0078 _cmp0078_warning)
584625
message(AUTHOR_WARNING "${_cmp0078_warning}\n")
585626
endif()
586627
if (NOT DEFINED UseSWIG_TARGET_NAME_PREFERENCE)
@@ -685,9 +726,9 @@ function(SWIG_ADD_LIBRARY name)
685726
endif()
686727
endforeach()
687728
set_property (DIRECTORY APPEND PROPERTY
688-
ADDITIONAL_MAKE_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
729+
ADDITIONAL_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps})
689730
if (UseSWIG_MODULE_VERSION VERSION_GREATER 1)
690-
set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${outputdir}")
731+
set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES "${outputdir}")
691732
endif()
692733

693734
add_library(${target_name}
@@ -706,8 +747,6 @@ function(SWIG_ADD_LIBRARY name)
706747
if (swig_lowercase_language STREQUAL "octave")
707748
set_target_properties(${target_name} PROPERTIES PREFIX "")
708749
set_target_properties(${target_name} PROPERTIES SUFFIX ".oct")
709-
elseif (swig_lowercase_language STREQUAL "fortran")
710-
# XXX
711750
elseif (swig_lowercase_language STREQUAL "go")
712751
set_target_properties(${target_name} PROPERTIES PREFIX "")
713752
elseif (swig_lowercase_language STREQUAL "java")
@@ -766,6 +805,8 @@ function(SWIG_ADD_LIBRARY name)
766805
if (APPLE)
767806
set_target_properties (${target_name} PROPERTIES SUFFIX ".dylib")
768807
endif ()
808+
elseif (swig_lowercase_language STREQUAL "fortran")
809+
# Do *not* override the target's library prefix
769810
else()
770811
# assume empty prefix because we expect the module to be dynamically loaded
771812
set_target_properties (${target_name} PROPERTIES PREFIX "")
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2+
# file Copyright.txt or https://cmake.org/licensing for details.
3+
4+
5+
if (ACTION STREQUAL "CLEAN")
6+
# Collect current list of generated files
7+
file (GLOB files LIST_DIRECTORIES FALSE RELATIVE "${SUPPORT_FILES_WORKING_DIRECTORY}" "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
8+
9+
if (files)
10+
# clean-up the output directory
11+
## compute full paths
12+
list (TRANSFORM files PREPEND "${SUPPORT_FILES_OUTPUT_DIRECTORY}/")
13+
## remove generated files from the output directory
14+
file (REMOVE ${files})
15+
16+
# clean-up working directory
17+
file (REMOVE_RECURSE "${SUPPORT_FILES_WORKING_DIRECTORY}")
18+
endif()
19+
20+
file (MAKE_DIRECTORY "${SUPPORT_FILES_WORKING_DIRECTORY}")
21+
endif()
22+
23+
if (ACTION STREQUAL "COPY")
24+
# Collect current list of generated files
25+
file (GLOB files LIST_DIRECTORIES FALSE "${SUPPORT_FILES_WORKING_DIRECTORY}/*")
26+
27+
if (files)
28+
# copy files to the output directory
29+
file (COPY ${files} DESTINATION "${SUPPORT_FILES_OUTPUT_DIRECTORY}")
30+
endif()
31+
endif()

0 commit comments

Comments
 (0)