UseSWIG.cmake 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. # - SWIG module for CMake
  2. # Defines the following macros:
  3. # SWIG_ADD_MODULE(name language [ files ])
  4. # - Define swig module with given name and specified language
  5. # SWIG_LINK_LIBRARIES(name [ libraries ])
  6. # - Link libraries to swig module
  7. # SWIG_GET_WRAPPER_DEPENDENCIES(swigFile genWrapper language DEST_VARIABLE)
  8. # - Put dependencies of the wrapper genWrapper generated by swig from
  9. # swigFile in DEST_VARIABLE
  10. # All other macros are for internal use only.
  11. # To get the actual name of the swig module,
  12. # use: ${SWIG_MODULE_${name}_REAL_NAME}.
  13. # Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify
  14. # special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add
  15. # special flags to all swig calls.
  16. # Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify
  17. # where to write all the swig generated module (swig -outdir option)
  18. # The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used
  19. # to specify extra dependencies for the generated modules.
  20. # If the source file generated by swig need some special flag you can use
  21. # SET_SOURCE_FILES_PROPERTIES( ${swig_generated_file_fullname}
  22. # PROPERTIES COMPILE_FLAGS "-bla")
  23. #=============================================================================
  24. # Copyright 2004-2009 Kitware, Inc.
  25. # Copyright 2009 Mathieu Malaterre <[email protected]>
  26. #
  27. # Distributed under the OSI-approved BSD License (the "License");
  28. # see accompanying file Copyright.txt for details.
  29. #
  30. # This software is distributed WITHOUT ANY WARRANTY; without even the
  31. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  32. # See the License for more information.
  33. #=============================================================================
  34. # (To distribute this file outside of CMake, substitute the full
  35. # License text for the above reference.)
  36. SET(SWIG_CXX_EXTENSION "cxx")
  37. SET(SWIG_EXTRA_LIBRARIES "")
  38. SET(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py")
  39. #
  40. # Get dependencies of the generated wrapper.
  41. #
  42. MACRO(SWIG_GET_WRAPPER_DEPENDENCIES swigFile genWrapper language DEST_VARIABLE)
  43. GET_FILENAME_COMPONENT(swig_getdeps_basename ${swigFile} NAME_WE)
  44. GET_FILENAME_COMPONENT(swig_getdeps_outdir ${genWrapper} PATH)
  45. GET_SOURCE_FILE_PROPERTY(swig_getdeps_extra_flags "${swigFile}" SWIG_FLAGS)
  46. IF("${swig_getdeps_extra_flags}" STREQUAL "NOTFOUND")
  47. SET(swig_getdeps_extra_flags "")
  48. ENDIF("${swig_getdeps_extra_flags}" STREQUAL "NOTFOUND")
  49. IF(NOT swig_getdeps_outdir)
  50. SET(swig_getdeps_outdir ${CMAKE_CURRENT_BINARY_DIR})
  51. ENDIF(NOT swig_getdeps_outdir)
  52. SET(swig_getdeps_depsfile
  53. ${swig_getdeps_outdir}/swig_${swig_getdeps_basename}_deps.txt)
  54. GET_DIRECTORY_PROPERTY(swig_getdeps_include_directories INCLUDE_DIRECTORIES)
  55. SET(swig_getdeps_include_dirs)
  56. FOREACH(it ${swig_getdeps_include_directories})
  57. SET(swig_getdeps_include_dirs ${swig_getdeps_include_dirs} "-I${it}")
  58. ENDFOREACH(it)
  59. EXECUTE_PROCESS(
  60. COMMAND ${SWIG_EXECUTABLE}
  61. -MM -MF ${swig_getdeps_depsfile} ${swig_getdeps_extra_flags}
  62. ${CMAKE_SWIG_FLAGS} -${language}
  63. -o ${genWrapper} ${swig_getdeps_include_dirs} ${swigFile}
  64. RESULT_VARIABLE swig_getdeps_result
  65. ERROR_VARIABLE swig_getdeps_error
  66. OUTPUT_STRIP_TRAILING_WHITESPACE)
  67. IF(NOT ${swig_getdeps_error} EQUAL 0)
  68. MESSAGE(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -MM -MF ${swig_getdeps_depsfile} ${swig_getdeps_extra_flags} ${CMAKE_SWIG_FLAGS} -${language} -o ${genWrapper} ${swig_getdeps_include_dirs} ${swigFile}\" failed with output:\n${swig_getdeps_error}")
  69. SET(swig_getdeps_dependencies "")
  70. ELSE(NOT ${swig_getdeps_error} EQUAL 0)
  71. FILE(READ ${swig_getdeps_depsfile} ${DEST_VARIABLE})
  72. # Remove the first line
  73. STRING(REGEX REPLACE "^.+: +\\\\\n +" ""
  74. ${DEST_VARIABLE} "${${DEST_VARIABLE}}")
  75. # Clean the end of each line
  76. STRING(REGEX REPLACE " +(\\\\)?\n" "\n" ${DEST_VARIABLE}
  77. "${${DEST_VARIABLE}}")
  78. # Clean beginning of each line
  79. STRING(REGEX REPLACE "\n +" "\n"
  80. ${DEST_VARIABLE} "${${DEST_VARIABLE}}")
  81. # clean paths
  82. STRING(REGEX REPLACE "\\\\\\\\" "/" ${DEST_VARIABLE}
  83. "${${DEST_VARIABLE}}")
  84. STRING(REGEX REPLACE "\n" ";"
  85. ${DEST_VARIABLE} "${${DEST_VARIABLE}}")
  86. ENDIF(NOT ${swig_getdeps_error} EQUAL 0)
  87. ENDMACRO(SWIG_GET_WRAPPER_DEPENDENCIES)
  88. #
  89. # For given swig module initialize variables associated with it
  90. #
  91. MACRO(SWIG_MODULE_INITIALIZE name language)
  92. STRING(TOUPPER "${language}" swig_uppercase_language)
  93. STRING(TOLOWER "${language}" swig_lowercase_language)
  94. SET(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}")
  95. SET(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")
  96. IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xUNKNOWNx$")
  97. MESSAGE(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
  98. ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xUNKNOWNx$")
  99. SET(SWIG_MODULE_${name}_REAL_NAME "${name}")
  100. IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPYTHONx$")
  101. # when swig is used without the -interface it will produce in the module.py
  102. # a 'import _modulename' statement, which implies having a corresponding
  103. # _modulename.so (*NIX), _modulename.pyd (Win32).
  104. SET(SWIG_MODULE_${name}_REAL_NAME "_${name}")
  105. ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPYTHONx$")
  106. IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPERLx$")
  107. SET(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
  108. ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPERLx$")
  109. ENDMACRO(SWIG_MODULE_INITIALIZE)
  110. #
  111. # For a given language, input file, and output file, determine extra files that
  112. # will be generated. This is internal swig macro.
  113. #
  114. MACRO(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
  115. SET(${outfiles} "")
  116. GET_SOURCE_FILE_PROPERTY(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename
  117. ${infile} SWIG_MODULE_NAME)
  118. IF(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
  119. GET_FILENAME_COMPONENT(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE)
  120. ENDIF(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
  121. FOREACH(it ${SWIG_${language}_EXTRA_FILE_EXTENSION})
  122. SET(${outfiles} ${${outfiles}}
  123. "${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}")
  124. ENDFOREACH(it)
  125. ENDMACRO(SWIG_GET_EXTRA_OUTPUT_FILES)
  126. #
  127. # Take swig (*.i) file and add proper custom commands for it
  128. #
  129. MACRO(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
  130. SET(swig_full_infile ${infile})
  131. GET_FILENAME_COMPONENT(swig_source_file_path "${infile}" PATH)
  132. GET_FILENAME_COMPONENT(swig_source_file_name_we "${infile}" NAME_WE)
  133. GET_SOURCE_FILE_PROPERTY(swig_source_file_generated ${infile} GENERATED)
  134. GET_SOURCE_FILE_PROPERTY(swig_source_file_cplusplus ${infile} CPLUSPLUS)
  135. GET_SOURCE_FILE_PROPERTY(swig_source_file_flags ${infile} SWIG_FLAGS)
  136. IF("${swig_source_file_flags}" STREQUAL "NOTFOUND")
  137. SET(swig_source_file_flags "")
  138. ENDIF("${swig_source_file_flags}" STREQUAL "NOTFOUND")
  139. SET(swig_source_file_fullname "${infile}")
  140. IF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
  141. STRING(REGEX REPLACE
  142. "^${CMAKE_CURRENT_SOURCE_DIR}" ""
  143. swig_source_file_relative_path
  144. "${swig_source_file_path}")
  145. ELSE(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
  146. IF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
  147. STRING(REGEX REPLACE
  148. "^${CMAKE_CURRENT_BINARY_DIR}" ""
  149. swig_source_file_relative_path
  150. "${swig_source_file_path}")
  151. SET(swig_source_file_generated 1)
  152. ELSE(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
  153. SET(swig_source_file_relative_path "${swig_source_file_path}")
  154. IF(swig_source_file_generated)
  155. SET(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}")
  156. ELSE(swig_source_file_generated)
  157. SET(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
  158. ENDIF(swig_source_file_generated)
  159. ENDIF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
  160. ENDIF(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
  161. SET(swig_generated_file_fullname
  162. "${CMAKE_CURRENT_BINARY_DIR}")
  163. IF(swig_source_file_relative_path)
  164. SET(swig_generated_file_fullname
  165. "${swig_generated_file_fullname}/${swig_source_file_relative_path}")
  166. ENDIF(swig_source_file_relative_path)
  167. # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
  168. IF(CMAKE_SWIG_OUTDIR)
  169. SET(swig_outdir ${CMAKE_SWIG_OUTDIR})
  170. ELSE(CMAKE_SWIG_OUTDIR)
  171. SET(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
  172. ENDIF(CMAKE_SWIG_OUTDIR)
  173. SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
  174. swig_extra_generated_files
  175. "${swig_outdir}"
  176. "${infile}")
  177. SET(swig_generated_file_fullname
  178. "${swig_generated_file_fullname}/${swig_source_file_name_we}")
  179. # add the language into the name of the file (i.e. TCL_wrap)
  180. # this allows for the same .i file to be wrapped into different languages
  181. SET(swig_generated_file_fullname
  182. "${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap")
  183. IF(swig_source_file_cplusplus)
  184. SET(swig_generated_file_fullname
  185. "${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}")
  186. ELSE(swig_source_file_cplusplus)
  187. SET(swig_generated_file_fullname
  188. "${swig_generated_file_fullname}.c")
  189. ENDIF(swig_source_file_cplusplus)
  190. #MESSAGE("Full path to source file: ${swig_source_file_fullname}")
  191. #MESSAGE("Full path to the output file: ${swig_generated_file_fullname}")
  192. GET_DIRECTORY_PROPERTY(cmake_include_directories INCLUDE_DIRECTORIES)
  193. SET(swig_include_dirs)
  194. FOREACH(it ${cmake_include_directories})
  195. SET(swig_include_dirs ${swig_include_dirs} "-I${it}")
  196. ENDFOREACH(it)
  197. SET(swig_special_flags)
  198. # default is c, so add c++ flag if it is c++
  199. IF(swig_source_file_cplusplus)
  200. SET(swig_special_flags ${swig_special_flags} "-c++")
  201. ENDIF(swig_source_file_cplusplus)
  202. SET(swig_extra_flags)
  203. IF(SWIG_MODULE_${name}_EXTRA_FLAGS)
  204. SET(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
  205. ENDIF(SWIG_MODULE_${name}_EXTRA_FLAGS)
  206. SWIG_GET_WRAPPER_DEPENDENCIES("${swig_source_file_fullname}"
  207. "${swig_generated_file_fullname}" ${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}
  208. swig_extra_dependencies)
  209. LIST(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${swig_extra_dependencies})
  210. ADD_CUSTOM_COMMAND(
  211. OUTPUT "${swig_generated_file_fullname}" ${swig_extra_generated_files}
  212. # Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir)
  213. COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir}
  214. COMMAND "${SWIG_EXECUTABLE}"
  215. ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
  216. ${swig_source_file_flags}
  217. ${CMAKE_SWIG_FLAGS}
  218. -outdir ${swig_outdir}
  219. ${swig_special_flags}
  220. ${swig_extra_flags}
  221. ${swig_include_dirs}
  222. -o "${swig_generated_file_fullname}"
  223. "${swig_source_file_fullname}"
  224. MAIN_DEPENDENCY "${swig_source_file_fullname}"
  225. DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS}
  226. COMMENT "Swig source")
  227. SET_SOURCE_FILES_PROPERTIES("${swig_generated_file_fullname}" ${swig_extra_generated_files}
  228. PROPERTIES GENERATED 1)
  229. SET(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
  230. ENDMACRO(SWIG_ADD_SOURCE_TO_MODULE)
  231. #
  232. # Create Swig module
  233. #
  234. MACRO(SWIG_ADD_MODULE name language)
  235. SWIG_MODULE_INITIALIZE(${name} ${language})
  236. SET(swig_dot_i_sources)
  237. SET(swig_other_sources)
  238. FOREACH(it ${ARGN})
  239. IF(${it} MATCHES ".*\\.i$")
  240. SET(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
  241. ELSE(${it} MATCHES ".*\\.i$")
  242. SET(swig_other_sources ${swig_other_sources} "${it}")
  243. ENDIF(${it} MATCHES ".*\\.i$")
  244. ENDFOREACH(it)
  245. SET(swig_generated_sources)
  246. FOREACH(it ${swig_dot_i_sources})
  247. SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it})
  248. SET(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
  249. ENDFOREACH(it)
  250. GET_DIRECTORY_PROPERTY(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
  251. SET_DIRECTORY_PROPERTIES(PROPERTIES
  252. ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
  253. ADD_LIBRARY(${SWIG_MODULE_${name}_REAL_NAME}
  254. MODULE
  255. ${swig_generated_sources}
  256. ${swig_other_sources})
  257. STRING(TOLOWER "${language}" swig_lowercase_language)
  258. IF ("${swig_lowercase_language}" STREQUAL "java")
  259. IF (APPLE)
  260. # In java you want:
  261. # System.loadLibrary("LIBRARY");
  262. # then JNI will look for a library whose name is platform dependent, namely
  263. # MacOS : libLIBRARY.jnilib
  264. # Windows: LIBRARY.dll
  265. # Linux : libLIBRARY.so
  266. SET_TARGET_PROPERTIES (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
  267. ENDIF (APPLE)
  268. ENDIF ("${swig_lowercase_language}" STREQUAL "java")
  269. IF ("${swig_lowercase_language}" STREQUAL "python")
  270. # this is only needed for the python case where a _modulename.so is generated
  271. SET_TARGET_PROPERTIES(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
  272. # Python extension modules on Windows must have the extension ".pyd"
  273. # instead of ".dll" as of Python 2.5. Older python versions do support
  274. # this suffix.
  275. # http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000
  276. # <quote>
  277. # Windows: .dll is no longer supported as a filename extension for extension modules.
  278. # .pyd is now the only filename extension that will be searched for.
  279. # </quote>
  280. IF(WIN32 AND NOT CYGWIN)
  281. SET_TARGET_PROPERTIES(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
  282. ENDIF(WIN32 AND NOT CYGWIN)
  283. ENDIF ("${swig_lowercase_language}" STREQUAL "python")
  284. ENDMACRO(SWIG_ADD_MODULE)
  285. #
  286. # Like TARGET_LINK_LIBRARIES but for swig modules
  287. #
  288. MACRO(SWIG_LINK_LIBRARIES name)
  289. IF(SWIG_MODULE_${name}_REAL_NAME)
  290. TARGET_LINK_LIBRARIES(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN})
  291. ELSE(SWIG_MODULE_${name}_REAL_NAME)
  292. MESSAGE(SEND_ERROR "Cannot find Swig library \"${name}\".")
  293. ENDIF(SWIG_MODULE_${name}_REAL_NAME)
  294. ENDMACRO(SWIG_LINK_LIBRARIES name)