#[==[.md # `vtkModuleWrapClientServer` This module includes logic necessary in order to wrap VTK modules using ParaView's ClientServer "language". This allows for classes in the module to be used as proxies between ParaView client and server programs. #]==] #[==[.md INTERNAL ## Wrapping a single module This function generates the wrapped sources for a module. It places the list of generated source files and classes in variables named in the second and third arguments, respectively. ``` _vtk_module_wrap_client_server_sources( ) ``` #]==] cmake_policy(PUSH) cmake_policy(SET CMP0053 NEW) if (POLICY CMP0116) cmake_policy(SET CMP0116 NEW) endif() function (_vtk_module_wrap_client_server_sources module sources classes) _vtk_module_get_module_property("${module}" PROPERTY "exclude_wrap" VARIABLE _vtk_client_server_exclude_wrap) if (_vtk_client_server_exclude_wrap) return () endif () _vtk_module_get_module_property("${module}" PROPERTY "client_server_exclude" VARIABLE _vtk_client_server_exclude) if (_vtk_client_server_exclude) return () endif () set(_vtk_client_server_args_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_client_server_library_name}-client-server.$.args") set(_vtk_client_server_genex_allowed 1) if (CMAKE_VERSION VERSION_LESS "3.19") get_property(_vtk_client_server_target_type TARGET "${_vtk_client_server_target_name}" PROPERTY TYPE) if (_vtk_client_server_target_type STREQUAL "INTERFACE_LIBRARY") set(_vtk_client_server_genex_allowed 0) endif () endif () set(_vtk_client_server_genex_compile_definitions "") set(_vtk_client_server_genex_include_directories "") if (_vtk_client_server_genex_allowed) set(_vtk_client_server_genex_compile_definitions "$") set(_vtk_client_server_genex_include_directories "$") set(_vtk_client_server_genex_interface_compile_definitions "$") set(_vtk_client_server_genex_interface_include_directories "$") set(_vtk_client_server_genex_compile_definitions_all "$,${_vtk_client_server_genex_compile_definitions},${_vtk_client_server_genex_interface_compile_definitions}>") set(_vtk_client_server_genex_include_directories_all "$,${_vtk_client_server_genex_include_directories},${_vtk_client_server_genex_interface_include_directories}>") else () if (NOT DEFINED ENV{CI}) message(AUTHOR_WARNING "ClientServer wrapping is not using target-local compile definitions " "or include directories. This may affect generation of the Client " "Server wrapper sources for the ${module} module. Use CMake 3.19+ to " "guarantee intended behavior.") endif () endif () file(GENERATE OUTPUT "${_vtk_client_server_args_file}" CONTENT "$<$:\n-D\'$\'>\n $<$:\n-I\'$\'>\n") _vtk_module_get_module_property("${module}" PROPERTY "hierarchy" VARIABLE _vtk_client_server_hierarchy_file) get_property(_vtk_client_server_is_imported TARGET "${_vtk_client_server_target_name}" PROPERTY "IMPORTED") if (_vtk_client_server_is_imported OR CMAKE_GENERATOR MATCHES "Ninja") set(_vtk_client_server_command_depend "${_vtk_client_server_hierarchy_file}") else () if (TARGET "${_vtk_client_server_library_name}-hierarchy") set(_vtk_client_server_command_depend "${_vtk_client_server_library_name}-hierarchy") else () message(FATAL_ERROR "The ${module} hierarchy file is attached to a non-imported target " "and a hierarchy target " "(${_vtk_client_server_library_name}-hierarchy) is missing.") endif () endif () # create directory for wrapped source files file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_client_server_library_name}CS") set(_vtk_client_server_sources) _vtk_module_get_module_property("${module}" PROPERTY "headers" VARIABLE _vtk_client_server_headers) set(_vtk_client_server_classes) foreach (_vtk_client_server_header IN LISTS _vtk_client_server_headers) get_filename_component(_vtk_client_server_basename "${_vtk_client_server_header}" NAME_WE) list(APPEND _vtk_client_server_classes "${_vtk_client_server_basename}") set(_vtk_client_server_source_output "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_client_server_library_name}CS/${_vtk_client_server_basename}ClientServer.cxx") set(_vtk_client_server_depfile_genex "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_client_server_library_name}CS/${_vtk_client_server_basename}ClientServer.cxx.$.d") set(_vtk_client_server_depfile_nogenex "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_client_server_library_name}CS/${_vtk_client_server_basename}ClientServer.cxx.d") list(APPEND _vtk_client_server_sources "${_vtk_client_server_source_output}") _vtk_module_depfile_args( MULTI_CONFIG_NEEDS_GENEX TOOL_ARGS _vtk_client_server_depfile_flags CUSTOM_COMMAND_ARGS _vtk_client_server_depfile_args SOURCE "${_vtk_client_server_header}" DEPFILE_PATH "${_vtk_client_server_depfile_genex}" DEPFILE_NO_GENEX_PATH "${_vtk_client_server_depfile_nogenex}" TOOL_FLAGS "-MF") add_custom_command( OUTPUT "${_vtk_client_server_source_output}" COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} "$" ${_vtk_client_server_depfile_flags} "@${_vtk_client_server_args_file}" -o "${_vtk_client_server_source_output}" "${_vtk_client_server_header}" ${_vtk_client_server_warning_args} --types "${_vtk_client_server_hierarchy_file}" ${_vtk_client_server_depfile_args} COMMENT "Generating client_server wrapper sources for ${_vtk_client_server_basename}" DEPENDS "$" "${_vtk_client_server_header}" "${_vtk_client_server_args_file}" "${_vtk_client_server_command_depend}") endforeach () set("${sources}" "${_vtk_client_server_sources}" PARENT_SCOPE) set("${classes}" "${_vtk_client_server_classes}" PARENT_SCOPE) endfunction () #[==[.md INTERNAL ## Generating a client server library A client server library may consist of the wrappings of multiple VTK modules. This is useful for kit-based builds where the modules part of the same kit belong to the same client server library as well. ``` _vtk_module_wrap_client_server_library( ...) ``` The first argument is the name of the client server library. The remaining arguments are VTK modules to include in the library. The remaining information it uses is assumed to be provided by the `vtk_module_wrap_client_server` function. #]==] function (_vtk_module_wrap_client_server_library name) set(_vtk_client_server_library_sources) set(_vtk_client_server_library_classes) foreach (_vtk_client_server_module IN LISTS ARGN) _vtk_module_get_module_property("${_vtk_client_server_module}" PROPERTY "exclude_wrap" VARIABLE _vtk_client_server_exclude_wrap) if (_vtk_client_server_exclude_wrap) continue () endif () _vtk_module_get_module_property("${_vtk_client_server_module}" PROPERTY "client_server_exclude" VARIABLE _vtk_client_server_exclude) if (_vtk_client_server_exclude) return () endif () _vtk_module_wrap_client_server_sources("${_vtk_client_server_module}" _vtk_client_server_sources _vtk_client_server_classes) list(APPEND _vtk_client_server_library_sources ${_vtk_client_server_sources}) list(APPEND _vtk_client_server_library_classes ${_vtk_client_server_classes}) endforeach () if (NOT _vtk_client_server_library_sources) return () endif () set(_vtk_client_server_declarations) set(_vtk_client_server_calls) foreach (_vtk_client_server_class IN LISTS _vtk_client_server_library_classes) string(APPEND _vtk_client_server_declarations "extern \"C\" { void ${_vtk_client_server_class}_Init(vtkClientServerInterpreter*); }\n") string(APPEND _vtk_client_server_calls " ${_vtk_client_server_class}_Init(csi);\n") endforeach () set(_vtk_client_server_init_content "#include \"vtkABI.h\" #include \"vtkClientServerInterpreter.h\" ${_vtk_client_server_declarations} extern \"C\" VTK_ABI_EXPORT void ${name}_Initialize(vtkClientServerInterpreter* csi) { (void)csi; ${_vtk_client_server_calls}}\n") set(_vtk_client_server_init_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${name}Init.cxx") file(GENERATE OUTPUT "${_vtk_client_server_init_file}" CONTENT "${_vtk_client_server_init_content}") # XXX(cmake): Why is this necessary? One would expect that `file(GENERATE)` # would do this automatically. set_property(SOURCE "${_vtk_client_server_init_file}" PROPERTY GENERATED 1) add_library("${name}" STATIC) target_sources("${name}" PRIVATE ${_vtk_client_server_library_sources} "${_vtk_client_server_init_file}") # Add a dummy file set to optimize dependencies. See CMP0154. _vtk_module_add_file_set("${name}" BASE_DIRS "${CMAKE_CURRENT_BINARY_DIR}" NAME dummy) if (BUILD_SHARED_LIBS) set_property(TARGET "${name}" PROPERTY POSITION_INDEPENDENT_CODE 1) endif () set(_vtk_build_LIBRARY_NAME_SUFFIX "${_vtk_client_server_LIBRARY_NAME_SUFFIX}") set(_vtk_build_ARCHIVE_DESTINATION "${_vtk_client_server_DESTINATION}") _vtk_module_apply_properties("${name}") vtk_module_autoinit( MODULES ${ARGN} TARGETS "${name}") target_link_libraries("${name}" PRIVATE ${ARGN} ParaView::RemotingClientServerStream VTK::CommonCore) set(_vtk_client_server_export) if (_vtk_client_server_INSTALL_EXPORT) list(APPEND _vtk_client_server_export EXPORT "${_vtk_client_server_INSTALL_EXPORT}") endif () install( TARGETS "${name}" ${_vtk_client_server_export} COMPONENT "${_vtk_client_server_COMPONENT}" ARCHIVE DESTINATION "${_vtk_client_server_DESTINATION}") endfunction () #[==[.md ## Wrapping a set of VTK modules for ClientServer ``` vtk_module_wrap_client_server( MODULES ... TARGET [WRAPPED_MODULES ] [FUNCTION_NAME ] [DESTINATION ] [INSTALL_EXPORT ] [COMPONENT ] [WARNINGS ...] ) ``` * `MODULES`: (Required) The list of modules to wrap. * `TARGET`: (Required) The target to create which represents all wrapped ClientServer modules. This is used to provide the function used to initialize the bindings. * `WRAPPED_MODULES`: (Recommended) Not all modules are wrappable. This variable will be set to contain the list of modules which were wrapped. * `FUNCTION_NAME`: (Recommended) (Defaults to `_initialize`) The function name to generate in order to initialize the client server bindings.A header with the name `.h` should be included in order to access the initialization function. * `DESTINATION`: (Defaults to `${CMAKE_INSTALL_LIBDIR}`) Where to install the generated libraries. * `INSTALL_EXPORT`: If provided, installs will add the installed libraries and generated interface target to the provided export set. * `COMPONENT`: (Defaults to `development`) All install rules created by this function will use this installation component. * ``WARNINGS``: Warnings to enable. Supported warnings: ``empty``. #]==] function (vtk_module_wrap_client_server) cmake_parse_arguments(_vtk_client_server "" "DESTINATION;INSTALL_EXPORT;TARGET;COMPONENT;FUNCTION_NAME;WRAPPED_MODULES" "MODULES;WARNINGS" ${ARGN}) if (_vtk_client_server_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_wrap_client_server: " "${_vtk_client_server_UNPARSED_ARGUMENTS}") endif () if (NOT _vtk_client_server_MODULES) message(WARNING "No modules were requested for client server wrapping.") return () endif () if (NOT _vtk_client_server_TARGET) message(FATAL_ERROR "The `TARGET` argument is required.") endif () set(_vtk_client_server_known_warnings empty) set(_vtk_client_server_warning_args) foreach (_vtk_client_server_warning IN LISTS _vtk_client_server_WARNINGS) if (NOT _vtk_client_server_warning IN_LIST _vtk_client_server_known_warnings) message(FATAL_ERROR "Unrecognized warning: ${_vtk_client_server_warning}") endif () list(APPEND _vtk_client_server_warning_args "-W${_vtk_client_server_warning}") endforeach () if (NOT DEFINED _vtk_client_server_DESTINATION) set(_vtk_client_server_DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif () if (NOT DEFINED _vtk_client_server_COMPONENT) set(_vtk_client_server_COMPONENT "development") endif () if (NOT DEFINED _vtk_client_server_FUNCTION_NAME) set(_vtk_client_server_FUNCTION_NAME "${_vtk_client_server_TARGET}_initialize") endif () # Disable CMake's automoc support for these targets. set(CMAKE_AUTOMOC 0) set(CMAKE_AUTORCC 0) set(CMAKE_AUTOUIC 0) # TODO: Install cmake properties? set(_vtk_client_server_all_modules) set(_vtk_client_server_all_wrapped_modules) foreach (_vtk_client_server_module IN LISTS _vtk_client_server_MODULES) _vtk_module_get_module_property("${_vtk_client_server_module}" PROPERTY "exclude_wrap" VARIABLE _vtk_client_server_exclude_wrap) if (_vtk_client_server_exclude_wrap) continue () endif () _vtk_module_get_module_property("${_vtk_client_server_module}" PROPERTY "client_server_exclude" VARIABLE _vtk_client_server_exclude) if (_vtk_client_server_exclude) continue () endif () _vtk_module_real_target(_vtk_client_server_target_name "${_vtk_client_server_module}") _vtk_module_get_module_property("${_vtk_client_server_module}" PROPERTY "library_name" VARIABLE _vtk_client_server_library_name) _vtk_module_wrap_client_server_library("${_vtk_client_server_library_name}CS" "${_vtk_client_server_module}") if (TARGET "${_vtk_client_server_library_name}CS") list(APPEND _vtk_client_server_all_modules "${_vtk_client_server_library_name}CS") list(APPEND _vtk_client_server_all_wrapped_modules "${_vtk_client_server_module}") endif () endforeach () if (NOT _vtk_client_server_all_modules) message(FATAL_ERROR "No modules given could be wrapped.") endif () if (DEFINED _vtk_client_server_WRAPPED_MODULES) set("${_vtk_client_server_WRAPPED_MODULES}" "${_vtk_client_server_all_wrapped_modules}" PARENT_SCOPE) endif () if (_vtk_client_server_TARGET) add_library("${_vtk_client_server_TARGET}" INTERFACE) target_include_directories("${_vtk_client_server_TARGET}" INTERFACE "$") set(_vtk_client_server_all_modules_include_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_vtk_client_server_TARGET}/${_vtk_client_server_TARGET}.h") set(_vtk_client_server_declarations) set(_vtk_client_server_calls) foreach (_vtk_client_server_module IN LISTS _vtk_client_server_all_modules) string(APPEND _vtk_client_server_declarations "extern \"C\" void ${_vtk_client_server_module}_Initialize(vtkClientServerInterpreter*);\n") string(APPEND _vtk_client_server_calls " ${_vtk_client_server_module}_Initialize(csi);\n") endforeach () set(_vtk_client_server_all_modules_include_content "#ifndef ${_vtk_client_server_TARGET}_h #define ${_vtk_client_server_TARGET}_h #include \"vtkClientServerInterpreter.h\" ${_vtk_client_server_declarations} inline void ${_vtk_client_server_FUNCTION_NAME}(vtkClientServerInterpreter* csi) { (void)csi; ${_vtk_client_server_calls}} #endif\n") file(GENERATE OUTPUT "${_vtk_client_server_all_modules_include_file}" CONTENT "${_vtk_client_server_all_modules_include_content}") target_link_libraries("${_vtk_client_server_TARGET}" INTERFACE ${_vtk_client_server_all_modules}) set(_vtk_client_server_export) if (_vtk_client_server_INSTALL_EXPORT) list(APPEND _vtk_client_server_export EXPORT "${_vtk_client_server_INSTALL_EXPORT}") endif () install( TARGETS "${_vtk_client_server_TARGET}" ${_vtk_client_server_export} COMPONENT "${_vtk_client_server_COMPONENT}" ARCHIVE DESTINATION "${_vtk_client_server_DESTINATION}") endif () endfunction () #[==[.md ## Excluding a module from wrapping Some modules should not be wrapped using client server bindings. Since this is independent of general wrapping facilities, an additional property is used to check. This may be set using the `vtk_module_client_server_exclude` function. ``` vtk_module_client_server_exclude( [MODULE ]) ``` The `MODULE` defaults to the module currently being built. If a module is not being built when this function is called, it must be provided. #]==] function (vtk_module_client_server_exclude) cmake_parse_arguments(_vtk_client_server_exclude "" "MODULE" "" ${ARGN}) if (_vtk_client_server_exclude_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments for vtk_module_wrap_client_server_exclude: " "${_vtk_client_server_exclude_UNPARSED_ARGUMENTS}") endif () if (NOT DEFINED _vtk_client_server_exclude_MODULE) if (NOT DEFINED _vtk_build_module) message(FATAL_ERROR "The `MODULE` argument must be provided outside of a module build.") endif () set(_vtk_client_server_exclude_MODULE "${_vtk_build_module}") endif () _vtk_module_set_module_property("${_vtk_client_server_exclude_MODULE}" PROPERTY "client_server_exclude" VALUE 1) endfunction () cmake_policy(POP)