Skip to content

Instantly share code, notes, and snippets.

@noc0lour
Created February 11, 2018 18:13
Show Gist options
  • Save noc0lour/3900b7563969c985ea59071e7d3f1a37 to your computer and use it in GitHub Desktop.
Save noc0lour/3900b7563969c985ea59071e7d3f1a37 to your computer and use it in GitHub Desktop.
--- /usr/share/cmake/Modules/UseSWIG.cmake 2017-11-10 13:28:57.000000000 +0100
+++ UseSWIG.cmake 2018-02-11 19:11:08.853784864 +0100
@@ -1,64 +1,42 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-#.rst:
-# UseSWIG
-# -------
-#
-# Defines the following macros for use with SWIG:
-#
-# ::
-#
-# SWIG_ADD_LIBRARY(<name>
-# [TYPE <SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS>]
-# LANGUAGE <language>
-# SOURCES <file>...
-# )
-# - Define swig module with given name and specified language
-# SWIG_LINK_LIBRARIES(name [ libraries ])
-# - Link libraries to swig module
-#
-# Source files properties on module files can be set before the invocation
-# of the SWIG_ADD_LIBRARY macro to specify special behavior of SWIG.
-#
-# The source file property CPLUSPLUS calls SWIG in c++ mode, e.g.::
-#
-# set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON)
-# swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
-#
-# The source file property SWIG_FLAGS adds custom flags to the SWIG executable.
-#
-# The source-file property SWIG_MODULE_NAME have to be provided to specify the actual
-# import name of the module in the target language if it cannot be scanned automatically
-# from source or different from the module file basename.::
-#
-# set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname)
-#
-# To get the name of the swig module target library, use: ${SWIG_MODULE_${name}_REAL_NAME}.
-#
-# Also some variables can be set to specify special behavior of SWIG.
-#
-# CMAKE_SWIG_FLAGS can be used to add special flags to all swig calls.
-#
-# CMAKE_SWIG_OUTDIR allows one to specify where to write
-# the language specific files (swig -outdir option).
-#
-# SWIG_OUTFILE_DIR allows one to specify where to write the output file
-# (swig -o option). If not specified, CMAKE_SWIG_OUTDIR is used.
-#
-# The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used to specify extra
-# dependencies for the generated modules.
-#
-# If the source file generated by swig need some special flag you can use::
-#
-# set_source_files_properties( ${swig_generated_file_fullname}
-# PROPERTIES COMPILE_FLAGS "-bla")
+# - SWIG module for CMake
+# Defines the following macros:
+# SWIG_ADD_MODULE(name language [ files ])
+# - Define swig module with given name and specified language
+# SWIG_LINK_LIBRARIES(name [ libraries ])
+# - Link libraries to swig module
+# All other macros are for internal use only.
+# To get the actual name of the swig module,
+# use: ${SWIG_MODULE_${name}_REAL_NAME}.
+# Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify
+# special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add
+# special flags to all swig calls.
+# Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify
+# where to write all the swig generated module (swig -outdir option)
+# The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used
+# to specify extra dependencies for the generated modules.
+# If the source file generated by swig need some special flag you can use
+# set_source_files_properties( ${swig_generated_file_fullname}
+# PROPERTIES COMPILE_FLAGS "-bla")
+
+
+#=============================================================================
+# Copyright 2004-2009 Kitware, Inc.
+# Copyright 2009 Mathieu Malaterre <[email protected]>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
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_PYTHON_EXTRA_FILE_EXTENSION "py")
#
# For given swig module initialize variables associated with it
@@ -70,22 +48,15 @@
set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")
set(SWIG_MODULE_${name}_REAL_NAME "${name}")
- if (";${CMAKE_SWIG_FLAGS};" MATCHES ";-noproxy;")
- set (SWIG_MODULE_${name}_NOPROXY TRUE)
- endif ()
- if("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xUNKNOWN")
+ if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN")
message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
- elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPYTHON" AND NOT SWIG_MODULE_${name}_NOPROXY)
- # swig will produce a module.py containing an 'import _modulename' statement,
- # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32),
- # unless the -noproxy flag is used
+ elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON")
+ # when swig is used without the -interface it will produce in the module.py
+ # a 'import _modulename' statement, which implies having a corresponding
+ # _modulename.so (*NIX), _modulename.pyd (Win32).
set(SWIG_MODULE_${name}_REAL_NAME "_${name}")
- elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xPERL")
+ elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL")
set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
- elseif("x${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "xCSHARP")
- # This makes sure that the name used in the generated DllImport
- # matches the library name created by CMake
- set(SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport;${name}")
endif()
endmacro()
@@ -99,36 +70,11 @@
get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename
${infile} SWIG_MODULE_NAME)
if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
-
- # try to get module name from "%module foo" syntax
- if ( EXISTS ${infile} )
- file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*[a-zA-Z0-9_]+.*" )
- endif ()
- if ( _MODULE_NAME )
- string ( REGEX REPLACE "[ ]*%module[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" )
- set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}")
-
- else ()
- # try to get module name from "%module (options=...) foo" syntax
- if ( EXISTS ${infile} )
- file ( STRINGS ${infile} _MODULE_NAME REGEX "[ ]*%module[ ]*\\(.*\\)[ ]*[a-zA-Z0-9_]+.*" )
- endif ()
- if ( _MODULE_NAME )
- string ( REGEX REPLACE "[ ]*%module[ ]*\\(.*\\)[ ]*([a-zA-Z0-9_]+).*" "\\1" _MODULE_NAME "${_MODULE_NAME}" )
- set(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${_MODULE_NAME}")
-
- else ()
- # fallback to file basename
- get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename ${infile} NAME_WE)
- endif ()
- endif ()
-
+ get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE)
endif()
- foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSIONS})
- set(extra_file "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}${it}")
- list(APPEND ${outfiles} ${extra_file})
- # Treat extra outputs as plain files regardless of language.
- set_property(SOURCE "${extra_file}" PROPERTY LANGUAGE "")
+ foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSION})
+ set(${outfiles} ${${outfiles}}
+ "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}")
endforeach()
endmacro()
@@ -137,6 +83,7 @@
#
macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
set(swig_full_infile ${infile})
+ get_filename_component(swig_source_file_path "${infile}" PATH)
get_filename_component(swig_source_file_name_we "${infile}" NAME_WE)
get_source_file_property(swig_source_file_generated ${infile} GENERATED)
get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS)
@@ -144,44 +91,69 @@
if("${swig_source_file_flags}" STREQUAL "NOTFOUND")
set(swig_source_file_flags "")
endif()
- get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)
+ set(swig_source_file_fullname "${infile}")
+ if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
+ string(REGEX REPLACE
+ "^${CMAKE_CURRENT_SOURCE_DIR}" ""
+ swig_source_file_relative_path
+ "${swig_source_file_path}")
+ else()
+ if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
+ string(REGEX REPLACE
+ "^${CMAKE_CURRENT_BINARY_DIR}" ""
+ swig_source_file_relative_path
+ "${swig_source_file_path}")
+ set(swig_source_file_generated 1)
+ else()
+ set(swig_source_file_relative_path "${swig_source_file_path}")
+ if(swig_source_file_generated)
+ set(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}")
+ else()
+ set(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
+ endif()
+ endif()
+ endif()
+ set(swig_generated_file_fullname
+ "${CMAKE_CURRENT_BINARY_DIR}")
+ if(swig_source_file_relative_path)
+ set(swig_generated_file_fullname
+ "${swig_generated_file_fullname}/${swig_source_file_relative_path}")
+ endif()
# If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
if(CMAKE_SWIG_OUTDIR)
set(swig_outdir ${CMAKE_SWIG_OUTDIR})
else()
set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
endif()
-
- if(SWIG_OUTFILE_DIR)
- set(swig_outfile_dir ${SWIG_OUTFILE_DIR})
- else()
- set(swig_outfile_dir ${swig_outdir})
- endif()
-
- if (NOT SWIG_MODULE_${name}_NOPROXY)
- SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
- swig_extra_generated_files
- "${swig_outdir}"
- "${swig_source_file_fullname}")
- endif()
+ SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
+ swig_extra_generated_files
+ "${swig_outdir}"
+ "${infile}")
set(swig_generated_file_fullname
- "${swig_outfile_dir}/${swig_source_file_name_we}")
+ "${swig_generated_file_fullname}/${swig_source_file_name_we}")
# add the language into the name of the file (i.e. TCL_wrap)
# this allows for the same .i file to be wrapped into different languages
- string(APPEND swig_generated_file_fullname
- "${SWIG_MODULE_${name}_LANGUAGE}_wrap")
+ set(swig_generated_file_fullname
+ "${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap")
if(swig_source_file_cplusplus)
- string(APPEND swig_generated_file_fullname
- ".${SWIG_CXX_EXTENSION}")
+ set(swig_generated_file_fullname
+ "${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}")
else()
- string(APPEND swig_generated_file_fullname
- ".c")
+ set(swig_generated_file_fullname
+ "${swig_generated_file_fullname}.c")
endif()
- #message("Full path to source file: ${swig_source_file_fullname}")
- #message("Full path to the output file: ${swig_generated_file_fullname}")
+ # Shut up some warnings from poor SWIG code generation that we
+ # can do nothing about, when this flag is available
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
+ if(HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
+ set_source_files_properties(${swig_generated_file_fullname}
+ PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable")
+ endif(HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
+
get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES)
list(REMOVE_DUPLICATES cmake_include_directories)
set(swig_include_dirs)
@@ -198,8 +170,38 @@
if(SWIG_MODULE_${name}_EXTRA_FLAGS)
set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
endif()
+
+ # hack to work around CMake bug in add_custom_command with multiple OUTPUT files
+
+ file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
+unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
+print(re.sub('\\W', '_', '${name} ${reldir} ' + unique))"
+ OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ file(
+ WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in
+ "int main(void){return 0;}\n"
+ )
+
+ # create dummy dependencies
add_custom_command(
- OUTPUT "${swig_generated_file_fullname}" ${swig_extra_generated_files}
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp
+ DEPENDS "${swig_source_file_fullname}" ${SWIG_MODULE_${name}_EXTRA_DEPS}
+ COMMENT ""
+ )
+
+ # create the dummy target
+ add_executable(${_target} ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp)
+
+ # add a custom command to the dummy target
+ add_custom_command(
+ TARGET ${_target}
# Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir)
COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir}
COMMAND "${SWIG_EXECUTABLE}"
@@ -212,54 +214,38 @@
${swig_include_dirs}
-o "${swig_generated_file_fullname}"
"${swig_source_file_fullname}"
- MAIN_DEPENDENCY "${swig_source_file_fullname}"
- DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS}
- IMPLICIT_DEPENDS CXX "${swig_source_file_fullname}"
- COMMENT "Swig source")
- set_source_files_properties("${swig_generated_file_fullname}" ${swig_extra_generated_files}
- PROPERTIES GENERATED 1)
+ COMMENT "Swig source"
+ )
+
+ #add dummy independent dependencies from the _target to each file
+ #that will be generated by the SWIG command above
+
set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
+
+ foreach(swig_gen_file ${${outfiles}})
+ add_custom_command(
+ OUTPUT ${swig_gen_file}
+ COMMAND "${CMAKE_COMMAND}" -E touch_nocreate "${swig_gen_file}"
+ DEPENDS ${_target}
+ COMMENT "dummy command to show ${_target} dependency of ${swig_gen_file}"
+ )
+ endforeach()
+
+ set_source_files_properties(
+ ${outfiles} PROPERTIES GENERATED 1
+ )
+
endmacro()
#
# Create Swig module
#
macro(SWIG_ADD_MODULE name language)
- message(DEPRECATION "SWIG_ADD_MODULE is deprecated. Use SWIG_ADD_LIBRARY instead.")
- swig_add_library(${name}
- LANGUAGE ${language}
- TYPE MODULE
- SOURCES ${ARGN})
-endmacro()
-
-
-macro(SWIG_ADD_LIBRARY name)
- set(options "")
- set(oneValueArgs LANGUAGE
- TYPE)
- set(multiValueArgs SOURCES)
- cmake_parse_arguments(_SAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
- if(NOT DEFINED _SAM_LANGUAGE)
- message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing LANGUAGE argument")
- endif()
-
- if(NOT DEFINED _SAM_SOURCES)
- message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing SOURCES argument")
- endif()
-
- if(NOT DEFINED _SAM_TYPE)
- set(_SAM_TYPE MODULE)
- elseif("${_SAM_TYPE}" STREQUAL "USE_BUILD_SHARED_LIBS")
- unset(_SAM_TYPE)
- endif()
-
- swig_module_initialize(${name} ${_SAM_LANGUAGE})
-
+ SWIG_MODULE_INITIALIZE(${name} ${language})
set(swig_dot_i_sources)
set(swig_other_sources)
- foreach(it ${_SAM_SOURCES})
- if(${it} MATCHES "\\.i$")
+ foreach(it ${ARGN})
+ if(${it} MATCHES ".*\\.i$")
set(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
else()
set(swig_other_sources ${swig_other_sources} "${it}")
@@ -275,19 +261,11 @@
set_directory_properties(PROPERTIES
ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
add_library(${SWIG_MODULE_${name}_REAL_NAME}
- ${_SAM_TYPE}
+ MODULE
${swig_generated_sources}
${swig_other_sources})
- if("${_SAM_TYPE}" STREQUAL "MODULE")
- set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES NO_SONAME ON)
- endif()
- string(TOLOWER "${_SAM_LANGUAGE}" swig_lowercase_language)
- if ("${swig_lowercase_language}" STREQUAL "octave")
- set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
- set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".oct")
- elseif ("${swig_lowercase_language}" STREQUAL "go")
- set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
- elseif ("${swig_lowercase_language}" STREQUAL "java")
+ string(TOLOWER "${language}" swig_lowercase_language)
+ if ("${swig_lowercase_language}" STREQUAL "java")
if (APPLE)
# In java you want:
# System.loadLibrary("LIBRARY");
@@ -297,11 +275,8 @@
# Linux : libLIBRARY.so
set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
endif ()
- elseif ("${swig_lowercase_language}" STREQUAL "lua")
- if("${_SAM_TYPE}" STREQUAL "MODULE")
- set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
- endif()
- elseif ("${swig_lowercase_language}" STREQUAL "python")
+ endif ()
+ if ("${swig_lowercase_language}" STREQUAL "python")
# this is only needed for the python case where a _modulename.so is generated
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
# Python extension modules on Windows must have the extension ".pyd"
@@ -315,22 +290,6 @@
if(WIN32 AND NOT CYGWIN)
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
endif()
- elseif ("${swig_lowercase_language}" STREQUAL "r")
- set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
- elseif ("${swig_lowercase_language}" STREQUAL "ruby")
- # In ruby you want:
- # require 'LIBRARY'
- # then ruby will look for a library whose name is platform dependent, namely
- # MacOS : LIBRARY.bundle
- # Windows: LIBRARY.dll
- # Linux : LIBRARY.so
- set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
- if (APPLE)
- set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".bundle")
- endif ()
- else()
- # assume empty prefix because we expect the module to be dynamically loaded
- set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
endif ()
endmacro()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment