############################################################################### # configure tcl # TCL support is currently unstable. Show the warning message message(WARNING "TCL support is currently unstable.But if we you still want to use it, please go ahead!") if(WRAP_ITK_INSTALL_COMPONENT_PER_MODULE) message(WARNING "Option WRAP_ITK_INSTALL_COMPONENT_PER_MODULE is not supported for TCL wrapping language") endif() find_package(TCL REQUIRED) # Hide useless settings provided by FindTCL. foreach(entry TCL_LIBRARY_DEBUG TK_LIBRARY_DEBUG TCL_STUB_LIBRARY TCL_STUB_LIBRARY_DEBUG TK_STUB_LIBRARY TK_STUB_LIBRARY_DEBUG TK_WISH) set(${entry} "${${entry}}" CACHE INTERNAL "This value is not used by ITK.") endforeach() include_directories(${TCL_INCLUDE_PATH} ${TK_INCLUDE_PATH}) ############################################################################### # store the current dir, so it can be reused later set(ITK_WRAP_TCL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tcl source dir") set(ITK_WRAP_TCL_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "tcl binary dir") ############################################################################### # create the tcl directory in the classindex dir file(MAKE_DIRECTORY ${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl) macro(itk_wrap_module_tcl library_name) set(ITK_WRAP_TCL_LIBRARY_DEPS ) set(ITK_WRAP_TCL_LIBRARY_DECLS ) set(ITK_WRAP_TCL_LIBRARY_CALLS ) set(ITK_WRAP_TCL_CXX_FILES ) endmacro() macro(itk_end_wrap_module_tcl) # Loop over the extra swig input files and add them to the generated files # lists. Guess that the generated cxx output will have the same name as # the .i input file. foreach(source ${WRAPPER_LIBRARY_SWIG_INPUTS}) get_filename_component(base_name ${source} NAME_WE) itk_wrap_submodule_tcl("${base_name}") itk_end_wrap_submodule_tcl("${base_name}") endforeach() # create the tcl customization stuff in the main module # it allow to group the tcls module in a single shared lib, by loading the int # functions of the module. I also import the objects from the submodules in the # main module. # # It uses ITK_WRAP_TCL_LIBRARY_DECLS, ITK_WRAP_TCL_LIBRARY_CALLS configure_file("${ITK_WRAP_TCL_SOURCE_DIR}/main_module_ext.i.in" "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl/${WRAPPER_LIBRARY_NAME}_ext.i" @ONLY) ) # set some var reused later set(interface_file "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/${WRAPPER_LIBRARY_NAME}.i") set(lib ${WRAPPER_LIBRARY_NAME}Tcl) set(cpp_file "${CMAKE_CURRENT_BINARY_DIR}/${WRAPPER_LIBRARY_NAME}Tcl.cpp") set(swig_command ${SWIG_EXECUTABLE}) if(ITK_USE_CCACHE) set(swig_command ${CCACHE_EXECUTABLE} ${swig_command}) endif() # and generate c++ code from the main module swig interface. add_custom_command( OUTPUT ${cpp_file} COMMAND ${swig_command} -c++ -tcl -O -features autodoc=1 # -Werror # -fcompact -w509 # Overloaded method -w365 # operator+= ignored -w366 # operator-= ignored -w367 # operator*= ignored -w368 # operator/= ignored -w378 # operator!= ignored -w503 # Can't wrap 'operator []' unless renamed to a valid identifier. -w508 # Declaration of '???' shadows declaration accessible via operator->() ### TODO: remove that once the bug for std::vector is fixed ### -w401 # Maybe you forgot to instantiate 'XXX' using %template. ### -w350 -w394 -w395 # operator new/new[]/delete[] ignored -o ${cpp_file} -I${GENERATORS_SRC_DIR} -I${WRAP_ITK_TYPEDEFS_DIRECTORY}/tcl -I${WRAP_ITK_TYPEDEFS_DIRECTORY} -outdir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${interface_file} WORKING_DIRECTORY ${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl DEPENDS ${DEPS} ${ITK_WRAP_TCL_LIBRARY_DEPS} ${interface_file} ${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl/${WRAPPER_LIBRARY_NAME}_ext.i ${SWIG_EXECUTABLE} ) WRAP_ITK_BINDINGS_INSTALL("/Tcl" "${tcl_file}") # build all the c++ files from this module in a common lib set(lib ${WRAPPER_LIBRARY_NAME}Tcl) add_library(${lib} SHARED ${cpp_file} ${ITK_WRAP_TCL_CXX_FILES} ${WRAPPER_LIBRARY_CXX_SOURCES}) if(CMAKE_COMPILER_IS_GNUCC) # disable warnings generated by swig set_target_properties(${lib} PROPERTIES COMPILE_FLAGS "-Wno-missing-field-initializers -Wno-shadow") endif() target_link_libraries(${lib} ${WRAPPER_LIBRARY_LINK_LIBRARIES} ${TCL_LIBRARY}) if(${module_prefix}_WRAP_EXPLICIT AND NOT ${WRAPPER_LIBRARY_NAME} STREQUAL ITKTclBase) target_link_libraries(${lib} ${WRAPPER_LIBRARY_NAME}Explicit) endif() add_dependencies(${lib} ${WRAPPER_LIBRARY_NAME}Swig) install(TARGETS "${lib}" DESTINATION "${ITK_INSTALL_LIBRARY_DIR}/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}/Tcl" COMPONENT ${WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER}RuntimeLibraries ) if(NOT EXTERNAL_WRAP_ITK_PROJECT) # don't depends on the targets from wrapitk in external projects foreach(dep ${WRAPPER_LIBRARY_DEPENDS}) add_dependencies(${lib} ${dep}Swig) endforeach() endif() endmacro() macro(itk_end_wrap_submodule_tcl group_name) set(base_name ${group_name}) # the default typemaps, exception handler, and includes set(ITK_WRAP_TCL_SWIG_EXT "%import tclBase.i\n\n${ITK_WRAP_TCL_SWIG_EXT}") # create the swig interface for all the groups in the module # set(interface_file "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/${base_name}.i") set(lib ${group_name}Tcl) set(cpp_file "${CMAKE_CURRENT_BINARY_DIR}/${base_name}Tcl.cpp") # create the tcl customization for that wrap_*.cmake file. configure_file("${ITK_WRAP_TCL_SOURCE_DIR}/module_ext.i.in" "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl/${group_name}_ext.i" @ONLY) ) # prepare dependencies set(DEPS ) foreach(dep ${WRAPPER_LIBRARY_DEPENDS}) list(APPEND DEPS ${${dep}SwigFiles}) endforeach() set(swig_command ${SWIG_EXECUTABLE}) if(ITK_USE_CCACHE) set(swig_command ${CCACHE_EXECUTABLE} ${swig_command}) endif() # and run swig to produce the c++ file and the .tcl file add_custom_command( OUTPUT ${cpp_file} COMMAND ${swig_command} -c++ -tcl -O -features autodoc=1 # -Werror # -fcompact -w509 # Overloaded method -w365 # operator+= ignored -w366 # operator-= ignored -w367 # operator*= ignored -w368 # operator/= ignored -w378 # operator!= ignored -w503 # Can't wrap 'operator []' unless renamed to a valid identifier -w508 # Declaration of '???' shadows declaration accessible via operator->() ### TODO: remove that once the bug for std::vector is fixed ### -w401 # Maybe you forgot to instantiate 'XXX' using %template. ### -w350 -w394 -w395 # operator new/new[]/delete[] ignored -o ${cpp_file} -I${GENERATORS_SRC_DIR} -I${WRAP_ITK_TYPEDEFS_DIRECTORY}/tcl -I${WRAP_ITK_TYPEDEFS_DIRECTORY} -outdir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${interface_file} WORKING_DIRECTORY ${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl DEPENDS ${DEPS} ${interface_file} ${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl/${base_name}_ext.i ${SWIG_EXECUTABLE} # ${ITK_WRAP_TCL_LIBRARY_DEPS} ) # gcc visibility can't be used without getting errors when passing objects # from one module to an other # # if(CMAKE_COMPILER_IS_GNUCC) # set_target_properties(${lib} PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") # endif() # add the c++ files which will be generated by the swig command to the # list of tcl related c++ files, so they can be built at the end # of the current module. list(APPEND ITK_WRAP_TCL_CXX_FILES ${cpp_file}) # add needed files to the deps list list(APPEND ITK_WRAP_TCL_LIBRARY_DEPS "${WRAPPER_MASTER_INDEX_OUTPUT_DIR}/tcl/${base_name}_ext.i" "${cpp_file}") # add this wrap_*.cmake stuff to the list of modules to init in the main module. # first the extern c declaration string(REGEX REPLACE "^(.)(.+)$" "\\1" first "${group_name}") string(REGEX REPLACE "^(.)(.+)$" "\\2" rest "${group_name}") string(TOUPPER "${first}" first) string(TOLOWER "${rest}" rest) set(capital_group_name "${first}${rest}tcl") set(ITK_WRAP_TCL_LIBRARY_DECLS "${ITK_WRAP_TCL_LIBRARY_DECLS}extern \"C\" int ${capital_group_name}_Init( Tcl_Interp* );\n") # and the call of the extern function set(ITK_WRAP_TCL_LIBRARY_CALLS "${ITK_WRAP_TCL_LIBRARY_CALLS} ${capital_group_name}_Init( interp );\n") endmacro() macro(itk_wrap_one_type_tcl wrap_method wrap_class swig_name template_params) endmacro() macro(ADD_TCL_CONFIG_TEMPLATE base_name wrap_class swig_name template_params) endmacro() macro(itk_wrap_submodule_tcl module) set(ITK_WRAP_TCL_SWIG_EXT "") endmacro() macro(itk_wrap_named_class_tcl class swig_name) # store the current class wrapped, so we can generate the typemaps for itk::ImageSource set(ITK_WRAP_TCL_CURRENT_CLASS "${class}") set(ITK_WRAP_TCL_CURRENT_SWIG_NAME "${swig_name}") endmacro() macro(itk_wrap_template_tcl name types) endmacro() macro(itk_wrap_simple_type_tcl wrap_class swig_name) if("${wrap_class}" MATCHES "<.*>") string(REGEX REPLACE "^([^<]+)< *(.+) *>([^>]*)$" "\\1" cpp_name "${wrap_class}") string(REGEX REPLACE "^([^<]+)< *(.+) *>([^>]*)$" "\\2" template_params "${wrap_class}") string(REGEX REPLACE "^([^<]+)< *(.+) *>([^>]*)$" "\\3" ext_def "${wrap_class}") else() set(cpp_name "${wrap_class}") set(template_params NO_TEMPLATE) set(ext_def "") endif() string(REGEX REPLACE ".*::" "" simple_name "${cpp_name}") # message("${wrap_class} -- ${swig_name}") # message("${cpp_name} -- ${template_params} -- ${ext_def}") # can't use that because std_vector.i complains loudly (with an error) about invalid superclass when that superclass is a std::vector # not wrapped with %template # but we can't declare them outside the current file without making swig use function defined outside # TODO: reenable that once that bug is fixed # # if("${cpp_name}" STREQUAL "itk::VectorContainer" AND NOT "${swig_name}" MATCHES "Pointer$") # # add a template definition for the superclass which is not in ITK # string(REGEX REPLACE "^[^,]+, *(.+) *$" "\\1" superclass_template_param "${template_params}") # if("${superclass_template_param}" MATCHES "::") # set(param "${superclass_template_param}") # string(REPLACE "::" "" superclass_template_param "${superclass_template_param}") # string(REPLACE "unsigned" "U" superclass_template_param "${superclass_template_param}") # string(REPLACE "signed" "S" superclass_template_param "${superclass_template_param}") # string(REPLACE "char" "C" superclass_template_param "${superclass_template_param}") # string(REPLACE "short" "S" superclass_template_param "${superclass_template_param}") # string(REPLACE "long" "L" superclass_template_param "${superclass_template_param}") # string(REPLACE "float" "F" superclass_template_param "${superclass_template_param}") # string(REPLACE "double" "D" superclass_template_param "${superclass_template_param}") # string(REPLACE " " "" superclass_template_param "${superclass_template_param}") # string(REPLACE "<" "" superclass_template_param "${superclass_template_param}") # string(REPLACE ">" "" superclass_template_param "${superclass_template_param}") # string(REPLACE "," "" superclass_template_param "${superclass_template_param}") # set(ITK_WRAP_TCL_SWIG_EXT "${ITK_WRAP_TCL_SWIG_EXT}%template(${swig_name}_Superclass) std::vector< ${superclass_template_param} >;\n") # endif() # endif() # This part is useless because swig doesn't recognize that std::map< X, Y > is the same than # std::map< X, Y, std::less< X > > and doesn't support a third parameter in the template # specification. # TODO: make a bugreport # # if("${cpp_name}" STREQUAL "itk::MapContainer" AND NOT "${swig_name}" MATCHES "Pointer$") # # add a template definition for the superclass which is not in ITK # string(REGEX REPLACE "^[^,]+, *(.+) *$" "\\1" superclass_template_param "${template_params}") # if("${superclass_template_param}" MATCHES "::") # set(param "${superclass_template_param}") # string(REPLACE "::" "" superclass_template_param "${superclass_template_param}") # string(REPLACE "unsigned" "U" superclass_template_param "${superclass_template_param}") # string(REPLACE "signed" "S" superclass_template_param "${superclass_template_param}") # string(REPLACE "char" "C" superclass_template_param "${superclass_template_param}") # string(REPLACE "short" "S" superclass_template_param "${superclass_template_param}") # string(REPLACE "long" "L" superclass_template_param "${superclass_template_param}") # string(REPLACE "float" "F" superclass_template_param "${superclass_template_param}") # string(REPLACE "double" "D" superclass_template_param "${superclass_template_param}") # string(REPLACE " " "" superclass_template_param "${superclass_template_param}") # string(REPLACE "<" "" superclass_template_param "${superclass_template_param}") # string(REPLACE ">" "" superclass_template_param "${superclass_template_param}") # string(REPLACE "," "" superclass_template_param "${superclass_template_param}") # set(ITK_WRAP_TCL_SWIG_EXT "${ITK_WRAP_TCL_SWIG_EXT}%template(${swig_name}_Superclass) std::map< unsigned long, ${superclass_template_param}, std::less< unsigned long > >;\n") # endif() # endif() endmacro() ############################################################################### # Create the TclUtils library if(NOT EXTERNAL_WRAP_ITK_PROJECT) add_subdirectory(Tests) macro(itk_end_wrap_modules_tcl) ############################################################################### # Configure pkgIndex.tcl for the build tree. if(CMAKE_CONFIGURATION_TYPES) foreach(config ${CMAKE_CONFIGURATION_TYPES}) set(ITK_WRAP_TCL_PACKAGE_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${config}") configure_file("${ITK_WRAP_TCL_SOURCE_DIR}/pkgIndex.tcl.in" "${ITK_WRAP_TCL_BINARY_DIR}/${config}/pkgIndex.tcl" @ONLY) endforeach() else() set(ITK_WRAP_TCL_PACKAGE_DIR "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") configure_file("${ITK_WRAP_TCL_SOURCE_DIR}/pkgIndex.tcl.in" "${ITK_WRAP_TCL_BINARY_DIR}/pkgIndex.tcl" @ONLY) endif() # configure pkgIndex.tcl for the installed tree set(ITK_WRAP_TCL_PACKAGE_DIR "${ITK_INSTALL_LIBRARY_DIR}/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}/Tcl") configure_file("${ITK_WRAP_TCL_SOURCE_DIR}/pkgIndex.tcl.in" "${ITK_WRAP_TCL_BINARY_DIR}/InstallOnly/itkwish_wont_find_me_here/pkgIndex.tcl" @ONLY) WRAP_ITK_BINDINGS_INSTALL(/Tcl "${ITK_WRAP_TCL_BINARY_DIR}/InstallOnly/itkwish_wont_find_me_here/pkgIndex.tcl") #install the actual executable install(FILES ${ITK_WRAP_TCL_SOURCE_DIR}/itkinteraction.tcl ${ITK_WRAP_TCL_SOURCE_DIR}/itktesting.tcl ${ITK_WRAP_TCL_SOURCE_DIR}/itkdata.tcl ${ITK_WRAP_TCL_SOURCE_DIR}/itkutils.tcl DESTINATION "${ITK_INSTALL_LIBRARY_DIR}/ITK-${ITK_VERSION_MAJOR}.${ITK_VERSION_MINOR}/Tcl" COMPONENT ${WRAP_ITK_INSTALL_COMPONENT_IDENTIFIER}RuntimeLibraries ) endmacro() macro(itk_wrap_modules_tcl) add_subdirectory(${ITK_WRAP_TCL_SOURCE_DIR}/TclBase) endmacro() else() macro(itk_end_wrap_modules_tcl) # just do nothing endmacro() macro(itk_wrap_modules_tcl) # just do nothing endmacro() endif()