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: 5UseSWIG 6------- 7 8This file provides support for ``SWIG``. It is assumed that :module:`FindSWIG` 9module has already been loaded. 10 11Defines the following command for use with ``SWIG``: 12 13.. command:: swig_add_library 14 15 Define swig module with given name and specified language:: 16 17 swig_add_library(<name> 18 [TYPE <SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS>] 19 LANGUAGE <language> 20 [NO_PROXY] 21 [OUTPUT_DIR <directory>] 22 [OUTFILE_DIR <directory>] 23 SOURCES <file>... 24 ) 25 26 Targets created with the ``swig_add_library`` command have the same 27 capabilities as targets created with the :command:`add_library` command, so 28 those targets can be used with any command expecting a target (e.g. 29 :command:`target_link_libraries`). 30 31 .. note:: 32 33 For multi-config generators, this module does not support 34 configuration-specific files generated by ``SWIG``. All build 35 configurations must result in the same generated source file. 36 37 ``TYPE`` 38 ``SHARED``, ``MODULE`` and ``STATIC`` have the same semantic as for the 39 :command:`add_library` command. If ``USE_BUILD_SHARED_LIBS`` is specified, 40 the library type will be ``STATIC`` or ``SHARED`` based on whether the 41 current value of the :variable:`BUILD_SHARED_LIBS` variable is ``ON``. If 42 no type is specified, ``MODULE`` will be used. 43 44 ``LANGUAGE`` 45 Specify the target language. 46 47 ``NO_PROXY`` 48 Prevent the generation of the wrapper layer (swig ``-noproxy`` option). 49 50 ``OUTPUT_DIR`` 51 Specify where to write the language specific files (swig ``-outdir`` 52 option). If not given, the ``CMAKE_SWIG_OUTDIR`` variable will be used. 53 If neither is specified, the default depends on the value of the 54 ``UseSWIG_MODULE_VERSION`` variable as follows: 55 56 * If ``UseSWIG_MODULE_VERSION`` is 1 or is undefined, output is written to 57 the :variable:`CMAKE_CURRENT_BINARY_DIR` directory. 58 * If ``UseSWIG_MODULE_VERSION`` is 2, a dedicated directory will be used. 59 The path of this directory can be retrieved from the 60 ``SWIG_SUPPORT_FILES_DIRECTORY`` target property. 61 62 ``OUTFILE_DIR`` 63 Specify an output directory name where the generated source file will be 64 placed (swig -o option). If not specified, the ``SWIG_OUTFILE_DIR`` variable 65 will be used. If neither is specified, ``OUTPUT_DIR`` or 66 ``CMAKE_SWIG_OUTDIR`` is used instead. 67 68 ``SOURCES`` 69 List of sources for the library. Files with extension ``.i`` will be 70 identified as sources for the ``SWIG`` tool. Other files will be handled in 71 the standard way. 72 73.. note:: 74 75 If ``UseSWIG_MODULE_VERSION`` is set to 2, it is **strongly** recommended 76 to use a dedicated directory unique to the target when either the 77 ``OUTPUT_DIR`` option or the ``CMAKE_SWIG_OUTDIR`` variable are specified. 78 The output directory contents are erased as part of the target build, so 79 to prevent interference between targets or losing other important files, each 80 target should have its own dedicated output directory. 81 82Source file properties on module files **must** be set before the invocation 83of the ``swig_add_library`` command to specify special behavior of SWIG and 84ensure generated files will receive the required settings. 85 86``CPLUSPLUS`` 87 Call SWIG in c++ mode. For example: 88 89 .. code-block:: cmake 90 91 set_property(SOURCE mymod.i PROPERTY CPLUSPLUS ON) 92 swig_add_library(mymod LANGUAGE python SOURCES mymod.i) 93 94``INCLUDE_DIRECTORIES``, ``COMPILE_DEFINITIONS`` and ``COMPILE_OPTIONS`` 95 Add custom flags to SWIG compiler and have same semantic as properties 96 :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and 97 :prop_sf:`COMPILE_OPTIONS`. 98 99``GENERATED_INCLUDE_DIRECTORIES``, ``GENERATED_COMPILE_DEFINITIONS`` and ``GENERATED_COMPILE_OPTIONS`` 100 Add custom flags to the C/C++ generated source. They will fill, respectively, 101 properties :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and 102 :prop_sf:`COMPILE_OPTIONS` of generated C/C++ file. 103 104``DEPENDS`` 105 Specify additional dependencies to the source file. 106 107``SWIG_MODULE_NAME`` 108 Specify the actual import name of the module in the target language. 109 This is required if it cannot be scanned automatically from source 110 or different from the module file basename. For example: 111 112 .. code-block:: cmake 113 114 set_property(SOURCE mymod.i PROPERTY SWIG_MODULE_NAME mymod_realname) 115 116Target library properties can be set to apply same configuration to all SWIG 117input files. 118 119``SWIG_INCLUDE_DIRECTORIES``, ``SWIG_COMPILE_DEFINITIONS`` and ``SWIG_COMPILE_OPTIONS`` 120 These properties will be applied to all SWIG input files and have same 121 semantic as target properties :prop_tgt:`INCLUDE_DIRECTORIES`, 122 :prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`COMPILE_OPTIONS`. 123 124 .. code-block:: cmake 125 126 swig_add_library(mymod LANGUAGE python SOURCES mymod.i) 127 set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2) 128 set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb) 129 130``SWIG_GENERATED_INCLUDE_DIRECTORIES``, ``SWIG_GENERATED_COMPILE_DEFINITIONS`` and ``SWIG_GENERATED_COMPILE_OPTIONS`` 131 These properties will populate, respectively, properties 132 :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and 133 :prop_sf:`COMPILE_FLAGS` of all generated C/C++ files. 134 135``SWIG_DEPENDS`` 136 Add dependencies to all SWIG input files. 137 138The following target properties are output properties and can be used to get 139information about support files generated by ``SWIG`` interface compilation. 140 141``SWIG_SUPPORT_FILES`` 142 This output property list of wrapper files generated during SWIG compilation. 143 144 .. code-block:: cmake 145 146 swig_add_library(mymod LANGUAGE python SOURCES mymod.i) 147 get_property(support_files TARGET mymod PROPERTY SWIG_SUPPORT_FILES) 148 149 .. note:: 150 151 Only most principal support files are listed. In case some advanced 152 features of ``SWIG`` are used (for example ``%template``), associated 153 support files may not be listed. Prefer to use the 154 ``SWIG_SUPPORT_FILES_DIRECTORY`` property to handle support files. 155 156``SWIG_SUPPORT_FILES_DIRECTORY`` 157 This output property specifies the directory where support files will be 158 generated. 159 160Some variables can be set to customize the behavior of ``swig_add_library`` 161as well as ``SWIG``: 162 163``UseSWIG_MODULE_VERSION`` 164 Specify different behaviors for ``UseSWIG`` module. 165 166 * Set to 1 or undefined: Legacy behavior is applied. 167 * Set to 2: A new strategy is applied regarding support files: the output 168 directory of support files is erased before ``SWIG`` interface compilation. 169 170``CMAKE_SWIG_FLAGS`` 171 Add flags to all swig calls. 172 173``CMAKE_SWIG_OUTDIR`` 174 Specify where to write the language specific files (swig ``-outdir`` option). 175 176``SWIG_OUTFILE_DIR`` 177 Specify an output directory name where the generated source file will be 178 placed. If not specified, ``CMAKE_SWIG_OUTDIR`` is used. 179 180``SWIG_MODULE_<name>_EXTRA_DEPS`` 181 Specify extra dependencies for the generated module for ``<name>``. 182#]=======================================================================] 183 184 185cmake_policy (VERSION 3.8) 186 187set(SWIG_CXX_EXTENSION "cxx") 188set(SWIG_EXTRA_LIBRARIES "") 189 190set(SWIG_PYTHON_EXTRA_FILE_EXTENSIONS ".py") 191set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java") 192 193## 194## PRIVATE functions 195## 196function (__SWIG_COMPUTE_TIMESTAMP name language infile workingdir __timestamp) 197 get_filename_component(filename "${infile}" NAME_WE) 198 set(${__timestamp} 199 "${workingdir}/${filename}${language}.stamp" PARENT_SCOPE) 200 # get_filename_component(filename "${infile}" ABSOLUTE) 201 # string(UUID uuid NAMESPACE 9735D882-D2F8-4E1D-88C9-A0A4F1F6ECA4 202 # NAME ${name}-${language}-${filename} TYPE SHA1) 203 # set(${__timestamp} "${workingdir}/${uuid}.stamp" PARENT_SCOPE) 204endfunction() 205 206# 207# For given swig module initialize variables associated with it 208# 209macro(SWIG_MODULE_INITIALIZE name language) 210 string(TOUPPER "${language}" SWIG_MODULE_${name}_LANGUAGE) 211 string(TOLOWER "${language}" SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG) 212 213 set(SWIG_MODULE_${name}_EXTRA_FLAGS) 214 if (NOT DEFINED SWIG_MODULE_${name}_NOPROXY) 215 set (SWIG_MODULE_${name}_NOPROXY FALSE) 216 endif() 217 if ("-noproxy" IN_LIST CMAKE_SWIG_FLAGS) 218 set (SWIG_MODULE_${name}_NOPROXY TRUE) 219 endif () 220 221 if (SWIG_MODULE_${name}_NOPROXY AND NOT "-noproxy" IN_LIST CMAKE_SWIG_FLAGS) 222 list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-noproxy") 223 endif() 224 if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "UNKNOWN") 225 message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") 226 elseif(SWIG_MODULE_${name}_LANGUAGE STREQUAL "PERL") 227 list(APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") 228 endif() 229endmacro() 230 231# 232# For a given language, input file, and output file, determine extra files that 233# will be generated. This is internal swig macro. 234# 235 236function(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile) 237 set(files) 238 get_source_file_property(module_basename 239 "${infile}" SWIG_MODULE_NAME) 240 if(NOT swig_module_basename) 241 242 # try to get module name from "%module foo" syntax 243 if ( EXISTS "${infile}" ) 244 file ( STRINGS "${infile}" module_basename REGEX "[ ]*%module[ ]*[a-zA-Z0-9_]+.*" ) 245 endif () 246 if ( module_basename ) 247 string ( REGEX REPLACE "[ ]*%module[ ]*([a-zA-Z0-9_]+).*" "\\1" module_basename "${module_basename}" ) 248 249 else () 250 # try to get module name from "%module (options=...) foo" syntax 251 if ( EXISTS "${infile}" ) 252 file ( STRINGS "${infile}" module_basename REGEX "[ ]*%module[ ]*\\(.*\\)[ ]*[a-zA-Z0-9_]+.*" ) 253 endif () 254 if ( module_basename ) 255 string ( REGEX REPLACE "[ ]*%module[ ]*\\(.*\\)[ ]*([a-zA-Z0-9_]+).*" "\\1" module_basename "${module_basename}" ) 256 257 else () 258 # fallback to file basename 259 get_filename_component(module_basename "${infile}" NAME_WE) 260 endif () 261 endif () 262 263 endif() 264 foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSIONS}) 265 set(extra_file "${generatedpath}/${module_basename}${it}") 266 list(APPEND files "${extra_file}") 267 endforeach() 268 # Treat extra outputs as plain files regardless of language. 269 set_source_files_properties(${files} PROPERTIES LANGUAGE "") 270 271 set (${outfiles} ${files} PARENT_SCOPE) 272endfunction() 273 274# 275# Take swig (*.i) file and add proper custom commands for it 276# 277function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) 278 get_filename_component(swig_source_file_name_we "${infile}" NAME_WE) 279 get_source_file_property(swig_source_file_cplusplus "${infile}" CPLUSPLUS) 280 281 # If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir 282 if(CMAKE_SWIG_OUTDIR) 283 set(outdir ${CMAKE_SWIG_OUTDIR}) 284 else() 285 set(outdir ${CMAKE_CURRENT_BINARY_DIR}) 286 endif() 287 288 if(SWIG_OUTFILE_DIR) 289 set(outfiledir ${SWIG_OUTFILE_DIR}) 290 else() 291 set(outfiledir ${outdir}) 292 endif() 293 294 if(SWIG_WORKING_DIR) 295 set (workingdir "${SWIG_WORKING_DIR}") 296 else() 297 set(workingdir "${outdir}") 298 endif() 299 300 set (swig_source_file_flags ${CMAKE_SWIG_FLAGS}) 301 # handle various swig compile flags properties 302 get_source_file_property (include_directories "${infile}" INCLUDE_DIRECTORIES) 303 if (include_directories) 304 list (APPEND swig_source_file_flags "$<$<BOOL:${include_directories}>:-I$<JOIN:${include_directories},$<SEMICOLON>-I>>") 305 endif() 306 set (property "$<TARGET_PROPERTY:${name},SWIG_INCLUDE_DIRECTORIES>") 307 list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>") 308 309 set (property "$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>") 310 list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>") 311 312 set (property "$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>") 313 get_source_file_property(use_target_include_dirs "${infile}" USE_TARGET_INCLUDE_DIRECTORIES) 314 if (use_target_include_dirs) 315 list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>") 316 elseif(use_target_include_dirs STREQUAL "NOTFOUND") 317 # not defined at source level, rely on target level 318 list (APPEND swig_source_file_flags "$<$<AND:$<BOOL:$<TARGET_PROPERTY:${name},SWIG_USE_TARGET_INCLUDE_DIRECTORIES>>,$<BOOL:${property}>>:-I$<JOIN:${property},$<SEMICOLON>-I>>") 319 endif() 320 321 set (property "$<TARGET_PROPERTY:${name},SWIG_COMPILE_DEFINITIONS>") 322 list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:${property},$<SEMICOLON>-D>>") 323 get_source_file_property (compile_definitions "${infile}" COMPILE_DEFINITIONS) 324 if (compile_definitions) 325 list (APPEND swig_source_file_flags "$<$<BOOL:${compile_definitions}>:-D$<JOIN:${compile_definitions},$<SEMICOLON>-D>>") 326 endif() 327 328 list (APPEND swig_source_file_flags "$<TARGET_PROPERTY:${name},SWIG_COMPILE_OPTIONS>") 329 get_source_file_property (compile_options "${infile}" COMPILE_OPTIONS) 330 if (compile_options) 331 list (APPEND swig_source_file_flags ${compile_options}) 332 endif() 333 334 # legacy support 335 get_source_file_property (swig_flags "${infile}" SWIG_FLAGS) 336 if (swig_flags) 337 list (APPEND swig_source_file_flags ${swig_flags}) 338 endif() 339 340 get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE) 341 342 if (NOT SWIG_MODULE_${name}_NOPROXY) 343 SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE} 344 swig_extra_generated_files 345 "${outdir}" 346 "${swig_source_file_fullname}") 347 endif() 348 set(swig_generated_file_fullname 349 "${outfiledir}/${swig_source_file_name_we}") 350 # add the language into the name of the file (i.e. TCL_wrap) 351 # this allows for the same .i file to be wrapped into different languages 352 string(APPEND swig_generated_file_fullname 353 "${SWIG_MODULE_${name}_LANGUAGE}_wrap") 354 355 if(swig_source_file_cplusplus) 356 string(APPEND swig_generated_file_fullname 357 ".${SWIG_CXX_EXTENSION}") 358 else() 359 string(APPEND swig_generated_file_fullname 360 ".c") 361 endif() 362 363 get_directory_property (cmake_include_directories INCLUDE_DIRECTORIES) 364 list (REMOVE_DUPLICATES cmake_include_directories) 365 set (swig_include_dirs) 366 if (cmake_include_directories) 367 set (swig_include_dirs "$<$<BOOL:${cmake_include_directories}>:-I$<JOIN:${cmake_include_directories},$<SEMICOLON>-I>>") 368 endif() 369 370 set(swig_special_flags) 371 # default is c, so add c++ flag if it is c++ 372 if(swig_source_file_cplusplus) 373 list (APPEND swig_special_flags "-c++") 374 endif() 375 376 set (swig_extra_flags) 377 if(SWIG_MODULE_${name}_LANGUAGE STREQUAL "CSHARP") 378 if(NOT ("-dllimport" IN_LIST swig_source_file_flags OR "-dllimport" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS)) 379 # This makes sure that the name used in the generated DllImport 380 # matches the library name created by CMake 381 list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-dllimport" "${name}") 382 endif() 383 endif() 384 list (APPEND swig_extra_flags ${SWIG_MODULE_${name}_EXTRA_FLAGS}) 385 386 # dependencies 387 set (swig_dependencies ${SWIG_MODULE_${name}_EXTRA_DEPS} $<TARGET_PROPERTY:${name},SWIG_DEPENDS>) 388 get_source_file_property(file_depends "${infile}" DEPENDS) 389 if (file_depends) 390 list (APPEND swig_dependencies ${file_depends}) 391 endif() 392 393 if (UseSWIG_MODULE_VERSION VERSION_GREATER 1) 394 # as part of custom command, start by removing old generated files 395 # to ensure obsolete files do not stay 396 set (swig_cleanup_command COMMAND "${CMAKE_COMMAND}" -E remove_directory "${outdir}") 397 else() 398 unset (swig_cleanup_command) 399 endif() 400 401 # IMPLICIT_DEPENDS below can not handle situations where a dependent file is 402 # removed. We need an extra step with timestamp and custom target, see #16830 403 # As this is needed only for Makefile generator do it conditionally 404 if(CMAKE_GENERATOR MATCHES "Make") 405 __swig_compute_timestamp(${name} ${SWIG_MODULE_${name}_LANGUAGE} 406 "${infile}" "${workingdir}" swig_generated_timestamp) 407 set(swig_custom_output "${swig_generated_timestamp}") 408 set(swig_custom_products 409 BYPRODUCTS "${swig_generated_file_fullname}" ${swig_extra_generated_files}) 410 set(swig_timestamp_command 411 COMMAND ${CMAKE_COMMAND} -E touch "${swig_generated_timestamp}") 412 else() 413 set(swig_custom_output 414 "${swig_generated_file_fullname}" ${swig_extra_generated_files}) 415 set(swig_custom_products) 416 set(swig_timestamp_command) 417 endif() 418 add_custom_command( 419 OUTPUT ${swig_custom_output} 420 ${swig_custom_products} 421 ${swig_cleanup_command} 422 # Let's create the ${outdir} at execution time, in case dir contains $(OutDir) 423 COMMAND "${CMAKE_COMMAND}" -E make_directory ${outdir} ${outfiledir} 424 ${swig_timestamp_command} 425 COMMAND "${CMAKE_COMMAND}" -E env "SWIG_LIB=${SWIG_DIR}" "${SWIG_EXECUTABLE}" 426 "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" 427 "${swig_source_file_flags}" 428 -outdir "${outdir}" 429 ${swig_special_flags} 430 ${swig_extra_flags} 431 "${swig_include_dirs}" 432 -o "${swig_generated_file_fullname}" 433 "${swig_source_file_fullname}" 434 MAIN_DEPENDENCY "${swig_source_file_fullname}" 435 DEPENDS ${swig_dependencies} 436 IMPLICIT_DEPENDS CXX "${swig_source_file_fullname}" 437 COMMENT "Swig source ${infile}" 438 COMMAND_EXPAND_LISTS) 439 set_source_files_properties("${swig_generated_file_fullname}" ${swig_extra_generated_files} 440 PROPERTIES GENERATED 1) 441 442 ## add all properties for generated file to various properties 443 get_property (include_directories SOURCE "${infile}" PROPERTY GENERATED_INCLUDE_DIRECTORIES) 444 set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY INCLUDE_DIRECTORIES ${include_directories} $<TARGET_PROPERTY:${name},SWIG_GENERATED_INCLUDE_DIRECTORIES>) 445 446 # get_property (compile_definitions SOURCE "${infile}" PROPERTY GENERATED_COMPILE_DEFINITIONS) 447 # set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_DEFINITIONS $<TARGET_PROPERTY:${name},SWIG_GENERATED_COMPILE_DEFINITIONS> ${compile_definitions}) 448 449 # get_property (compile_options SOURCE "${infile}" PROPERTY GENERATED_COMPILE_OPTIONS) 450 # set_property (SOURCE "${swig_generated_file_fullname}" PROPERTY COMPILE_OPTIONS $<TARGET_PROPERTY:${name},SWIG_GENERATED_COMPILE_OPTIONS> ${compile_options}) 451 452 set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files} PARENT_SCOPE) 453 454 # legacy support 455 set (swig_generated_file_fullname "${swig_generated_file_fullname}" PARENT_SCOPE) 456endfunction() 457 458# 459# Create Swig module 460# 461macro(SWIG_ADD_MODULE name language) 462 message(DEPRECATION "SWIG_ADD_MODULE is deprecated. Use SWIG_ADD_LIBRARY instead.") 463 swig_add_library(${name} 464 LANGUAGE ${language} 465 TYPE MODULE 466 SOURCES ${ARGN}) 467endmacro() 468 469 470function(SWIG_ADD_LIBRARY name) 471 set(options NO_PROXY) 472 set(oneValueArgs LANGUAGE 473 TYPE 474 OUTPUT_DIR 475 OUTFILE_DIR) 476 set(multiValueArgs SOURCES) 477 cmake_parse_arguments(_SAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 478 479 if (TARGET ${name}) 480 # a target with same name is already defined. 481 # call NOW add_library command to raise the most useful error message 482 add_library(${name}) 483 return() 484 endif() 485 486 if (_SAM_UNPARSED_ARGUMENTS) 487 message(FATAL_ERROR "SWIG_ADD_LIBRARY: ${_SAM_UNPARSED_ARGUMENTS}: unexpected arguments") 488 endif() 489 490 if(NOT DEFINED _SAM_LANGUAGE) 491 message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing LANGUAGE argument") 492 endif() 493 494 if(NOT DEFINED _SAM_SOURCES) 495 message(FATAL_ERROR "SWIG_ADD_LIBRARY: Missing SOURCES argument") 496 endif() 497 498 if(NOT DEFINED _SAM_TYPE) 499 set(_SAM_TYPE MODULE) 500 elseif(_SAM_TYPE STREQUAL "USE_BUILD_SHARED_LIBS") 501 unset(_SAM_TYPE) 502 endif() 503 504 if (NOT DEFINED UseSWIG_MODULE_VERSION) 505 set (UseSWIG_MODULE_VERSION 1) 506 elseif (NOT UseSWIG_MODULE_VERSION MATCHES "^(1|2)$") 507 message (FATAL_ERROR "UseSWIG_MODULE_VERSION: ${UseSWIG_MODULE_VERSION}: invalid value. 1 or 2 is expected.") 508 endif() 509 510 set (workingdir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${name}.dir") 511 # set special variable to pass extra information to command SWIG_ADD_SOURCE_TO_MODULE 512 # which cannot be changed due to legacy compatibility 513 set (SWIG_WORKING_DIR "${workingdir}") 514 515 set (outputdir "${_SAM_OUTPUT_DIR}") 516 if (NOT _SAM_OUTPUT_DIR) 517 if (CMAKE_SWIG_OUTDIR) 518 set (outputdir "${CMAKE_SWIG_OUTDIR}") 519 else() 520 if (UseSWIG_MODULE_VERSION VERSION_GREATER 1) 521 set (outputdir "${workingdir}/${_SAM_LANGUAGE}.files") 522 else() 523 set (outputdir "${CMAKE_CURRENT_BINARY_DIR}") 524 endif() 525 endif() 526 endif() 527 528 set (outfiledir "${_SAM_OUTFILE_DIR}") 529 if(NOT _SAM_OUTFILE_DIR) 530 if (SWIG_OUTFILE_DIR) 531 set (outfiledir "${SWIG_OUTFILE_DIR}") 532 else() 533 if (_SAM_OUTPUT_DIR OR CMAKE_SWIG_OUTDIR) 534 set (outfiledir "${outputdir}") 535 else() 536 set (outfiledir "${workingdir}") 537 endif() 538 endif() 539 endif() 540 # set again, locally, predefined variables to ensure compatibility 541 # with command SWIG_ADD_SOURCE_TO_MODULE 542 set(CMAKE_SWIG_OUTDIR "${outputdir}") 543 set(SWIG_OUTFILE_DIR "${outfiledir}") 544 545 set (SWIG_MODULE_${name}_NOPROXY ${_SAM_NO_PROXY}) 546 swig_module_initialize(${name} ${_SAM_LANGUAGE}) 547 548 set(swig_dot_i_sources ${_SAM_SOURCES}) 549 list(FILTER swig_dot_i_sources INCLUDE REGEX "\\.i$") 550 if (NOT swig_dot_i_sources) 551 message(FATAL_ERROR "SWIG_ADD_LIBRARY: no SWIG interface files specified") 552 endif() 553 set(swig_other_sources ${_SAM_SOURCES}) 554 list(REMOVE_ITEM swig_other_sources ${swig_dot_i_sources}) 555 556 set(swig_generated_sources) 557 set(swig_generated_timestamps) 558 foreach(swig_it IN LISTS swig_dot_i_sources) 559 SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source "${swig_it}") 560 list (APPEND swig_generated_sources "${swig_generated_source}") 561 if(CMAKE_GENERATOR MATCHES "Make") 562 __swig_compute_timestamp(${name} ${SWIG_MODULE_${name}_LANGUAGE} "${swig_it}" 563 "${workingdir}" swig_timestamp) 564 list (APPEND swig_generated_timestamps "${swig_timestamp}") 565 endif() 566 endforeach() 567 set_property (DIRECTORY APPEND PROPERTY 568 ADDITIONAL_MAKE_CLEAN_FILES ${swig_generated_sources} ${swig_generated_timestamps}) 569 if (UseSWIG_MODULE_VERSION VERSION_GREATER 1) 570 set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${outputdir}") 571 endif() 572 573 add_library(${name} 574 ${_SAM_TYPE} 575 ${swig_generated_sources} 576 ${swig_other_sources}) 577 if(CMAKE_GENERATOR MATCHES "Make") 578 # see IMPLICIT_DEPENDS above 579 add_custom_target(${name}_swig_compilation DEPENDS ${swig_generated_timestamps}) 580 add_dependencies(${name} ${name}_swig_compilation) 581 endif() 582 if(_SAM_TYPE STREQUAL "MODULE") 583 set_target_properties(${name} PROPERTIES NO_SONAME ON) 584 endif() 585 string(TOLOWER "${_SAM_LANGUAGE}" swig_lowercase_language) 586 if (swig_lowercase_language STREQUAL "octave") 587 set_target_properties(${name} PROPERTIES PREFIX "") 588 set_target_properties(${name} PROPERTIES SUFFIX ".oct") 589 elseif (swig_lowercase_language STREQUAL "go") 590 set_target_properties(${name} PROPERTIES PREFIX "") 591 elseif (swig_lowercase_language STREQUAL "java") 592 # In java you want: 593 # System.loadLibrary("LIBRARY"); 594 # then JNI will look for a library whose name is platform dependent, namely 595 # MacOS : libLIBRARY.jnilib 596 # Windows: LIBRARY.dll 597 # Linux : libLIBRARY.so 598 if (APPLE) 599 set_target_properties (${name} PROPERTIES SUFFIX ".jnilib") 600 endif() 601 if ((WIN32 AND MINGW) OR CYGWIN OR CMAKE_SYSTEM_NAME STREQUAL MSYS) 602 set_target_properties(${name} PROPERTIES PREFIX "") 603 endif() 604 elseif (swig_lowercase_language STREQUAL "lua") 605 if(_SAM_TYPE STREQUAL "MODULE") 606 set_target_properties(${name} PROPERTIES PREFIX "") 607 endif() 608 elseif (swig_lowercase_language STREQUAL "python") 609 if (SWIG_MODULE_${name}_NOPROXY) 610 set_target_properties(${name} PROPERTIES PREFIX "") 611 else() 612 # swig will produce a module.py containing an 'import _modulename' statement, 613 # which implies having a corresponding _modulename.so (*NIX), _modulename.pyd (Win32), 614 # unless the -noproxy flag is used 615 set_target_properties(${name} PROPERTIES PREFIX "_") 616 endif() 617 # Python extension modules on Windows must have the extension ".pyd" 618 # instead of ".dll" as of Python 2.5. Older python versions do support 619 # this suffix. 620 # http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000 621 # <quote> 622 # Windows: .dll is no longer supported as a filename extension for extension modules. 623 # .pyd is now the only filename extension that will be searched for. 624 # </quote> 625 if(WIN32 AND NOT CYGWIN) 626 set_target_properties(${name} PROPERTIES SUFFIX ".pyd") 627 endif() 628 elseif (swig_lowercase_language STREQUAL "r") 629 set_target_properties(${name} PROPERTIES PREFIX "") 630 elseif (swig_lowercase_language STREQUAL "ruby") 631 # In ruby you want: 632 # require 'LIBRARY' 633 # then ruby will look for a library whose name is platform dependent, namely 634 # MacOS : LIBRARY.bundle 635 # Windows: LIBRARY.dll 636 # Linux : LIBRARY.so 637 set_target_properties (${name} PROPERTIES PREFIX "") 638 if (APPLE) 639 set_target_properties (${name} PROPERTIES SUFFIX ".bundle") 640 endif () 641 elseif (swig_lowercase_language STREQUAL "perl") 642 # assume empty prefix because we expect the module to be dynamically loaded 643 set_target_properties (${name} PROPERTIES PREFIX "") 644 if (APPLE) 645 set_target_properties (${name} PROPERTIES SUFFIX ".dylib") 646 endif () 647 else() 648 # assume empty prefix because we expect the module to be dynamically loaded 649 set_target_properties (${name} PROPERTIES PREFIX "") 650 endif () 651 652 # target property SWIG_SUPPORT_FILES_DIRECTORY specify output directory of support files 653 set_property (TARGET ${name} PROPERTY SWIG_SUPPORT_FILES_DIRECTORY "${outputdir}") 654 # target property SWIG_SUPPORT_FILES lists principal proxy support files 655 if (NOT SWIG_MODULE_${name}_NOPROXY) 656 string(TOUPPER "${_SAM_LANGUAGE}" swig_uppercase_language) 657 set(swig_all_support_files) 658 foreach (swig_it IN LISTS SWIG_${swig_uppercase_language}_EXTRA_FILE_EXTENSIONS) 659 set (swig_support_files ${swig_generated_sources}) 660 list (FILTER swig_support_files INCLUDE REGEX ".*${swig_it}$") 661 list(APPEND swig_all_support_files ${swig_support_files}) 662 endforeach() 663 if (swig_all_support_files) 664 list(REMOVE_DUPLICATES swig_all_support_files) 665 endif() 666 set_property (TARGET ${name} PROPERTY SWIG_SUPPORT_FILES ${swig_all_support_files}) 667 endif() 668 669 # to ensure legacy behavior, export some variables 670 set (SWIG_MODULE_${name}_LANGUAGE "${SWIG_MODULE_${name}_LANGUAGE}" PARENT_SCOPE) 671 set (SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}" PARENT_SCOPE) 672 set (SWIG_MODULE_${name}_REAL_NAME "${name}" PARENT_SCOPE) 673 set (SWIG_MODULE_${name}_NOPROXY "${SWIG_MODULE_${name}_NOPROXY}" PARENT_SCOPE) 674 set (SWIG_MODULE_${name}_EXTRA_FLAGS "${SWIG_MODULE_${name}_EXTRA_FLAGS}" PARENT_SCOPE) 675 # the last one is a bit crazy but it is documented, so... 676 # NOTA: works as expected if only ONE input file is specified 677 set (swig_generated_file_fullname "${swig_generated_file_fullname}" PARENT_SCOPE) 678endfunction() 679 680# 681# Like TARGET_LINK_LIBRARIES but for swig modules 682# 683function(SWIG_LINK_LIBRARIES name) 684 message(DEPRECATION "SWIG_LINK_LIBRARIES is deprecated. Use TARGET_LINK_LIBRARIES instead.") 685 if(SWIG_MODULE_${name}_REAL_NAME) 686 target_link_libraries(${name} ${ARGN}) 687 else() 688 message(SEND_ERROR "Cannot find Swig library \"${name}\".") 689 endif() 690endfunction() 691