-# Copyright (C) 2009-2012 EDF R&D
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-
-import os, shutil, glob, socket
-import traceback
-import warnings
-
-try:
- from string import Template
-except:
- from compat import Template, set
-
-class Invalid(Exception):
- pass
-
-debug=0
-
-from mod_tmpl import resMakefile, makecommon, configure, paco_configure
-from mod_tmpl import mainMakefile, autogen, application
-from mod_tmpl import check_sphinx
-from cata_tmpl import catalog, interface, idl, idlMakefile, parallel_interface
-from cata_tmpl import xml, xml_interface, xml_service
-from cata_tmpl import idlMakefilePaCO_BUILT_SOURCES, idlMakefilePaCO_nodist_salomeinclude_HEADERS
-from cata_tmpl import idlMakefilePACO_salomepython_DATA, idlMakefilePACO_salomeidl_DATA
-from cata_tmpl import idlMakefilePACO_INCLUDES
-from cata_tmpl import cataOutStream, cataInStream, cataOutparam, cataInparam
-from cata_tmpl import cataOutParallelStream, cataInParallelStream
-from cata_tmpl import cataService, cataCompo
-from aster_tmpl import check_aster
-from salomemodules import salome_modules
-from yacstypes import corbaTypes, corbaOutTypes, moduleTypes, idlTypes, corba_in_type, corba_out_type
-from yacstypes import ValidTypes, PyValidTypes, calciumTypes, DatastreamParallelTypes
-from yacstypes import ValidImpl, ValidImplTypes, ValidStreamTypes, ValidParallelStreamTypes, ValidDependencies
-from gui_tmpl import pyguimakefile, pysalomeapp, cppguimakefile, cppsalomeapp
-from doc_tmpl import docmakefile, docconf, docsalomeapp
-
-def makedirs(namedir):
- """Create a new directory named namedir. If a directory already exists copy it to namedir.bak"""
- if os.path.exists(namedir):
- dirbak = namedir+".bak"
- if os.path.exists(dirbak):
- shutil.rmtree(dirbak)
- os.rename(namedir, dirbak)
- os.listdir(dirbak) #needed to update filesystem on special machines (cluster with NFS, for example)
- os.makedirs(namedir)
-
-class Module(object):
- """
- A :class:`Module` instance represents a SALOME module that contains components given as a list of
- component instances (:class:`CPPComponent` or :class:`PYComponent` or :class:`F77Component` or :class:`ASTERComponent`)
- with the parameter *components*.
-
- :param name: gives the name of the module. The SALOME source module
- will be located in the <name_SRC> directory.
- :type name: str
- :param components: gives the list of components of the module.
- :param prefix: is the path of the installation directory.
- :param layout: If given and has the value "monodir", all components
- will be generated in a single directory. The default is to generate each component in its
- own directory.
- :param doc: can be used to add an online documentation to the module. It must be a list of file names (sources, images, ...) that will be
- used to build a sphinx documentation (see http://sphinx.pocoo.org, for more information). If not given, the Makefile.am
- and the conf.py (sphinx configuration) files are generated. In this case, the file name extension of source files must be .rst.
- See small examples in Examples/pygui1 and Examples/cppgui1.
- :param gui: can be used to add a GUI to the module. It must be a list of file names (sources, images, qt designer files, ...).
- If not given, the Makefile.am and SalomeApp.xml are generated. All image files are put in the resources directory of the module.
- The GUI can be implemented in C++ (file name extension '.cxx') or in Python (file name extension '.py').
- See small examples in Examples/pygui1 and Examples/cppgui1.
-
- For example, the following call defines a module named "mymodule" with 2 components c1 and c2 (they must have been
- defined before) that will be installed in the "install" directory::
-
- >>> m = module_generator.Module('mymodule', components=[c1,c2],
- prefix="./install")
-
- """
- def __init__(self, name, components=None, prefix="",layout="multidir", doc=None, gui=None):
- self.name = name
- self.components = components or []
- self.prefix = prefix or "%s_INSTALL" % name
- self.layout=layout
- self.doc = doc
- self.gui = gui
- try:
- self.validate()
- except Invalid,e:
- if debug:
- traceback.print_exc()
- print "Error in module %s: %s" % (name,e)
- raise SystemExit
-
- def validate(self):
- # Test Module name, canot have a "-" in the name
- if self.name.find("-") != -1:
- raise Invalid("Module name %s is not valid, remove character - in the module name" % self.name)
- lcompo = set()
- for compo in self.components:
- if compo.name in lcompo:
- raise Invalid("%s is already defined as a component of the module" % compo.name)
- lcompo.add(compo.name)
- compo.validate()
- if self.gui and self.layout != "multidir":
- raise Invalid("A module with GUI can not be generated if layout is not multidir")
-
-class Component(object):
- def __init__(self, name, services=None, impl="PY", libs="", rlibs="",
- includes="", kind="lib", sources=None,
- inheritedclass="",compodefs="",
- idls=None,interfacedefs="",inheritedinterface="",addedmethods=""):
- self.name = name
- self.impl = impl
- self.kind = kind
- self.services = services or []
- self.libs = libs
- self.rlibs = rlibs
- self.includes = includes
- self.sources = sources or []
- self.inheritedclass=inheritedclass
- self.compodefs=compodefs
- self.idls=idls
- self.interfacedefs=interfacedefs
- self.inheritedinterface=inheritedinterface
- self.addedmethods=addedmethods
-
- def validate(self):
- if self.impl not in ValidImpl:
- raise Invalid("%s is not a valid implementation. It should be one of %s" % (self.impl, ValidImpl))
-
- lnames = set()
- for serv in self.services:
- serv.impl = self.impl
- if serv.name in lnames:
- raise Invalid("%s is already defined as a service of the module" % serv.name)
- lnames.add(serv.name)
- serv.validate()
-
- for src in self.sources:
- if not os.path.exists(src):
- raise Invalid("Source file %s does not exist" % src)
-
- def getImpl(self):
- return "SO", ""
-
- def getMakefileItems(self,gen):
- return {}
-
- def setPrerequisites(self, prerequisites_file):
- self.prerequisites = prerequisites_file
-
-class Service(object):
- """
- A :class:`Service` instance represents a component service with dataflow and datastream ports.
-
- :param name: gives the name of the service.
- :type name: str
- :param inport: gives the list of input dataflow ports.
- :param outport: gives the list of output dataflow ports. An input or output dataflow port is defined
- by a 2-tuple (port name, data type name). The list of supported basic data types is: "double", "long", "string",
- "dblevec", "stringvec", "intvec", "file" and "pyobj" only for Python services. Depending on the implementation
- language, it is also possible to use some types from SALOME modules (see :ref:`yacstypes`).
- :param ret: gives the type of the return parameter
- :param instream: gives the list of input datastream ports.
- :param outstream: gives the list of output datastream ports. An input or output datastream port is defined
- by a 3-tuple (port name, data type name, mode name). The list of possible data types is: "CALCIUM_double", "CALCIUM_integer",
- "CALCIUM_real", "CALCIUM_string", "CALCIUM_complex", "CALCIUM_logical", "CALCIUM_long". The mode can be "I" (iterative mode)
- or "T" (temporal mode).
- :param defs: gives the source code to insert in the definition section of the component. It can be C++ includes
- or Python imports
- :type defs: str
- :param body: gives the source code to insert in the service call. It can be any C++
- or Python code that fits well in the body of the service method.
- :type body: str
-
- For example, the following call defines a minimal Python service with one input dataflow port (name "a", type double)
- and one input datastream port::
-
- >>> s1 = module_generator.Service('myservice', inport=[("a","double"),],
- instream=[("aa","CALCIUM_double","I")],
- body="print a")
-
-
- """
- def __init__(self, name, inport=None, outport=None, ret="void", instream=None, outstream=None,
- parallel_instream=None, parallel_outstream=None, defs="", body="", impl_type="sequential"):
- self.name = name
- self.inport = inport or []
- self.outport = outport or []
- self.ret = ret
- self.instream = instream or []
- self.outstream = outstream or []
- self.parallel_instream = parallel_instream or []
- self.parallel_outstream = parallel_outstream or []
- self.defs = defs
- self.body = body
- self.impl = ""
- self.impl_type = impl_type
-
- def validate(self):
- lports = set()
- for port in self.inport:
- name, typ = self.validatePort(port)
- if name in lports:
- raise Invalid("%s is already defined as a service parameter" % name)
- lports.add(name)
-
- for port in self.outport:
- name, typ = self.validatePort(port)
- if name in lports:
- raise Invalid("%s is already defined as a service parameter" % name)
- lports.add(name)
-
- lports = set()
- for port in self.instream:
- name, typ, dep = self.validateStream(port)
- if name in lports:
- raise Invalid("%s is already defined as a stream port" % name)
- lports.add(name)
-
- for port in self.outstream:
- name, typ, dep = self.validateStream(port)
- if name in lports:
- raise Invalid("%s is already defined as a stream port" % name)
- lports.add(name)
-
- for port in self.parallel_instream:
- name, typ = self.validateParallelStream(port)
- if name in lports:
- raise Invalid("%s is already defined as a stream port" % name)
- lports.add(name)
-
- for port in self.parallel_outstream:
- name, typ = self.validateParallelStream(port)
- if name in lports:
- raise Invalid("%s is already defined as a stream port" % name)
- lports.add(name)
-
- self.validateImplType()
-
- def validatePort(self, port):
- try:
- name, typ = port
- except:
- raise Invalid("%s is not a valid definition of an data port (name,type)" % (port,))
-
- if self.impl in ("PY", "ASTER"):
- validtypes = PyValidTypes
- else:
- validtypes = ValidTypes
-
- if typ not in validtypes:
- raise Invalid("%s is not a valid type. It should be one of %s" % (typ, validtypes))
- return name, typ
-
- def validateImplType(self):
- if self.impl_type not in ValidImplTypes:
- raise Invalid("%s is not a valid impl type. It should be one of %s" % (self.impl_type, ValidImplTypes))
-
- def validateStream(self, port):
- try:
- name, typ, dep = port
- except:
- raise Invalid("%s is not a valid definition of a stream port (name,type,dependency)" % (port,))
- if typ not in ValidStreamTypes:
- raise Invalid("%s is not a valid type. It should be one of %s" % (typ, ValidStreamTypes))
- if dep not in ValidDependencies:
- raise Invalid("%s is not a valid dependency. It should be one of %s" % (dep, ValidDependencies))
- return name, typ, dep
-
- def validateParallelStream(self, port):
- try:
- name, typ = port
- except:
- raise Invalid("%s is not a valid definition of a parallel stream port (name,type)" % (port,))
- if typ not in ValidParallelStreamTypes:
- raise Invalid("%s is not a valid type. It should be one of %s" % (typ, ValidParallelStreamTypes))
- return name, typ
-
-class Generator(object):
- """
- A :class:`Generator` instance take a :class:`Module` instance as its first parameter and can be used to generate the
- SALOME source module, builds it, installs it and includes it in a SALOME application.
-
- :param module: gives the :class:`Module` instance that will be used for the generation.
- :param context: If given , its content is used to specify the prerequisites
- environment file (key *"prerequisites"*) and the SALOME KERNEL installation directory (key *"kernel"*).
- :type context: dict
-
- For example, the following call creates a generator for the module m::
-
- >>> g = module_generator.Generator(m,context)
- """
- def __init__(self, module, context=None):
- self.module = module
- self.context = context or {}
- self.kernel = self.context["kernel"]
- self.gui = self.context.get("gui")
- self.makeflags = self.context.get("makeflags")
- self.aster = ""
- if self.module.gui and not self.gui:
- raise Invalid("To generate a module with GUI, you need to set the 'gui' parameter in the context dictionnary")
- for component in self.module.components:
- component.setPrerequisites(self.context.get("prerequisites"))
-
- def generate(self):
- """Generate a SALOME source module"""
- module = self.module
- namedir = module.name+"_SRC"
- force = self.context.get("force")
- update = self.context.get("update")
- paco = self.context.get("paco")
- if os.path.exists(namedir):
- if force:
- shutil.rmtree(namedir)
- elif not update:
- raise Invalid("The directory %s already exists" % namedir)
- if update:
- makedirs(namedir)
- else:
- os.makedirs(namedir)
-
- srcs = {}
- makefile = "SUBDIRS="
- makefileItems={"header":"""
-include $(top_srcdir)/adm_local/make_common_starter.am
-AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions
-""",
- "salomepython_PYTHON":[],
- "dist_salomescript_SCRIPTS":[],
- "salomeres_DATA":[],
- "lib_LTLIBRARIES":[],
- "salomeinclude_HEADERS":[],
- "body":"",
- }
-
- #get the list of SALOME modules used and put it in used_modules attribute
- def get_dependent_modules(mod,modules):
- modules[mod]=1
- if not salome_modules[mod].has_key("depends"):return
- for m in salome_modules[mod]["depends"]:
- if modules.has_key(m):continue
- get_dependent_modules(m,modules)
-
- modules = {}
- for compo in module.components:
- for serv in compo.services:
- for name, typ in serv.inport + serv.outport + [ ("return",serv.ret) ] :
- mod = moduleTypes[typ]
- if mod:
- get_dependent_modules(mod,modules)
-
- self.used_modules = modules.keys()
-
- for compo in module.components:
- #for components files
- fdict=compo.makeCompo(self)
- if self.module.layout=="multidir":
- srcs[compo.name] = fdict
- #for src/Makefile.am
- makefile = makefile + " " + compo.name
- else:
- srcs.update(fdict)
- #for src/Makefile.am
- mdict=compo.getMakefileItems(self)
- makefileItems["salomepython_PYTHON"]=makefileItems["salomepython_PYTHON"]+mdict.get("salomepython_PYTHON",[])
- makefileItems["dist_salomescript_SCRIPTS"]=makefileItems["dist_salomescript_SCRIPTS"]+mdict.get("dist_salomescript_SCRIPTS",[])
- makefileItems["salomeres_DATA"]=makefileItems["salomeres_DATA"]+mdict.get("salomeres_DATA",[])
- makefileItems["lib_LTLIBRARIES"]=makefileItems["lib_LTLIBRARIES"]+mdict.get("lib_LTLIBRARIES",[])
- makefileItems["salomeinclude_HEADERS"]=makefileItems["salomeinclude_HEADERS"]+mdict.get("salomeinclude_HEADERS",[])
- makefileItems["body"]=makefileItems["body"]+mdict.get("body","")+'\n'
-
- if module.gui:
- GUIname=module.name+"GUI"
- fdict=self.makeGui(namedir)
- srcs[GUIname] = fdict
- #for src/Makefile.am
- makefile = makefile + " " + GUIname
-
- if self.module.layout == "multidir":
- srcs["Makefile.am"] = makefile+'\n'
- else:
- srcs["Makefile.am"] = self.makeMakefile(makefileItems)
-
- docsubdir=""
- if module.doc:
- docsubdir="doc"
-
- #for catalog files
- catalogfile = "%sCatalog.xml" % module.name
-
- need_boost=0
- if module.gui:
- need_boost=1
- for compo in module.components:
- if hasattr(compo,"calciumextendedinterface") and compo.calciumextendedinterface:
- need_boost=1
- break
-
- #add makefile definitions to make_common_starter.am
- other_includes=""
- common_starter = makecommon.substitute(other_includes=other_includes)
- for mod in self.used_modules:
- common_starter = common_starter + salome_modules[mod]["makefiledefs"] + '\n'
-
- adm_local={"make_common_starter.am": common_starter, "check_aster.m4":check_aster}
- if module.doc:
- adm_local["check_sphinx.m4"]=check_sphinx
-
- self.makeFiles({"autogen.sh":autogen,
- "Makefile.am":mainMakefile.substitute(docsubdir=docsubdir),
- "README":"", "NEWS":"", "AUTHORS":"", "ChangeLog":"",
- "src":srcs,
- "resources":{"Makefile.am":resMakefile.substitute(module=module.name), catalogfile:self.makeCatalog()},
- "adm_local":adm_local,
- }, namedir)
-
- #add checks for modules in configure.ac
- configure_modules=""
- for mod in self.used_modules:
- configure_modules = configure_modules + salome_modules[mod]["configdefs"] + '\n'
-
- #for configure.ac
- configure_makefiles = []
- if self.module.layout=="multidir":
- for compo in module.components:
- configure_makefiles.append(" src/"+compo.name+"/Makefile")
-
- if module.gui:
- configure_makefiles.append(" src/%sGUI/Makefile" % module.name)
- if module.doc:
- configure_makefiles.append(" doc/Makefile")
-
- other_check=""
- other_summary=""
- other_require=""
-
- if need_boost:
- other_check=other_check+"""CHECK_BOOST
-"""
- other_summary=other_summary+"""echo " Boost ................. : $boost_ok"
-"""
-
- if module.gui:
- other_check=other_check + """CHECK_SALOME_GUI
-CHECK_QT
-"""
- other_summary=other_summary+'''echo " SALOME GUI ............. : $SalomeGUI_ok"
-echo " Qt ..................... : $qt_ok"
-'''
- other_require=other_require + """
- if test "x$SalomeGUI_ok" = "xno"; then
- AC_MSG_ERROR([SALOME GUI is required],1)
- fi
- if test "x$qt_ok" = "xno"; then
- AC_MSG_ERROR([Qt library is required],1)
- fi
-"""
- if module.doc:
- other_check=other_check+"CHECK_SPHINX\n"
- other_summary=other_summary+'''echo " Sphinx ................. : $sphinx_ok"\n'''
- other_require=other_require + """
- if test "x$sphinx_ok" = "xno"; then
- AC_MSG_ERROR([Sphinx documentation generator is required],1)
- fi
-"""
-
- files={}
- #for idl files
- idlfile = "%s.idl" % module.name
- paco_config=""
- PACO_BUILT_SOURCES=""
- PACO_SALOMEINCLUDE_HEADERS=""
- PACO_INCLUDES=""
- PACO_salomepython_DATA=""
- PACO_salomeidl_DATA=""
-
- if paco:
- PACO_BUILT_SOURCES = idlMakefilePaCO_BUILT_SOURCES.substitute(module=module.name)
- PACO_SALOMEINCLUDE_HEADERS = idlMakefilePaCO_nodist_salomeinclude_HEADERS.substitute(module=module.name)
- PACO_salomepython_DATA = idlMakefilePACO_salomepython_DATA.substitute(module=module.name)
- PACO_salomeidl_DATA = idlMakefilePACO_salomeidl_DATA.substitute(module=module.name)
- PACO_INCLUDES = idlMakefilePACO_INCLUDES
- paco_config=paco_configure
-
- files["configure.ac"]=configure.substitute(module=module.name.lower(),
- makefiles='\n'.join(configure_makefiles),
- paco_configure=paco_config,
- modules=configure_modules,
- other_check=other_check,
- other_summary=other_summary,
- other_require=other_require,
- )
-
- #if components have other idls
- other_idls=""
- other_sks=""
- for compo in module.components:
- if compo.idls:
- for idl in compo.idls:
- for fidl in glob.glob(idl):
- other_idls=other_idls+os.path.basename(fidl) +" "
- other_sks=other_sks+os.path.splitext(os.path.basename(fidl))[0]+"SK.cc "
-
- idlfiles={"Makefile.am": idlMakefile.substitute(module=module.name,
- PACO_BUILT_SOURCES=PACO_BUILT_SOURCES,
- PACO_SALOMEINCLUDE_HEADERS=PACO_SALOMEINCLUDE_HEADERS,
- PACO_INCLUDES=PACO_INCLUDES,
- PACO_salomepython_DATA=PACO_salomepython_DATA,
- PACO_salomeidl_DATA=PACO_salomeidl_DATA,
- other_idls=other_idls,other_sks=other_sks,
- ),
- idlfile : self.makeidl(),
- }
- if paco:
- idlfiles["%s.xml" % module.name]=self.makexml()
-
- files["idl"]=idlfiles
-
- self.makeFiles(files,namedir)
-
- os.chmod(os.path.join(namedir, "autogen.sh"), 0777)
- #copy source files if any in created tree
- for compo in module.components:
- for src in compo.sources:
- if self.module.layout=="multidir":
- shutil.copyfile(src, os.path.join(namedir, "src", compo.name, os.path.basename(src)))
- else:
- shutil.copyfile(src, os.path.join(namedir, "src", os.path.basename(src)))
-
- if compo.idls:
- #copy provided idl files in idl directory
- for idl in compo.idls:
- for fidl in glob.glob(idl):
- shutil.copyfile(fidl, os.path.join(namedir, "idl", os.path.basename(fidl)))
-
- checks= ("check_Kernel.m4", "check_omniorb.m4", "ac_linker_options.m4", "ac_cxx_option.m4",
- "python.m4", "enable_pthreads.m4", "check_f77.m4", "acx_pthread.m4", "check_paco++.m4",
- "check_mpi.m4", "check_lam.m4", "check_openmpi.m4", "check_mpich.m4")
- if need_boost:
- checks=checks+("check_boost.m4",)
- for m4file in checks:
- shutil.copyfile(os.path.join(self.kernel, "salome_adm", "unix", "config_files", m4file),
- os.path.join(namedir, "adm_local", m4file))
-
- if self.module.gui:
- for m4file in ("check_GUI.m4", "check_qt.m4", "check_opengl.m4"):
- shutil.copyfile(os.path.join(self.gui, "adm_local", "unix", "config_files", m4file),
- os.path.join(namedir, "adm_local", m4file))
-
- self.makeDoc(namedir)
- return
-
- def makeDoc(self,namedir):
- if not self.module.doc:
- return
- rep=os.path.join(namedir,"doc")
- os.makedirs(rep)
- for docs in self.module.doc:
- for doc in glob.glob(docs):
- name = os.path.basename(doc)
- shutil.copyfile(doc, os.path.join(rep, name))
-
- d={}
-
- others=""
- if not self.module.gui:
- #without gui but with doc: create a small SalomeApp.xml in doc directory
- if not os.path.exists(os.path.join(namedir, "doc", "SalomeApp.xml")):
- #create a minimal SalomeApp.xml
- salomeapp=docsalomeapp.substitute(module=self.module.name,lmodule=self.module.name.lower())
- d["SalomeApp.xml"]=salomeapp
- others="SalomeApp.xml"
-
- if not os.path.exists(os.path.join(namedir, "doc", "Makefile.am")):
- #create a minimal makefile.am
- d["Makefile.am"]=docmakefile.substitute(others=others)
-
- if not os.path.exists(os.path.join(namedir, "doc", "conf.py")):
- #create a minimal conf.py
- d["conf.py"]=docconf.substitute(module=self.module.name)
-
- self.makeFiles(d,os.path.join(namedir,"doc"))
-
- def makeGui(self,namedir):
- if not self.module.gui:
- return
- ispython=False
- iscpp=False
- #Force creation of intermediate directories
- os.makedirs(os.path.join(namedir, "src", self.module.name+"GUI"))
-
- for srcs in self.module.gui:
- for src in glob.glob(srcs):
- shutil.copyfile(src, os.path.join(namedir, "src", self.module.name+"GUI", os.path.basename(src)))
- if src[-3:]==".py":ispython=True
- if src[-4:]==".cxx":iscpp=True
- if ispython and iscpp:
- raise Invalid("Module GUI must be pure python or pure C++ but not mixed")
- if ispython:
- return self.makePyGUI(namedir)
- if iscpp:
- return self.makeCPPGUI(namedir)
- raise Invalid("Module GUI must be in python or C++ but it is none of them")
-
- def makePyGUI(self,namedir):
- d={}
- if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "Makefile.am")):
- #create a minimal makefile.am
- sources=[]
- other=[]
- for srcs in self.module.gui:
- for src in glob.glob(srcs):
- if src[-3:]==".py":
- sources.append(os.path.basename(src))
- else:
- other.append(os.path.basename(src))
- makefile=pyguimakefile.substitute(sources=" ".join(sources),other_sources=" ".join(other))
- d["Makefile.am"]=makefile
-
- if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "SalomeApp.xml")):
- #create a minimal SalomeApp.xml
- salomeapp=pysalomeapp.substitute(module=self.module.name,lmodule=self.module.name.lower())
- d["SalomeApp.xml"]=salomeapp
-
- return d
-
- def makeCPPGUI(self,namedir):
- d={}
- if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "Makefile.am")):
- #create a minimal makefile.am
- sources=[]
- other=[]
- ui_files=[]
- for srcs in self.module.gui:
- for src in glob.glob(srcs):
- if src[-4:]==".cxx":
- sources.append(os.path.basename(src))
- elif src[-2:]==".h":
- sources.append(os.path.basename(src)[:-2]+"_moc.cxx")
- elif src[-3:]==".ui":
- ui_files.append("ui_"+os.path.basename(src)[:-3]+".h")
- elif src[-3:]==".ts":
- other.append(os.path.basename(src)[:-3]+".qm")
- else:
- other.append(os.path.basename(src))
-
- makefile=cppguimakefile.substitute(sources=" ".join(sources),other_sources=" ".join(other),
- module=self.module.name, uisources= " ".join(ui_files))
- d["Makefile.am"]=makefile
-
- if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "SalomeApp.xml")):
- #create a minimal SalomeApp.xml
- salomeapp=cppsalomeapp.substitute(module=self.module.name,lmodule=self.module.name.lower())
- d["SalomeApp.xml"]=salomeapp
-
- return d
-
- def makeMakefile(self,makefileItems):
- makefile=""
- if makefileItems.has_key("header"):
- makefile=makefile + makefileItems["header"]+'\n'
- if makefileItems.has_key("lib_LTLIBRARIES"):
- makefile=makefile+"lib_LTLIBRARIES= "+" ".join(makefileItems["lib_LTLIBRARIES"])+'\n'
- if makefileItems.has_key("salomepython_PYTHON"):
- makefile=makefile+"salomepython_PYTHON= "+" ".join(makefileItems["salomepython_PYTHON"])+'\n'
- if makefileItems.has_key("dist_salomescript_SCRIPTS"):
- makefile=makefile+"dist_salomescript_SCRIPTS= "+" ".join(makefileItems["dist_salomescript_SCRIPTS"])+'\n'
- if makefileItems.has_key("salomeres_DATA"):
- makefile=makefile+"salomeres_DATA= "+" ".join(makefileItems["salomeres_DATA"])+'\n'
- if makefileItems.has_key("salomeinclude_HEADERS"):
- makefile=makefile+"salomeinclude_HEADERS= "+" ".join(makefileItems["salomeinclude_HEADERS"])+'\n'
- if makefileItems.has_key("body"):
- makefile=makefile+makefileItems["body"]+'\n'
- return makefile
-
- def makeArgs(self, service):
- """generate source service for arguments"""
- params = []
- for name, typ in service.inport:
- if typ=="file":continue #files are not passed through service interface
- params.append("%s %s" % (corba_in_type(typ, self.module.name), name))
- for name, typ in service.outport:
- if typ=="file":continue #files are not passed through service interface
- params.append("%s %s" % (corba_out_type(typ, self.module.name), name))
- return ",".join(params)
-
- def makeCatalog(self):
- """generate SALOME components catalog source"""
- components = []
- for compo in self.module.components:
- services = []
- for serv in compo.services:
- params = []
- for name, typ in serv.inport:
- params.append(cataInparam.substitute(name=name, type=typ))
- inparams = "\n".join(params)
- params = []
- for name, typ in serv.outport:
- params.append(cataOutparam.substitute(name=name, type=typ))
- if serv.ret != "void" :
- params.append(cataOutparam.substitute(name="return", type=serv.ret))
- outparams = "\n".join(params)
- streams = []
- for name, typ, dep in serv.instream:
- streams.append(cataInStream.substitute(name=name, type=calciumTypes[typ], dep=dep))
- for name, typ, dep in serv.outstream:
- streams.append(cataOutStream.substitute(name=name, type=calciumTypes[typ], dep=dep))
- for name, typ in serv.parallel_instream:
- streams.append(cataInParallelStream.substitute(name=name, type=DatastreamParallelTypes[typ]))
- for name, typ in serv.parallel_outstream:
- streams.append(cataOutParallelStream.substitute(name=name, type=DatastreamParallelTypes[typ]))
- datastreams = "\n".join(streams)
- services.append(cataService.substitute(service=serv.name, author="EDF-RD",
- inparams=inparams, outparams=outparams, datastreams=datastreams))
- impltype, implname = compo.getImpl()
- components.append(cataCompo.substitute(component=compo.name, author="EDF-RD", impltype=impltype, implname=implname,
- services='\n'.join(services)))
- return catalog.substitute(components='\n'.join(components))
-
- def makeidl(self):
- """generate module IDL file source (CORBA interface)"""
- from pacocompo import PACOComponent
- interfaces = []
- idldefs=""
- for compo in self.module.components:
- if isinstance(compo, PACOComponent):
- services = []
- for serv in compo.services:
- params = []
- for name, typ in serv.inport:
- if typ == "file":continue #files are not passed through IDL interface
- params.append("in %s %s" % (idlTypes[typ], name))
- for name, typ in serv.outport:
- if typ == "file":continue #files are not passed through IDL interface
- params.append("out %s %s" % (idlTypes[typ], name))
- service = " void %s(" % serv.name
- service = service+",".join(params)+");"
- services.append(service)
-
- interfaces.append(parallel_interface.substitute(component=compo.name, services="\n".join(services)))
-
- else:
- services = []
- for serv in compo.services:
- params = []
- for name, typ in serv.inport:
- if typ == "file":continue #files are not passed through IDL interface
- if compo.impl in ("PY", "ASTER") and typ == "pyobj":
- typ = "Engines::fileBlock"
- else:
- typ=idlTypes[typ]
- params.append("in %s %s" % (typ, name))
- for name, typ in serv.outport:
- if typ == "file":continue #files are not passed through IDL interface
- if compo.impl in ("PY", "ASTER") and typ == "pyobj":
- typ = "Engines::fileBlock"
- else:
- typ=idlTypes[typ]
- params.append("out %s %s" % (typ, name))
- service = " %s %s(" % (idlTypes[serv.ret],serv.name)
- service = service+",".join(params)+") raises (SALOME::SALOME_Exception);"
- services.append(service)
-
- from hxxcompo import HXX2SALOMEComponent
- from hxxparacompo import HXX2SALOMEParaComponent
- if isinstance(compo,HXX2SALOMEComponent) or isinstance(compo,HXX2SALOMEParaComponent):
- from hxx_tmpl import interfaceidlhxx
- Inherited=""
- if isinstance(compo,HXX2SALOMEParaComponent):
- Inherited="SALOME_MED::ParaMEDMEMComponent"
- idldefs="""#include "ParaMEDMEMComponent.idl"\n"""
- else:
- if compo.use_medmem==True:
- Inherited="Engines::EngineComponent,SALOME::MultiCommClass,SALOME_MED::MED_Gen_Driver"
- else:
- Inherited="Engines::EngineComponent"
- interfaces.append(interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services)))
- else:
- inheritedinterface=""
- if compo.inheritedinterface:
- inheritedinterface=compo.inheritedinterface+","
- interfaces.append(interface.substitute(component=compo.name, services="\n".join(services),inheritedinterface=inheritedinterface))
-
- #build idl includes for SALOME modules
- for mod in self.used_modules:
- idldefs = idldefs + salome_modules[mod]["idldefs"]
-
- for compo in self.module.components:
- if compo.interfacedefs:
- idldefs = idldefs + compo.interfacedefs
-
- return idl.substitute(module=self.module.name, interfaces='\n'.join(interfaces),idldefs=idldefs)
-
- # For PaCO++
- def makexml(self):
- from pacocompo import PACOComponent
- interfaces = []
- for compo in self.module.components:
- if isinstance(compo, PACOComponent):
- services = []
- for serv in compo.services:
- if serv.impl_type == "parallel":
- service = xml_service.substitute(service_name=serv.name)
- services.append(service)
- interfaces.append(xml_interface.substitute(component=compo.name, xml_services="\n".join(services)))
- return xml.substitute(module=self.module.name, interfaces='\n'.join(interfaces))
-
- def makeFiles(self, dic, basedir):
- """create files and directories defined in dictionary dic in basedir directory
- dic key = file name to create
- dic value = file content or dictionary defining the content of a sub directory
- """
- for name, content in dic.items():
- filename = os.path.join(basedir, name)
- if isinstance(content, str):
- fil = open(filename, 'w')
- fil.write(content)
- fil.close()
- else:
- if not os.path.exists(filename):
- os.makedirs(filename)
- self.makeFiles(content, filename)
-
- def bootstrap(self):
- """Execute the first build step (bootstrap autotools with autogen.sh script) : execution of libtool, autoconf, automake"""
- ier = os.system("cd %s_SRC;sh autogen.sh" % self.module.name)
- if ier != 0:
- raise Invalid("bootstrap has ended in error")
-
- def configure(self):
- """Execute the second build step (configure) with installation prefix as given by the prefix attribute of module"""
- prefix = self.module.prefix
- paco = self.context.get("paco")
- mpi = self.context.get("mpi")
- args = (self.module.name, self.kernel, self.aster)
- cmd = "cd %s_SRC;./configure --with-kernel=%s --with-aster=%s" % args
- if self.gui:
- cmd = cmd + " --with-gui=%s" % self.gui
- if prefix:
- prefix = os.path.abspath(prefix)
- cmd = cmd + " --prefix=%s" % prefix
- if paco:
- cmd += " --with-paco=%s" % paco
- if mpi:
- cmd += " --with-mpi=%s" % mpi
-
- ier = os.system(cmd)
- if ier != 0:
- raise Invalid("configure has ended in error")
-
- def make(self):
- """Execute the third build step (compile and link) : make"""
- make_command = "make "
- if self.makeflags:
- make_command += self.makeflags
- ier = os.system("cd %s_SRC;%s" % (self.module.name, make_command))
- if ier != 0:
- raise Invalid("make has ended in error")
-
- def install(self):
- """Execute the installation step : make install """
- makedirs(self.module.prefix)
- ier = os.system("cd %s_SRC;make install" % self.module.name)
- if ier != 0:
- raise Invalid("install has ended in error")
-
- def make_appli(self, appliname, restrict=None, altmodules=None, resources=""):
- """
- Create a SALOME application containing the module and preexisting SALOME modules.
-
- :param appliname: is a string that gives the name of the application (directory path where the application
- will be installed).
- :type appliname: str
- :param restrict: If given (a list of module names), only those SALOME modules will be included in the
- application. The default is to include all modules that are located in the same directory as the KERNEL module and have
- the same suffix (for example, if KERNEL directory is KERNEL_V5 and GEOM directory is GEOM_V5, GEOM module is automatically
- included, except if restrict is used).
- :param altmodules: can be used to add SALOME modules that cannot be managed with the precedent rule. This parameter
- is a dict with a module name as the key and the installation path as the value.
- :param resources: can be used to define an alternative resources catalog (path of the file).
-
- For example, the following calls create a SALOME application with external modules and resources catalog in "appli" directory::
-
- >>> g=Generator(m,context)
- >>> g.generate()
- >>> g.bootstrap()
- >>> g.configure()
- >>> g.make()
- >>> g.install()
- >>> g.make_appli("appli", restrict=["KERNEL"], altmodules={"GUI":GUI_ROOT_DIR, "YACS":YACS_ROOT_DIR},
- resources="myresources.xml")
-
- """
- makedirs(appliname)
-
- rootdir, kerdir = os.path.split(self.kernel)
-
- #collect modules besides KERNEL module with the same suffix if any
- modules_dict = {}
- if kerdir[:6] == "KERNEL":
- suffix = kerdir[6:]
- for mod in os.listdir(rootdir):
- if mod[-len(suffix):] == suffix:
- module = mod[:-len(suffix)]
- path = os.path.join(rootdir, mod)
- #try to find catalog files
- lcata = glob.glob(os.path.join(path, "share", "salome", "resources", "*", "*Catalog.xml"))
- if not lcata:
- #catalogs have not been found : try the upper level
- lcata = glob.glob(os.path.join(path, "share", "salome", "resources", "*Catalog.xml"))
- if lcata:
- #catalogs have been found : add the corresponding entries in the application
- for cata in lcata:
- catadir, catafile = os.path.split(cata)
- name = catafile[:-11]
- modules_dict[name] = ' <module name="%s" path="%s"/>' % (name, path)
- else:
- modules_dict[module] = ' <module name="%s" path="%s"/>' % (module, path)
-
- modules_dict["KERNEL"] = ' <module name="KERNEL" path="%s"/>' % self.kernel
-
- #keep only the modules which names are in restrict if given
- modules = []
- if restrict:
- for mod in restrict:
- if modules_dict.has_key(mod):
- modules.append(modules_dict[mod])
- else:
- modules = modules_dict.values()
-
- #add the alternate modules if given
- if altmodules:
- for module, path in altmodules.items():
- modules.append(' <module name="%s" path="%s"/>' % (module, path))
-
- #add the generated module
- modules.append(' <module name="%s" path="%s"/>' % (self.module.name, os.path.abspath(self.module.prefix)))
-
-
- #try to find a prerequisites file
- prerequisites = self.context.get("prerequisites")
- if not prerequisites:
- #try to find one in rootdir
- prerequisites = os.path.join(rootdir, "profile%s.sh" % suffix)
- if not os.path.exists(prerequisites):
- raise Invalid("Can not create an application : prerequisites file not defined or does not exist")
-
- #add resources catalog if it exists
- resources_spec=""
- if os.path.isfile(resources):
- resources_spec='<resources path="%s" />' % os.path.abspath(resources)
-
- #create config_appli.xml file
- appli = application.substitute(prerequisites=prerequisites,
- modules="\n".join(modules),
- resources=resources_spec)
- fil = open(os.path.join(appliname, "config_appli.xml"), 'w')
- fil.write(appli)
- fil.close()
-
- #execute appli_gen.py script
- appligen = os.path.join(self.kernel, "bin", "salome", "appli_gen.py")
- ier = os.system("cd %s;%s" % (appliname, appligen))
- if ier != 0:
- raise Invalid("make_appli has ended in error")
-
- #add CatalogResources.xml if not created by appli_gen.py
- if not os.path.exists(os.path.join(appliname, "CatalogResources.xml")):
- #CatalogResources.xml does not exist create a minimal one
- fil = open(os.path.join(appliname, 'CatalogResources.xml'), 'w')
- command = """<!DOCTYPE ResourcesCatalog>
-<resources>
- <machine hostname="%s" protocol="ssh" mode="interactive" />
-</resources>
-"""
- host = socket.gethostname().split('.')[0]
- fil.write(command % host)
- fil.close()
-
+# Copyright (C) 2009-2012 EDF R&D\r
+#\r
+# This library is free software; you can redistribute it and/or\r
+# modify it under the terms of the GNU Lesser General Public\r
+# License as published by the Free Software Foundation; either\r
+# version 2.1 of the License.\r
+#\r
+# This library is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+# Lesser General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU Lesser General Public\r
+# License along with this library; if not, write to the Free Software\r
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+#\r
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+#\r
+\r
+import os, shutil, glob, socket\r
+import traceback\r
+import warnings\r
+\r
+try:\r
+ from string import Template\r
+except:\r
+ from compat import Template, set\r
+\r
+class Invalid(Exception):\r
+ pass\r
+\r
+debug=0\r
+\r
+from mod_tmpl import resMakefile, makecommon, configure, paco_configure\r
+from mod_tmpl import mainMakefile, autogen, application\r
+from mod_tmpl import check_sphinx\r
+from cata_tmpl import catalog, interface, idl, idlMakefile, parallel_interface\r
+from cata_tmpl import xml, xml_interface, xml_service\r
+from cata_tmpl import idlMakefilePaCO_BUILT_SOURCES, idlMakefilePaCO_nodist_salomeinclude_HEADERS\r
+from cata_tmpl import idlMakefilePACO_salomepython_DATA, idlMakefilePACO_salomeidl_DATA\r
+from cata_tmpl import idlMakefilePACO_INCLUDES\r
+from cata_tmpl import cataOutStream, cataInStream, cataOutparam, cataInparam\r
+from cata_tmpl import cataOutParallelStream, cataInParallelStream\r
+from cata_tmpl import cataService, cataCompo\r
+from aster_tmpl import check_aster\r
+from salomemodules import salome_modules\r
+from yacstypes import corbaTypes, corbaOutTypes, moduleTypes, idlTypes, corba_in_type, corba_out_type\r
+from yacstypes import ValidTypes, PyValidTypes, calciumTypes, DatastreamParallelTypes\r
+from yacstypes import ValidImpl, ValidImplTypes, ValidStreamTypes, ValidParallelStreamTypes, ValidDependencies\r
+from gui_tmpl import pyguimakefile, pysalomeapp, cppguimakefile, cppsalomeapp\r
+from doc_tmpl import docmakefile, docconf, docsalomeapp\r
+\r
+def makedirs(namedir):\r
+ """Create a new directory named namedir. If a directory already exists copy it to namedir.bak"""\r
+ if os.path.exists(namedir):\r
+ dirbak = namedir+".bak"\r
+ if os.path.exists(dirbak):\r
+ shutil.rmtree(dirbak)\r
+ os.rename(namedir, dirbak)\r
+ os.listdir(dirbak) #needed to update filesystem on special machines (cluster with NFS, for example)\r
+ os.makedirs(namedir)\r
+\r
+class Module(object):\r
+ """\r
+ A :class:`Module` instance represents a SALOME module that contains components given as a list of\r
+ component instances (:class:`CPPComponent` or :class:`PYComponent` or :class:`F77Component` or :class:`ASTERComponent`)\r
+ with the parameter *components*.\r
+\r
+ :param name: gives the name of the module. The SALOME source module\r
+ will be located in the <name_SRC> directory.\r
+ :type name: str\r
+ :param components: gives the list of components of the module.\r
+ :param prefix: is the path of the installation directory.\r
+ :param layout: If given and has the value "monodir", all components\r
+ will be generated in a single directory. The default is to generate each component in its\r
+ own directory.\r
+ :param doc: can be used to add an online documentation to the module. It must be a list of file names (sources, images, ...) that will be\r
+ used to build a sphinx documentation (see http://sphinx.pocoo.org, for more information). If not given, the Makefile.am\r
+ and the conf.py (sphinx configuration) files are generated. In this case, the file name extension of source files must be .rst.\r
+ See small examples in Examples/pygui1 and Examples/cppgui1.\r
+ :param gui: can be used to add a GUI to the module. It must be a list of file names (sources, images, qt designer files, ...).\r
+ If not given, the Makefile.am and SalomeApp.xml are generated. All image files are put in the resources directory of the module.\r
+ The GUI can be implemented in C++ (file name extension '.cxx') or in Python (file name extension '.py').\r
+ See small examples in Examples/pygui1 and Examples/cppgui1.\r
+\r
+ For example, the following call defines a module named "mymodule" with 2 components c1 and c2 (they must have been\r
+ defined before) that will be installed in the "install" directory::\r
+\r
+ >>> m = module_generator.Module('mymodule', components=[c1,c2],\r
+ prefix="./install")\r
+\r
+ """\r
+ def __init__(self, name, components=None, prefix="",layout="multidir", doc=None, gui=None):\r
+ self.name = name\r
+ self.components = components or []\r
+ self.prefix = prefix or "%s_INSTALL" % name\r
+ self.layout=layout\r
+ self.doc = doc\r
+ self.gui = gui\r
+ try:\r
+ self.validate()\r
+ except Invalid,e:\r
+ if debug:\r
+ traceback.print_exc()\r
+ print "Error in module %s: %s" % (name,e)\r
+ raise SystemExit\r
+\r
+ def validate(self):\r
+ # Test Module name, canot have a "-" in the name\r
+ if self.name.find("-") != -1:\r
+ raise Invalid("Module name %s is not valid, remove character - in the module name" % self.name)\r
+ lcompo = set()\r
+ for compo in self.components:\r
+ if compo.name in lcompo:\r
+ raise Invalid("%s is already defined as a component of the module" % compo.name)\r
+ lcompo.add(compo.name)\r
+ compo.validate()\r
+ if self.gui and self.layout != "multidir":\r
+ raise Invalid("A module with GUI can not be generated if layout is not multidir")\r
+\r
+class Component(object):\r
+ def __init__(self, name, services=None, impl="PY", libs="", rlibs="",\r
+ includes="", kind="lib", sources=None,\r
+ inheritedclass="",compodefs="",\r
+ idls=None,interfacedefs="",inheritedinterface="",addedmethods=""):\r
+ self.name = name\r
+ self.impl = impl\r
+ self.kind = kind\r
+ self.services = services or []\r
+ self.libs = libs\r
+ self.rlibs = rlibs\r
+ self.includes = includes\r
+ self.sources = sources or []\r
+ self.inheritedclass=inheritedclass\r
+ self.compodefs=compodefs\r
+ self.idls=idls\r
+ self.interfacedefs=interfacedefs\r
+ self.inheritedinterface=inheritedinterface\r
+ self.addedmethods=addedmethods\r
+\r
+ def validate(self):\r
+ if self.impl not in ValidImpl:\r
+ raise Invalid("%s is not a valid implementation. It should be one of %s" % (self.impl, ValidImpl))\r
+\r
+ lnames = set()\r
+ for serv in self.services:\r
+ serv.impl = self.impl\r
+ if serv.name in lnames:\r
+ raise Invalid("%s is already defined as a service of the module" % serv.name)\r
+ lnames.add(serv.name)\r
+ serv.validate()\r
+\r
+ for src in self.sources:\r
+ if not os.path.exists(src):\r
+ raise Invalid("Source file %s does not exist" % src)\r
+\r
+ def getImpl(self):\r
+ return "SO", ""\r
+\r
+ def getMakefileItems(self,gen):\r
+ return {}\r
+\r
+ def setPrerequisites(self, prerequisites_file):\r
+ self.prerequisites = prerequisites_file\r
+\r
+class Service(object):\r
+ """\r
+ A :class:`Service` instance represents a component service with dataflow and datastream ports.\r
+\r
+ :param name: gives the name of the service.\r
+ :type name: str\r
+ :param inport: gives the list of input dataflow ports.\r
+ :param outport: gives the list of output dataflow ports. An input or output dataflow port is defined\r
+ by a 2-tuple (port name, data type name). The list of supported basic data types is: "double", "long", "string",\r
+ "dblevec", "stringvec", "intvec", "file" and "pyobj" only for Python services. Depending on the implementation\r
+ language, it is also possible to use some types from SALOME modules (see :ref:`yacstypes`).\r
+ :param ret: gives the type of the return parameter\r
+ :param instream: gives the list of input datastream ports.\r
+ :param outstream: gives the list of output datastream ports. An input or output datastream port is defined\r
+ by a 3-tuple (port name, data type name, mode name). The list of possible data types is: "CALCIUM_double", "CALCIUM_integer",\r
+ "CALCIUM_real", "CALCIUM_string", "CALCIUM_complex", "CALCIUM_logical", "CALCIUM_long". The mode can be "I" (iterative mode)\r
+ or "T" (temporal mode).\r
+ :param defs: gives the source code to insert in the definition section of the component. It can be C++ includes\r
+ or Python imports\r
+ :type defs: str\r
+ :param body: gives the source code to insert in the service call. It can be any C++\r
+ or Python code that fits well in the body of the service method.\r
+ :type body: str\r
+\r
+ For example, the following call defines a minimal Python service with one input dataflow port (name "a", type double)\r
+ and one input datastream port::\r
+\r
+ >>> s1 = module_generator.Service('myservice', inport=[("a","double"),],\r
+ instream=[("aa","CALCIUM_double","I")],\r
+ body="print a")\r
+\r
+\r
+ """\r
+ def __init__(self, name, inport=None, outport=None, ret="void", instream=None, outstream=None,\r
+ parallel_instream=None, parallel_outstream=None, defs="", body="", impl_type="sequential"):\r
+ self.name = name\r
+ self.inport = inport or []\r
+ self.outport = outport or []\r
+ self.ret = ret\r
+ self.instream = instream or []\r
+ self.outstream = outstream or []\r
+ self.parallel_instream = parallel_instream or []\r
+ self.parallel_outstream = parallel_outstream or []\r
+ self.defs = defs\r
+ self.body = body\r
+ self.impl = ""\r
+ self.impl_type = impl_type\r
+\r
+ def validate(self):\r
+ lports = set()\r
+ for port in self.inport:\r
+ name, typ = self.validatePort(port)\r
+ if name in lports:\r
+ raise Invalid("%s is already defined as a service parameter" % name)\r
+ lports.add(name)\r
+\r
+ for port in self.outport:\r
+ name, typ = self.validatePort(port)\r
+ if name in lports:\r
+ raise Invalid("%s is already defined as a service parameter" % name)\r
+ lports.add(name)\r
+\r
+ lports = set()\r
+ for port in self.instream:\r
+ name, typ, dep = self.validateStream(port)\r
+ if name in lports:\r
+ raise Invalid("%s is already defined as a stream port" % name)\r
+ lports.add(name)\r
+\r
+ for port in self.outstream:\r
+ name, typ, dep = self.validateStream(port)\r
+ if name in lports:\r
+ raise Invalid("%s is already defined as a stream port" % name)\r
+ lports.add(name)\r
+\r
+ for port in self.parallel_instream:\r
+ name, typ = self.validateParallelStream(port)\r
+ if name in lports:\r
+ raise Invalid("%s is already defined as a stream port" % name)\r
+ lports.add(name)\r
+\r
+ for port in self.parallel_outstream:\r
+ name, typ = self.validateParallelStream(port)\r
+ if name in lports:\r
+ raise Invalid("%s is already defined as a stream port" % name)\r
+ lports.add(name)\r
+\r
+ self.validateImplType()\r
+\r
+ def validatePort(self, port):\r
+ try:\r
+ name, typ = port\r
+ except:\r
+ raise Invalid("%s is not a valid definition of an data port (name,type)" % (port,))\r
+\r
+ if self.impl in ("PY", "ASTER"):\r
+ validtypes = PyValidTypes\r
+ else:\r
+ validtypes = ValidTypes\r
+\r
+ if typ not in validtypes:\r
+ raise Invalid("%s is not a valid type. It should be one of %s" % (typ, validtypes))\r
+ return name, typ\r
+\r
+ def validateImplType(self):\r
+ if self.impl_type not in ValidImplTypes:\r
+ raise Invalid("%s is not a valid impl type. It should be one of %s" % (self.impl_type, ValidImplTypes))\r
+\r
+ def validateStream(self, port):\r
+ try:\r
+ name, typ, dep = port\r
+ except:\r
+ raise Invalid("%s is not a valid definition of a stream port (name,type,dependency)" % (port,))\r
+ if typ not in ValidStreamTypes:\r
+ raise Invalid("%s is not a valid type. It should be one of %s" % (typ, ValidStreamTypes))\r
+ if dep not in ValidDependencies:\r
+ raise Invalid("%s is not a valid dependency. It should be one of %s" % (dep, ValidDependencies))\r
+ return name, typ, dep\r
+\r
+ def validateParallelStream(self, port):\r
+ try:\r
+ name, typ = port\r
+ except:\r
+ raise Invalid("%s is not a valid definition of a parallel stream port (name,type)" % (port,))\r
+ if typ not in ValidParallelStreamTypes:\r
+ raise Invalid("%s is not a valid type. It should be one of %s" % (typ, ValidParallelStreamTypes))\r
+ return name, typ\r
+\r
+class Generator(object):\r
+ """\r
+ A :class:`Generator` instance take a :class:`Module` instance as its first parameter and can be used to generate the\r
+ SALOME source module, builds it, installs it and includes it in a SALOME application.\r
+\r
+ :param module: gives the :class:`Module` instance that will be used for the generation.\r
+ :param context: If given , its content is used to specify the prerequisites\r
+ environment file (key *"prerequisites"*) and the SALOME KERNEL installation directory (key *"kernel"*).\r
+ :type context: dict\r
+\r
+ For example, the following call creates a generator for the module m::\r
+\r
+ >>> g = module_generator.Generator(m,context)\r
+ """\r
+ def __init__(self, module, context=None):\r
+ self.module = module\r
+ self.context = context or {}\r
+ self.kernel = self.context["kernel"]\r
+ self.gui = self.context.get("gui")\r
+ self.makeflags = self.context.get("makeflags")\r
+ self.aster = ""\r
+ if self.module.gui and not self.gui:\r
+ raise Invalid("To generate a module with GUI, you need to set the 'gui' parameter in the context dictionnary")\r
+ for component in self.module.components:\r
+ component.setPrerequisites(self.context.get("prerequisites"))\r
+\r
+ def generate(self):\r
+ """Generate a SALOME source module"""\r
+ module = self.module\r
+ namedir = module.name+"_SRC"\r
+ force = self.context.get("force")\r
+ update = self.context.get("update")\r
+ paco = self.context.get("paco")\r
+ if os.path.exists(namedir):\r
+ if force:\r
+ shutil.rmtree(namedir)\r
+ elif not update:\r
+ raise Invalid("The directory %s already exists" % namedir)\r
+ if update:\r
+ makedirs(namedir)\r
+ else:\r
+ os.makedirs(namedir)\r
+\r
+ srcs = {}\r
+ makefile = "SUBDIRS="\r
+ makefileItems={"header":"""\r
+include $(top_srcdir)/adm_local/make_common_starter.am\r
+AM_CFLAGS=$(SALOME_INCLUDES) -fexceptions\r
+""",\r
+ "salomepython_PYTHON":[],\r
+ "dist_salomescript_SCRIPTS":[],\r
+ "salomeres_DATA":[],\r
+ "lib_LTLIBRARIES":[],\r
+ "salomeinclude_HEADERS":[],\r
+ "body":"",\r
+ }\r
+\r
+ #get the list of SALOME modules used and put it in used_modules attribute\r
+ def get_dependent_modules(mod,modules):\r
+ modules[mod]=1\r
+ if not salome_modules[mod].has_key("depends"):return\r
+ for m in salome_modules[mod]["depends"]:\r
+ if modules.has_key(m):continue\r
+ get_dependent_modules(m,modules)\r
+\r
+ modules = {}\r
+ for compo in module.components:\r
+ for serv in compo.services:\r
+ for name, typ in serv.inport + serv.outport + [ ("return",serv.ret) ] :\r
+ mod = moduleTypes[typ]\r
+ if mod:\r
+ get_dependent_modules(mod,modules)\r
+\r
+ self.used_modules = modules.keys()\r
+\r
+ for compo in module.components:\r
+ #for components files\r
+ fdict=compo.makeCompo(self)\r
+ if self.module.layout=="multidir":\r
+ srcs[compo.name] = fdict\r
+ #for src/Makefile.am\r
+ makefile = makefile + " " + compo.name\r
+ else:\r
+ srcs.update(fdict)\r
+ #for src/Makefile.am\r
+ mdict=compo.getMakefileItems(self)\r
+ makefileItems["salomepython_PYTHON"]=makefileItems["salomepython_PYTHON"]+mdict.get("salomepython_PYTHON",[])\r
+ makefileItems["dist_salomescript_SCRIPTS"]=makefileItems["dist_salomescript_SCRIPTS"]+mdict.get("dist_salomescript_SCRIPTS",[])\r
+ makefileItems["salomeres_DATA"]=makefileItems["salomeres_DATA"]+mdict.get("salomeres_DATA",[])\r
+ makefileItems["lib_LTLIBRARIES"]=makefileItems["lib_LTLIBRARIES"]+mdict.get("lib_LTLIBRARIES",[])\r
+ makefileItems["salomeinclude_HEADERS"]=makefileItems["salomeinclude_HEADERS"]+mdict.get("salomeinclude_HEADERS",[])\r
+ makefileItems["body"]=makefileItems["body"]+mdict.get("body","")+'\n'\r
+\r
+ if module.gui:\r
+ GUIname=module.name+"GUI"\r
+ fdict=self.makeGui(namedir)\r
+ srcs[GUIname] = fdict\r
+ #for src/Makefile.am\r
+ makefile = makefile + " " + GUIname\r
+\r
+ if self.module.layout == "multidir":\r
+ srcs["Makefile.am"] = makefile+'\n'\r
+ else:\r
+ srcs["Makefile.am"] = self.makeMakefile(makefileItems)\r
+\r
+ docsubdir=""\r
+ if module.doc:\r
+ docsubdir="doc"\r
+\r
+ #for catalog files\r
+ catalogfile = "%sCatalog.xml" % module.name\r
+\r
+ need_boost=0\r
+ if module.gui:\r
+ need_boost=1\r
+ for compo in module.components:\r
+ if hasattr(compo,"calciumextendedinterface") and compo.calciumextendedinterface:\r
+ need_boost=1\r
+ break\r
+\r
+ #add makefile definitions to make_common_starter.am\r
+ other_includes=""\r
+ common_starter = makecommon.substitute(other_includes=other_includes)\r
+ for mod in self.used_modules:\r
+ common_starter = common_starter + salome_modules[mod]["makefiledefs"] + '\n'\r
+\r
+ adm_local={"make_common_starter.am": common_starter, "check_aster.m4":check_aster}\r
+ if module.doc:\r
+ adm_local["check_sphinx.m4"]=check_sphinx\r
+\r
+ self.makeFiles({"autogen.sh":autogen,\r
+ "Makefile.am":mainMakefile.substitute(docsubdir=docsubdir),\r
+ "README":"", "NEWS":"", "AUTHORS":"", "ChangeLog":"",\r
+ "src":srcs,\r
+ "resources":{"Makefile.am":resMakefile.substitute(module=module.name), catalogfile:self.makeCatalog()},\r
+ "adm_local":adm_local,\r
+ }, namedir)\r
+\r
+ #add checks for modules in configure.ac\r
+ configure_modules=""\r
+ for mod in self.used_modules:\r
+ configure_modules = configure_modules + salome_modules[mod]["configdefs"] + '\n'\r
+\r
+ #for configure.ac\r
+ configure_makefiles = []\r
+ if self.module.layout=="multidir":\r
+ for compo in module.components:\r
+ configure_makefiles.append(" src/"+compo.name+"/Makefile")\r
+\r
+ if module.gui:\r
+ configure_makefiles.append(" src/%sGUI/Makefile" % module.name)\r
+ if module.doc:\r
+ configure_makefiles.append(" doc/Makefile")\r
+\r
+ other_check=""\r
+ other_summary=""\r
+ other_require=""\r
+\r
+ if need_boost:\r
+ other_check=other_check+"""CHECK_BOOST\r
+"""\r
+ other_summary=other_summary+"""echo " Boost ................. : $boost_ok"\r
+"""\r
+\r
+ if module.gui:\r
+ other_check=other_check + """CHECK_SALOME_GUI\r
+CHECK_QT\r
+"""\r
+ other_summary=other_summary+'''echo " SALOME GUI ............. : $SalomeGUI_ok"\r
+echo " Qt ..................... : $qt_ok"\r
+'''\r
+ other_require=other_require + """\r
+ if test "x$SalomeGUI_ok" = "xno"; then\r
+ AC_MSG_ERROR([SALOME GUI is required],1)\r
+ fi\r
+ if test "x$qt_ok" = "xno"; then\r
+ AC_MSG_ERROR([Qt library is required],1)\r
+ fi\r
+"""\r
+ if module.doc:\r
+ other_check=other_check+"CHECK_SPHINX\n"\r
+ other_summary=other_summary+'''echo " Sphinx ................. : $sphinx_ok"\n'''\r
+ other_require=other_require + """\r
+ if test "x$sphinx_ok" = "xno"; then\r
+ AC_MSG_ERROR([Sphinx documentation generator is required],1)\r
+ fi\r
+"""\r
+\r
+ files={}\r
+ #for idl files\r
+ idlfile = "%s.idl" % module.name\r
+ paco_config=""\r
+ PACO_BUILT_SOURCES=""\r
+ PACO_SALOMEINCLUDE_HEADERS=""\r
+ PACO_INCLUDES=""\r
+ PACO_salomepython_DATA=""\r
+ PACO_salomeidl_DATA=""\r
+\r
+ if paco:\r
+ PACO_BUILT_SOURCES = idlMakefilePaCO_BUILT_SOURCES.substitute(module=module.name)\r
+ PACO_SALOMEINCLUDE_HEADERS = idlMakefilePaCO_nodist_salomeinclude_HEADERS.substitute(module=module.name)\r
+ PACO_salomepython_DATA = idlMakefilePACO_salomepython_DATA.substitute(module=module.name)\r
+ PACO_salomeidl_DATA = idlMakefilePACO_salomeidl_DATA.substitute(module=module.name)\r
+ PACO_INCLUDES = idlMakefilePACO_INCLUDES\r
+ paco_config=paco_configure\r
+\r
+ files["configure.ac"]=configure.substitute(module=module.name.lower(),\r
+ makefiles='\n'.join(configure_makefiles),\r
+ paco_configure=paco_config,\r
+ modules=configure_modules,\r
+ other_check=other_check,\r
+ other_summary=other_summary,\r
+ other_require=other_require,\r
+ )\r
+\r
+ #if components have other idls\r
+ other_idls=""\r
+ other_sks=""\r
+ for compo in module.components:\r
+ if compo.idls:\r
+ for idl in compo.idls:\r
+ for fidl in glob.glob(idl):\r
+ other_idls=other_idls+os.path.basename(fidl) +" "\r
+ other_sks=other_sks+os.path.splitext(os.path.basename(fidl))[0]+"SK.cc "\r
+\r
+ idlfiles={"Makefile.am": idlMakefile.substitute(module=module.name,\r
+ PACO_BUILT_SOURCES=PACO_BUILT_SOURCES,\r
+ PACO_SALOMEINCLUDE_HEADERS=PACO_SALOMEINCLUDE_HEADERS,\r
+ PACO_INCLUDES=PACO_INCLUDES,\r
+ PACO_salomepython_DATA=PACO_salomepython_DATA,\r
+ PACO_salomeidl_DATA=PACO_salomeidl_DATA,\r
+ other_idls=other_idls,other_sks=other_sks,\r
+ ),\r
+ idlfile : self.makeidl(),\r
+ }\r
+ if paco:\r
+ idlfiles["%s.xml" % module.name]=self.makexml()\r
+\r
+ files["idl"]=idlfiles\r
+\r
+ self.makeFiles(files,namedir)\r
+\r
+ os.chmod(os.path.join(namedir, "autogen.sh"), 0777)\r
+ #copy source files if any in created tree\r
+ for compo in module.components:\r
+ for src in compo.sources:\r
+ if self.module.layout=="multidir":\r
+ shutil.copyfile(src, os.path.join(namedir, "src", compo.name, os.path.basename(src)))\r
+ else:\r
+ shutil.copyfile(src, os.path.join(namedir, "src", os.path.basename(src)))\r
+\r
+ if compo.idls:\r
+ #copy provided idl files in idl directory\r
+ for idl in compo.idls:\r
+ for fidl in glob.glob(idl):\r
+ shutil.copyfile(fidl, os.path.join(namedir, "idl", os.path.basename(fidl)))\r
+\r
+ checks= ("check_Kernel.m4", "check_omniorb.m4", "ac_linker_options.m4", "ac_cxx_option.m4",\r
+ "python.m4", "enable_pthreads.m4", "check_f77.m4", "acx_pthread.m4", "check_paco++.m4",\r
+ "check_mpi.m4", "check_lam.m4", "check_openmpi.m4", "check_mpich.m4")\r
+ if need_boost:\r
+ checks=checks+("check_boost.m4",)\r
+ for m4file in checks:\r
+ shutil.copyfile(os.path.join(self.kernel, "salome_adm", "unix", "config_files", m4file),\r
+ os.path.join(namedir, "adm_local", m4file))\r
+\r
+ if self.module.gui:\r
+ for m4file in ("check_GUI.m4", "check_qt.m4", "check_opengl.m4"):\r
+ shutil.copyfile(os.path.join(self.gui, "adm_local", "unix", "config_files", m4file),\r
+ os.path.join(namedir, "adm_local", m4file))\r
+\r
+ self.makeDoc(namedir)\r
+ return\r
+\r
+ def makeDoc(self,namedir):\r
+ if not self.module.doc:\r
+ return\r
+ rep=os.path.join(namedir,"doc")\r
+ os.makedirs(rep)\r
+ for docs in self.module.doc:\r
+ for doc in glob.glob(docs):\r
+ name = os.path.basename(doc)\r
+ shutil.copyfile(doc, os.path.join(rep, name))\r
+\r
+ d={}\r
+\r
+ others=""\r
+ if not self.module.gui:\r
+ #without gui but with doc: create a small SalomeApp.xml in doc directory\r
+ if not os.path.exists(os.path.join(namedir, "doc", "SalomeApp.xml")):\r
+ #create a minimal SalomeApp.xml\r
+ salomeapp=docsalomeapp.substitute(module=self.module.name,lmodule=self.module.name.lower())\r
+ d["SalomeApp.xml"]=salomeapp\r
+ others="SalomeApp.xml"\r
+\r
+ if not os.path.exists(os.path.join(namedir, "doc", "Makefile.am")):\r
+ #create a minimal makefile.am\r
+ d["Makefile.am"]=docmakefile.substitute(others=others)\r
+\r
+ if not os.path.exists(os.path.join(namedir, "doc", "conf.py")):\r
+ #create a minimal conf.py\r
+ d["conf.py"]=docconf.substitute(module=self.module.name)\r
+\r
+ self.makeFiles(d,os.path.join(namedir,"doc"))\r
+\r
+ def makeGui(self,namedir):\r
+ if not self.module.gui:\r
+ return\r
+ ispython=False\r
+ iscpp=False\r
+ #Force creation of intermediate directories\r
+ os.makedirs(os.path.join(namedir, "src", self.module.name+"GUI"))\r
+\r
+ for srcs in self.module.gui:\r
+ for src in glob.glob(srcs):\r
+ shutil.copyfile(src, os.path.join(namedir, "src", self.module.name+"GUI", os.path.basename(src)))\r
+ if src[-3:]==".py":ispython=True\r
+ if src[-4:]==".cxx":iscpp=True\r
+ if ispython and iscpp:\r
+ raise Invalid("Module GUI must be pure python or pure C++ but not mixed")\r
+ if ispython:\r
+ return self.makePyGUI(namedir)\r
+ if iscpp:\r
+ return self.makeCPPGUI(namedir)\r
+ raise Invalid("Module GUI must be in python or C++ but it is none of them")\r
+\r
+ def makePyGUI(self,namedir):\r
+ d={}\r
+ if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "Makefile.am")):\r
+ #create a minimal makefile.am\r
+ sources=[]\r
+ other=[]\r
+ for srcs in self.module.gui:\r
+ for src in glob.glob(srcs):\r
+ if src[-3:]==".py":\r
+ sources.append(os.path.basename(src))\r
+ else:\r
+ other.append(os.path.basename(src))\r
+ makefile=pyguimakefile.substitute(sources=" ".join(sources),other_sources=" ".join(other))\r
+ d["Makefile.am"]=makefile\r
+\r
+ if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "SalomeApp.xml")):\r
+ #create a minimal SalomeApp.xml\r
+ salomeapp=pysalomeapp.substitute(module=self.module.name,lmodule=self.module.name.lower())\r
+ d["SalomeApp.xml"]=salomeapp\r
+\r
+ return d\r
+\r
+ def makeCPPGUI(self,namedir):\r
+ d={}\r
+ if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "Makefile.am")):\r
+ #create a minimal makefile.am\r
+ sources=[]\r
+ other=[]\r
+ ui_files=[]\r
+ for srcs in self.module.gui:\r
+ for src in glob.glob(srcs):\r
+ if src[-4:]==".cxx":\r
+ sources.append(os.path.basename(src))\r
+ elif src[-2:]==".h":\r
+ sources.append(os.path.basename(src)[:-2]+"_moc.cxx")\r
+ elif src[-3:]==".ui":\r
+ ui_files.append("ui_"+os.path.basename(src)[:-3]+".h")\r
+ elif src[-3:]==".ts":\r
+ other.append(os.path.basename(src)[:-3]+".qm")\r
+ elif src[-13:]=="SalomeApp.xml":\r
+ pass # This file is already included in the cppguimakefile template!\r
+ else:\r
+ other.append(os.path.basename(src))\r
+\r
+ makefile=cppguimakefile.substitute(sources=" ".join(sources),other_sources=" ".join(other),\r
+ module=self.module.name, uisources= " ".join(ui_files))\r
+ d["Makefile.am"]=makefile\r
+\r
+ if not os.path.exists(os.path.join(namedir, "src", self.module.name+"GUI", "SalomeApp.xml")):\r
+ #create a minimal SalomeApp.xml\r
+ salomeapp=cppsalomeapp.substitute(module=self.module.name,lmodule=self.module.name.lower())\r
+ d["SalomeApp.xml"]=salomeapp\r
+\r
+ return d\r
+\r
+ def makeMakefile(self,makefileItems):\r
+ makefile=""\r
+ if makefileItems.has_key("header"):\r
+ makefile=makefile + makefileItems["header"]+'\n'\r
+ if makefileItems.has_key("lib_LTLIBRARIES"):\r
+ makefile=makefile+"lib_LTLIBRARIES= "+" ".join(makefileItems["lib_LTLIBRARIES"])+'\n'\r
+ if makefileItems.has_key("salomepython_PYTHON"):\r
+ makefile=makefile+"salomepython_PYTHON= "+" ".join(makefileItems["salomepython_PYTHON"])+'\n'\r
+ if makefileItems.has_key("dist_salomescript_SCRIPTS"):\r
+ makefile=makefile+"dist_salomescript_SCRIPTS= "+" ".join(makefileItems["dist_salomescript_SCRIPTS"])+'\n'\r
+ if makefileItems.has_key("salomeres_DATA"):\r
+ makefile=makefile+"salomeres_DATA= "+" ".join(makefileItems["salomeres_DATA"])+'\n'\r
+ if makefileItems.has_key("salomeinclude_HEADERS"):\r
+ makefile=makefile+"salomeinclude_HEADERS= "+" ".join(makefileItems["salomeinclude_HEADERS"])+'\n'\r
+ if makefileItems.has_key("body"):\r
+ makefile=makefile+makefileItems["body"]+'\n'\r
+ return makefile\r
+\r
+ def makeArgs(self, service):\r
+ """generate source service for arguments"""\r
+ params = []\r
+ for name, typ in service.inport:\r
+ if typ=="file":continue #files are not passed through service interface\r
+ params.append("%s %s" % (corba_in_type(typ, self.module.name), name))\r
+ for name, typ in service.outport:\r
+ if typ=="file":continue #files are not passed through service interface\r
+ params.append("%s %s" % (corba_out_type(typ, self.module.name), name))\r
+ return ",".join(params)\r
+\r
+ def makeCatalog(self):\r
+ """generate SALOME components catalog source"""\r
+ components = []\r
+ for compo in self.module.components:\r
+ services = []\r
+ for serv in compo.services:\r
+ params = []\r
+ for name, typ in serv.inport:\r
+ params.append(cataInparam.substitute(name=name, type=typ))\r
+ inparams = "\n".join(params)\r
+ params = []\r
+ for name, typ in serv.outport:\r
+ params.append(cataOutparam.substitute(name=name, type=typ))\r
+ if serv.ret != "void" :\r
+ params.append(cataOutparam.substitute(name="return", type=serv.ret))\r
+ outparams = "\n".join(params)\r
+ streams = []\r
+ for name, typ, dep in serv.instream:\r
+ streams.append(cataInStream.substitute(name=name, type=calciumTypes[typ], dep=dep))\r
+ for name, typ, dep in serv.outstream:\r
+ streams.append(cataOutStream.substitute(name=name, type=calciumTypes[typ], dep=dep))\r
+ for name, typ in serv.parallel_instream:\r
+ streams.append(cataInParallelStream.substitute(name=name, type=DatastreamParallelTypes[typ]))\r
+ for name, typ in serv.parallel_outstream:\r
+ streams.append(cataOutParallelStream.substitute(name=name, type=DatastreamParallelTypes[typ]))\r
+ datastreams = "\n".join(streams)\r
+ services.append(cataService.substitute(service=serv.name, author="EDF-RD",\r
+ inparams=inparams, outparams=outparams, datastreams=datastreams))\r
+ impltype, implname = compo.getImpl()\r
+ components.append(cataCompo.substitute(component=compo.name, author="EDF-RD", impltype=impltype, implname=implname,\r
+ services='\n'.join(services)))\r
+ return catalog.substitute(components='\n'.join(components))\r
+\r
+ def makeidl(self):\r
+ """generate module IDL file source (CORBA interface)"""\r
+ from pacocompo import PACOComponent\r
+ interfaces = []\r
+ idldefs=""\r
+ for compo in self.module.components:\r
+ if isinstance(compo, PACOComponent):\r
+ services = []\r
+ for serv in compo.services:\r
+ params = []\r
+ for name, typ in serv.inport:\r
+ if typ == "file":continue #files are not passed through IDL interface\r
+ params.append("in %s %s" % (idlTypes[typ], name))\r
+ for name, typ in serv.outport:\r
+ if typ == "file":continue #files are not passed through IDL interface\r
+ params.append("out %s %s" % (idlTypes[typ], name))\r
+ service = " void %s(" % serv.name\r
+ service = service+",".join(params)+");"\r
+ services.append(service)\r
+\r
+ interfaces.append(parallel_interface.substitute(component=compo.name, services="\n".join(services)))\r
+\r
+ else:\r
+ services = []\r
+ for serv in compo.services:\r
+ params = []\r
+ for name, typ in serv.inport:\r
+ if typ == "file":continue #files are not passed through IDL interface\r
+ if compo.impl in ("PY", "ASTER") and typ == "pyobj":\r
+ typ = "Engines::fileBlock"\r
+ else:\r
+ typ=idlTypes[typ]\r
+ params.append("in %s %s" % (typ, name))\r
+ for name, typ in serv.outport:\r
+ if typ == "file":continue #files are not passed through IDL interface\r
+ if compo.impl in ("PY", "ASTER") and typ == "pyobj":\r
+ typ = "Engines::fileBlock"\r
+ else:\r
+ typ=idlTypes[typ]\r
+ params.append("out %s %s" % (typ, name))\r
+ service = " %s %s(" % (idlTypes[serv.ret],serv.name)\r
+ service = service+",".join(params)+") raises (SALOME::SALOME_Exception);"\r
+ services.append(service)\r
+\r
+ from hxxcompo import HXX2SALOMEComponent\r
+ from hxxparacompo import HXX2SALOMEParaComponent\r
+ if isinstance(compo,HXX2SALOMEComponent) or isinstance(compo,HXX2SALOMEParaComponent):\r
+ from hxx_tmpl import interfaceidlhxx\r
+ Inherited=""\r
+ if isinstance(compo,HXX2SALOMEParaComponent):\r
+ Inherited="SALOME_MED::ParaMEDMEMComponent"\r
+ idldefs="""#include "ParaMEDMEMComponent.idl"\n"""\r
+ else:\r
+ if compo.use_medmem==True:\r
+ Inherited="Engines::EngineComponent,SALOME::MultiCommClass,SALOME_MED::MED_Gen_Driver"\r
+ else:\r
+ Inherited="Engines::EngineComponent"\r
+ interfaces.append(interfaceidlhxx.substitute(component=compo.name,inherited=Inherited, services="\n".join(services)))\r
+ else:\r
+ inheritedinterface=""\r
+ if compo.inheritedinterface:\r
+ inheritedinterface=compo.inheritedinterface+","\r
+ interfaces.append(interface.substitute(component=compo.name, services="\n".join(services),inheritedinterface=inheritedinterface))\r
+\r
+ #build idl includes for SALOME modules\r
+ for mod in self.used_modules:\r
+ idldefs = idldefs + salome_modules[mod]["idldefs"]\r
+\r
+ for compo in self.module.components:\r
+ if compo.interfacedefs:\r
+ idldefs = idldefs + compo.interfacedefs\r
+\r
+ return idl.substitute(module=self.module.name, interfaces='\n'.join(interfaces),idldefs=idldefs)\r
+\r
+ # For PaCO++\r
+ def makexml(self):\r
+ from pacocompo import PACOComponent\r
+ interfaces = []\r
+ for compo in self.module.components:\r
+ if isinstance(compo, PACOComponent):\r
+ services = []\r
+ for serv in compo.services:\r
+ if serv.impl_type == "parallel":\r
+ service = xml_service.substitute(service_name=serv.name)\r
+ services.append(service)\r
+ interfaces.append(xml_interface.substitute(component=compo.name, xml_services="\n".join(services)))\r
+ return xml.substitute(module=self.module.name, interfaces='\n'.join(interfaces))\r
+\r
+ def makeFiles(self, dic, basedir):\r
+ """create files and directories defined in dictionary dic in basedir directory\r
+ dic key = file name to create\r
+ dic value = file content or dictionary defining the content of a sub directory\r
+ """\r
+ for name, content in dic.items():\r
+ filename = os.path.join(basedir, name)\r
+ if isinstance(content, str):\r
+ fil = open(filename, 'w')\r
+ fil.write(content)\r
+ fil.close()\r
+ else:\r
+ if not os.path.exists(filename):\r
+ os.makedirs(filename)\r
+ self.makeFiles(content, filename)\r
+\r
+ def bootstrap(self):\r
+ """Execute the first build step (bootstrap autotools with autogen.sh script) : execution of libtool, autoconf, automake"""\r
+ ier = os.system("cd %s_SRC;sh autogen.sh" % self.module.name)\r
+ if ier != 0:\r
+ raise Invalid("bootstrap has ended in error")\r
+\r
+ def configure(self):\r
+ """Execute the second build step (configure) with installation prefix as given by the prefix attribute of module"""\r
+ prefix = self.module.prefix\r
+ paco = self.context.get("paco")\r
+ mpi = self.context.get("mpi")\r
+ args = (self.module.name, self.kernel, self.aster)\r
+ cmd = "cd %s_SRC;./configure --with-kernel=%s --with-aster=%s" % args\r
+ if self.gui:\r
+ cmd = cmd + " --with-gui=%s" % self.gui\r
+ if prefix:\r
+ prefix = os.path.abspath(prefix)\r
+ cmd = cmd + " --prefix=%s" % prefix\r
+ if paco:\r
+ cmd += " --with-paco=%s" % paco\r
+ if mpi:\r
+ cmd += " --with-mpi=%s" % mpi\r
+\r
+ ier = os.system(cmd)\r
+ if ier != 0:\r
+ raise Invalid("configure has ended in error")\r
+\r
+ def make(self):\r
+ """Execute the third build step (compile and link) : make"""\r
+ make_command = "make "\r
+ if self.makeflags:\r
+ make_command += self.makeflags\r
+ ier = os.system("cd %s_SRC;%s" % (self.module.name, make_command))\r
+ if ier != 0:\r
+ raise Invalid("make has ended in error")\r
+\r
+ def install(self):\r
+ """Execute the installation step : make install """\r
+ makedirs(self.module.prefix)\r
+ ier = os.system("cd %s_SRC;make install" % self.module.name)\r
+ if ier != 0:\r
+ raise Invalid("install has ended in error")\r
+\r
+ def make_appli(self, appliname, restrict=None, altmodules=None, resources=""):\r
+ """\r
+ Create a SALOME application containing the module and preexisting SALOME modules.\r
+\r
+ :param appliname: is a string that gives the name of the application (directory path where the application\r
+ will be installed).\r
+ :type appliname: str\r
+ :param restrict: If given (a list of module names), only those SALOME modules will be included in the\r
+ application. The default is to include all modules that are located in the same directory as the KERNEL module and have\r
+ the same suffix (for example, if KERNEL directory is KERNEL_V5 and GEOM directory is GEOM_V5, GEOM module is automatically\r
+ included, except if restrict is used).\r
+ :param altmodules: can be used to add SALOME modules that cannot be managed with the precedent rule. This parameter\r
+ is a dict with a module name as the key and the installation path as the value.\r
+ :param resources: can be used to define an alternative resources catalog (path of the file).\r
+\r
+ For example, the following calls create a SALOME application with external modules and resources catalog in "appli" directory::\r
+\r
+ >>> g=Generator(m,context)\r
+ >>> g.generate()\r
+ >>> g.bootstrap()\r
+ >>> g.configure()\r
+ >>> g.make()\r
+ >>> g.install()\r
+ >>> g.make_appli("appli", restrict=["KERNEL"], altmodules={"GUI":GUI_ROOT_DIR, "YACS":YACS_ROOT_DIR},\r
+ resources="myresources.xml")\r
+\r
+ """\r
+ makedirs(appliname)\r
+\r
+ rootdir, kerdir = os.path.split(self.kernel)\r
+\r
+ #collect modules besides KERNEL module with the same suffix if any\r
+ modules_dict = {}\r
+ if kerdir[:6] == "KERNEL":\r
+ suffix = kerdir[6:]\r
+ for mod in os.listdir(rootdir):\r
+ if mod[-len(suffix):] == suffix:\r
+ module = mod[:-len(suffix)]\r
+ path = os.path.join(rootdir, mod)\r
+ #try to find catalog files\r
+ lcata = glob.glob(os.path.join(path, "share", "salome", "resources", "*", "*Catalog.xml"))\r
+ if not lcata:\r
+ #catalogs have not been found : try the upper level\r
+ lcata = glob.glob(os.path.join(path, "share", "salome", "resources", "*Catalog.xml"))\r
+ if lcata:\r
+ #catalogs have been found : add the corresponding entries in the application\r
+ for cata in lcata:\r
+ catadir, catafile = os.path.split(cata)\r
+ name = catafile[:-11]\r
+ modules_dict[name] = ' <module name="%s" path="%s"/>' % (name, path)\r
+ else:\r
+ modules_dict[module] = ' <module name="%s" path="%s"/>' % (module, path)\r
+\r
+ modules_dict["KERNEL"] = ' <module name="KERNEL" path="%s"/>' % self.kernel\r
+\r
+ #keep only the modules which names are in restrict if given\r
+ modules = []\r
+ if restrict:\r
+ for mod in restrict:\r
+ if modules_dict.has_key(mod):\r
+ modules.append(modules_dict[mod])\r
+ else:\r
+ modules = modules_dict.values()\r
+\r
+ #add the alternate modules if given\r
+ if altmodules:\r
+ for module, path in altmodules.items():\r
+ modules.append(' <module name="%s" path="%s"/>' % (module, path))\r
+\r
+ #add the generated module\r
+ modules.append(' <module name="%s" path="%s"/>' % (self.module.name, os.path.abspath(self.module.prefix)))\r
+\r
+\r
+ #try to find a prerequisites file\r
+ prerequisites = self.context.get("prerequisites")\r
+ if not prerequisites:\r
+ #try to find one in rootdir\r
+ prerequisites = os.path.join(rootdir, "profile%s.sh" % suffix)\r
+ if not os.path.exists(prerequisites):\r
+ raise Invalid("Can not create an application : prerequisites file not defined or does not exist")\r
+\r
+ #add resources catalog if it exists\r
+ resources_spec=""\r
+ if os.path.isfile(resources):\r
+ resources_spec='<resources path="%s" />' % os.path.abspath(resources)\r
+\r
+ #create config_appli.xml file\r
+ appli = application.substitute(prerequisites=prerequisites,\r
+ modules="\n".join(modules),\r
+ resources=resources_spec)\r
+ fil = open(os.path.join(appliname, "config_appli.xml"), 'w')\r
+ fil.write(appli)\r
+ fil.close()\r
+\r
+ #execute appli_gen.py script\r
+ appligen = os.path.join(self.kernel, "bin", "salome", "appli_gen.py")\r
+ ier = os.system("cd %s;%s" % (appliname, appligen))\r
+ if ier != 0:\r
+ raise Invalid("make_appli has ended in error")\r
+\r
+ #add CatalogResources.xml if not created by appli_gen.py\r
+ if not os.path.exists(os.path.join(appliname, "CatalogResources.xml")):\r
+ #CatalogResources.xml does not exist create a minimal one\r
+ fil = open(os.path.join(appliname, 'CatalogResources.xml'), 'w')\r
+ command = """<!DOCTYPE ResourcesCatalog>\r
+<resources>\r
+ <machine hostname="%s" protocol="ssh" mode="interactive" />\r
+</resources>\r
+"""\r
+ host = socket.gethostname().split('.')[0]\r
+ fil.write(command % host)\r
+ fil.close()\r
+\r
-# Copyright (C) 2009-2012 EDF R&D
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-"""
- Module that generates SALOME c++ Component from a non SALOME c++ component
- (its header and its shares library)
-"""
-
-debug=1
-import os
-import string
-import fnmatch
-from tempfile import mkstemp
-from gener import Component, Invalid
-from hxx_tmpl import cxxService, hxxCompo, cxxCompo, compoMakefile
-from module_generator import Service
-from yacstypes import corba_rtn_type,moduleTypes
-from hxx_awk import parse01,parse1,parse2,parse3
-from hxx_awk import cpp2idl_mapping
-# these tables contain the part of code which depends upon c++ types
-from hxx_awk import cpp_impl_a,cpp_impl_b,cpp_impl_c
-from hxx_awk import cpp2yacs_mapping
-from tempfile import mkdtemp
-from hxx_tmpl_gui import hxxgui_cxx, hxxgui_h, hxxgui_icon_ts
-from hxx_tmpl_gui import hxxgui_message_en, hxxgui_message_fr
-from hxx_tmpl_gui import hxxgui_config, hxxgui_xml_fr, hxxgui_xml_en
-
-# ------------------------------------------------------------------------------
-
-class HXX2SALOMEComponent(Component):
- def __init__(self, hxxfile , cpplib , cpp_path ):
- # search a file within a directory tree
- def search_file(pattern, root):
- matches = []
- for path, dirs, files in os.walk(os.path.abspath(root)):
- for filename in fnmatch.filter(files, pattern):
- matches.append(os.path.join(path, filename))
- return matches
-
- hxxfileful = search_file(hxxfile,cpp_path)
- cpplibful = search_file(cpplib,cpp_path)
- format_error = 'Error in HXX2SALOMEComponent : file %s ot found in %s'
- assert len(hxxfileful) > 0, format_error % (hxxfile, cpp_path)
- assert len(cpplibful) > 0, format_error % (cpplib, cpp_path)
- hxxfile = hxxfileful[0]
- cpplib = cpplibful[0]
-
- # grab name of c++ component
- cmd1="""awk '$1 == "class" && $0 !~ /;/ {print $2}' """ + hxxfile +\
- """|awk -F: '{printf "%s",$1}' """
- f=os.popen(cmd1)
- class_name=f.readlines()[0]
- name=class_name
- print "classname=",class_name
- f.close()
-
- # create temporary awk files for the parsing
- (fd01,p01n)=mkstemp()
- f01=os.fdopen(fd01,"w")
- f01.write(parse01)
- f01.close()
-
- (fd1,p1n)=mkstemp()
- f1=os.fdopen(fd1,"w")
- f1.write(parse1)
- f1.close()
-
- (fd2,p2n)=mkstemp()
- f2=os.fdopen(fd2,"w")
- f2.write(parse2)
- f2.close()
-
- (fd3,p3n)=mkstemp()
- f3=os.fdopen(fd3,"w")
- f3.write(parse3)
- f3.close()
-
- # awk parsing of hxx files -
- # result written in file parse_type_result
- cmd2 = [
- "cat %s" % hxxfile,
- "awk -f %s" % p01n,
- "sed 's/virtual //g'",
- "sed 's/MEDMEM_EXPORT//g'",
- "sed 's/throw.*;/;/g'",
- "awk -f %s" % p1n,
- "awk -f %s" % p2n,
- "awk -v class_name=%s -f %s" % (class_name, p3n) ]
- cmd2 = ' | '.join(cmd2)
-
- #os.system(cmd2)
- import subprocess, sys
- subprocess.call(cmd2, shell=True, stdout=sys.stdout, stderr=subprocess.STDOUT)
- os.remove(p01n)
- os.remove(p1n)
- os.remove(p2n)
- os.remove(p3n)
-
- # Retrieve the information which was generated in
- # the file parse_type_result.
- # The structure of the file is :
- #
- # Function return_type function_name
- # [arg1_type arg1_name]
- # [arg2_type arg2_name]
- # ...
- # The service names are stored in list_of_services
- # The information relative to a service (called service_name) is stored in
- # the dictionnary service_definition[service_name]
- list_of_services=[]
- service_definition={}
- result_parsing=open("parse_type_result","r")
- for line in result_parsing.readlines():
- line=line[0:-1] # get rid of trailing \n
- words = string.split(line,';')
-
- if len(words) >=3 and words[0] == "Function": # detect a new service
- function_name=words[2]
- # store the name of new service
- list_of_services.append(function_name)
- # create a dict to store informations relative to this service
- service_definition[function_name]={}
- service_definition[function_name]["ret"]=words[1] # return type
- service_definition[function_name]["inports"]=[]
- service_definition[function_name]["outports"]=[]
- service_definition[function_name]["ports"]=[]
- service_definition[function_name]["impl"]=[]
-
- # an argument type and argument name of the current service
- if len(words) == 2:
- current_service=list_of_services[-1]
- current_service_dict=service_definition[current_service]
- typename=words[0]
- argname=words[1]
- # store in c++ order the arg names
- current_service_dict["ports"].append( (argname,typename) )
-
- # separate in from out parameters
- inout=cpp2idl_mapping[typename][0:2]
- assert inout=="in" or inout=="ou",'Error in table cpp2idl_mapping'
- if inout == "in":
- current_service_dict["inports"].append((argname, typename) )
- else:
- current_service_dict["outports"].append((argname, typename) )
- #
- # For each service :
- # - generate implementation of c++ servant
- # - store it in service_definition[serv]["impl"]
- for serv in list_of_services:
- if debug:
- print "service : ",serv
- print " inports -> ",service_definition[serv]["inports"]
- print " outports -> ",service_definition[serv]["outports"]
- print " return -> ",service_definition[serv]["ret"]
-
-
- # Part 1 : Argument pre-processing
- s_argument_processing="//\tArguments processing\n"
- for (argname,argtype) in service_definition[serv]["inports"] + \
- service_definition[serv]["outports"]:
- format=cpp_impl_a[argtype]
- s_argument_processing += format % {"arg" : argname }
-
- # if there was no args
- if s_argument_processing=="//\tArguments processing\n":
- s_argument_processing=""
-
-
- # Part 2 : Call to the underlying c++ function
- s_call_cpp_function="//\tCall cpp component\n\t"
- rtn_type=service_definition[serv]["ret"]
-
- # if return type is void, the call syntax is different
- if rtn_type == "void" :
- s_call_cpp_function += "cppCompo_->%s(" % serv
- else:
- s_call_cpp_function +=\
- "%s _rtn_cpp = cppCompo_->%s(" % (rtn_type ,serv )
-
- for (argname,argtype) in service_definition[serv]["ports"]:
- # special treatment for some arguments
- post=""
- pre=""
-
- if string.find(cpp_impl_a[argtype],"auto_ptr" ) != -1 :
- # for auto_ptr argument, retrieve the raw pointer behind
- post=".get()"
- if argtype == "const MEDMEM::MESH&" or \
- argtype == "const MEDMEM::SUPPORT&" :
- # we cannot create MESHClient on the stack
- # (private constructor!),
- # so we create it on the heap and dereference it
- pre="*"
-
- post+="," # separator between arguments
- s_call_cpp_function += " %s_%s%s" % ( pre,argname,post)
- if s_call_cpp_function[-1]==',':
- # get rid of trailing comma
- s_call_cpp_function=s_call_cpp_function[0:-1]
-
- s_call_cpp_function=s_call_cpp_function+');\n'
-
- # Part 3.a : Out Argument Post-processing
- s_argument_postprocessing="//\tPost-processing & return\n"
- for (argname,argtype) in service_definition[serv]["outports"]:
- format=cpp_impl_c[argtype]
- # the treatment of %(module) is postponed in makecxx()
- # because we don't know here the module name
- s_argument_postprocessing += \
- format % {"arg" : argname, "module" : "%(module)s" }
-
- # Part 3.b : In Argument Post-processing
- for (argname,argtype) in service_definition[serv]["inports"]:
- # not all in types require a treatment
- if cpp_impl_c.has_key(argtype):
- format=cpp_impl_c[argtype]
- # id : treatment of %(module) is postponed in makecxx
- s_argument_postprocessing += \
- format % {"arg" : argname, "module" : "%(module)s" }
-
- # Part 3.c : return processing
- s_rtn_processing=cpp_impl_b[rtn_type]
-
- format_end_serv = "\tendService(\"%(class_name)s_i::%(serv_name)s\");"
- format_end_serv += "\n\tEND_OF(\"%(class_name)s_i::%(serv_name)s\");\n"
- s_rtn_processing += format_end_serv %\
- { "serv_name" : serv, "class_name" : class_name }
-
- if rtn_type != "void":
- s_rtn_processing += "\treturn _rtn_ior;"
-
- service_definition[serv]["impl"] = s_argument_processing + \
- s_call_cpp_function + \
- s_argument_postprocessing + \
- s_rtn_processing
- if debug:
- print "implementation :\n",service_definition[serv]["impl"]
-
- #
- # Create a list of Service objects (called services),
- # and give it to Component constructor
- #
- services=[]
- self.use_medmem=False
- self.use_medcoupling=False
- for serv in list_of_services:
- # for inports and outports, Service class expects a list of tuples,
- # each tuple containing the name and the yacs type of the port
- # thus we need to convert c++ types to yacs types
- # (we use for that the cpp2yacs_mapping table)
- inports=[]
- for op in service_definition[serv]["inports"]:
- inports.append([op[0], cpp2yacs_mapping[op[1]] ] )
-
- outports = []
- for op in service_definition[serv]["outports"]:
- outports.append([op[0], cpp2yacs_mapping[op[1]] ] )
-
- Return="void"
- if service_definition[serv]["ret"] != "void":
- Return=cpp2yacs_mapping[service_definition[serv]["ret"]]
-
- # find out if component uses medmem types and/or medcoupling types
- for (argname,argtype) in inports + outports + [("return",Return)]:
- if moduleTypes[argtype]=="MED":
- if argtype.count("CorbaInterface")>0:
- self.use_medcoupling=True
- else:
- self.use_medmem=True
- break
-
- code=service_definition[serv]["impl"]
- if debug:
- print "service : ",serv
- print " inports -> ",service_definition[serv]["inports"]
- print " converted inports -> ",inports
- print " outports -> ",service_definition[serv]["outports"]
- print " converted outports -> ",outports
- print " Return -> ",service_definition[serv]["ret"]
- print " converted Return -> ",Return
-
- services.append(Service(serv,
- inport=inports,
- outport=outports,
- ret=Return,
- defs="",
- body=code,
- ) )
-
- Includes="-I${"+name+"CPP_ROOT_DIR}/include"
- Libs="-L${"+name+"CPP_ROOT_DIR}/lib -l"+name+"CXX"
- Compodefs=""
- Inheritedclass=""
- self.inheritedconstructor=""
- if self.use_medmem:
- Compodefs="""
-#include CORBA_CLIENT_HEADER(MED)
-#include CORBA_CLIENT_HEADER(MED_Gen)
-#include "FIELDClient.hxx"
-#include "MESHClient.hxx"
-#include "MEDMEM_Support_i.hxx"
-#include "MEDMEM_Mesh_i.hxx"
-#include "MEDMEM_FieldTemplate_i.hxx"
-#include "Med_Gen_Driver_i.hxx"
-"""
- Inheritedclass="Med_Gen_Driver_i, public SALOMEMultiComm"
- self.inheritedconstructor="Med_Gen_Driver_i(orb),"
-
- if self.use_medcoupling:
- Compodefs+="""
-#include CORBA_CLIENT_HEADER(MEDCouplingCorbaServant)
-#include CORBA_CLIENT_HEADER(MED_Gen)
-#include "MEDCouplingFieldDoubleServant.hxx"
-#include "MEDCouplingUMeshServant.hxx"
-#include "DataArrayDoubleServant.hxx"
-#include "MEDCouplingFieldDouble.hxx"
-#include "MEDCouplingUMesh.hxx"
-#include "MEDCouplingUMeshClient.hxx"
-#include "MEDCouplingFieldDouble.hxx"
-#include "MEDCouplingFieldDoubleClient.hxx"
-#include "MEDCouplingMemArray.hxx"
-#include "DataArrayDoubleClient.hxx"
-"""
-
- Component.__init__(self, name, services, impl="CPP", libs=Libs,
- rlibs="", includes=Includes, kind="lib",
- sources=None,inheritedclass=Inheritedclass,
- compodefs=Compodefs)
-
-# ------------------------------------------------------------------------------
- def makeCompo(self, gen):
- """generate files for C++ component
- return a dict where key is the file name and
- value is the content of the file
- """
- cxxfile = "%s_i.cxx" % self.name
- hxxfile = "%s_i.hxx" % self.name
- return {"Makefile.am":gen.makeMakefile(self.getMakefileItems(gen)),
- cxxfile:self.makecxx(gen),
- hxxfile:self.makehxx(gen)
- }
-
-# ------------------------------------------------------------------------------
- def getMakefileItems(self,gen):
- makefileItems={"header":"""
-include $(top_srcdir)/adm_local/make_common_starter.am
-
-"""}
- makefileItems["lib_LTLIBRARIES"]=["lib"+self.name+"Engine.la"]
- makefileItems["salomeinclude_HEADERS"]=["%s_i.hxx" % self.name]
- makefileItems["body"]=compoMakefile.substitute(module=gen.module.name,
- component=self.name,
- libs=self.libs,
- includes=self.includes)
- return makefileItems
-
-# ------------------------------------------------------------------------------
- def makehxx(self, gen):
- """return a string that is the content of .hxx file
- """
- services = []
- for serv in self.services:
- service = " %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),
- serv.name)
- service = service+gen.makeArgs(serv)+") throw (SALOME::SALOME_Exception);"
- services.append(service)
- servicesdef = "\n".join(services)
-
- inheritedclass=self.inheritedclass
- if self.inheritedclass:
- inheritedclass= " public virtual " + self.inheritedclass + ","
-
- return hxxCompo.substitute(component=self.name,
- module=gen.module.name,
- servicesdef=servicesdef,
- inheritedclass=inheritedclass,
- compodefs=self.compodefs)
-
-# ------------------------------------------------------------------------------
- def makecxx(self, gen, exe=0):
- """return a string that is the content of .cxx file
- """
- services = []
- inits = []
- defs = []
- for serv in self.services:
- defs.append(serv.defs)
- print "CNC bug : ",serv.body
- service = cxxService.substitute(
- component=self.name,
- service=serv.name,
- ret=corba_rtn_type(serv.ret,gen.module.name),
- parameters=gen.makeArgs(serv),
- body=serv.body % {"module":gen.module.name+"_ORB"} )
- services.append(service)
- return cxxCompo.substitute(component=self.name,
- inheritedconstructor=self.inheritedconstructor,
- servicesdef="\n".join(defs),
- servicesimpl="\n".join(services))
-
-# ------------------------------------------------------------------------------
- def getGUIfilesTemplate(self):
- """generate in a temporary directory files for a generic GUI,
- and return a list with file names.
- it is the responsability of the user to get rid
- of the temporary directory when finished
- """
- gui_cxx=hxxgui_cxx.substitute(component_name=self.name)
- gui_h=hxxgui_h.substitute(component_name=self.name)
- gui_icon_ts=hxxgui_icon_ts.substitute(component_name=self.name)
- gui_message_en=hxxgui_message_en.substitute(component_name=self.name)
- gui_message_fr=hxxgui_message_fr.substitute(component_name=self.name)
- gui_config=hxxgui_config.substitute(component_name=self.name)
- gui_xml_fr=hxxgui_xml_fr.substitute(component_name=self.name)
- gui_xml_en=hxxgui_xml_en.substitute(component_name=self.name)
- temp_dir=mkdtemp()
- gui_cxx_file_name=os.path.join(temp_dir,self.name+"GUI.cxx")
- gui_h_file_name=os.path.join(temp_dir,self.name+"GUI.h")
- gui_icon_ts_file_name=os.path.join(temp_dir,self.name+"_icons.ts")
- gui_message_en_file_name=os.path.join(temp_dir,self.name+"_msg_en.ts")
- gui_message_fr_file_name=os.path.join(temp_dir,self.name+"_msg_fr.ts")
- gui_config_file_name=os.path.join(temp_dir,"config")
- gui_xml_fr_file_name=os.path.join(temp_dir,self.name+"_en.xml")
- gui_xml_en_file_name=os.path.join(temp_dir,self.name+"_fr.xml")
-
- list_of_gui_names=[]
-
- gui_cxx_file=open(gui_cxx_file_name,"w")
- gui_cxx_file.write(gui_cxx)
- gui_cxx_file.close()
- list_of_gui_names.append(gui_cxx_file_name)
-
- gui_h_file=open(gui_h_file_name,"w")
- gui_h_file.write(gui_h)
- gui_h_file.close()
- list_of_gui_names.append(gui_h_file_name)
-
- gui_icon_ts_file=open(gui_icon_ts_file_name,"w")
- gui_icon_ts_file.write(gui_icon_ts)
- gui_icon_ts_file.close()
- list_of_gui_names.append(gui_icon_ts_file_name)
-
- gui_message_en_file=open(gui_message_en_file_name,"w")
- gui_message_en_file.write(gui_message_en)
- gui_message_en_file.close()
- list_of_gui_names.append(gui_message_en_file_name)
-
- gui_message_fr_file=open(gui_message_fr_file_name,"w")
- gui_message_fr_file.write(gui_message_fr)
- gui_message_fr_file.close()
- list_of_gui_names.append(gui_message_fr_file_name)
-
- gui_config_file=open(gui_config_file_name,"w")
- gui_config_file.write(gui_config)
- gui_config_file.close()
- list_of_gui_names.append(gui_config_file_name)
-
- gui_xml_fr_file=open(gui_xml_fr_file_name,"w")
- gui_xml_fr_file.write(gui_xml_fr)
- gui_xml_fr_file.close()
- list_of_gui_names.append(gui_xml_fr_file_name)
-
- gui_xml_en_file=open(gui_xml_en_file_name,"w")
- gui_xml_en_file.write(gui_xml_en)
- gui_xml_en_file.close()
- list_of_gui_names.append(gui_xml_en_file_name)
-
-
- return list_of_gui_names
+# Copyright (C) 2009-2012 EDF R&D\r
+#\r
+# This library is free software; you can redistribute it and/or\r
+# modify it under the terms of the GNU Lesser General Public\r
+# License as published by the Free Software Foundation; either\r
+# version 2.1 of the License.\r
+#\r
+# This library is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+# Lesser General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU Lesser General Public\r
+# License along with this library; if not, write to the Free Software\r
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+#\r
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
+#\r
+"""\r
+ Module that generates SALOME c++ Component from a non SALOME c++ component \r
+ (its header and its shares library)\r
+"""\r
+\r
+debug=1\r
+import os\r
+import string\r
+import fnmatch\r
+from tempfile import mkstemp\r
+from gener import Component, Invalid\r
+from hxx_tmpl import cxxService, hxxCompo, cxxCompo, compoMakefile\r
+from module_generator import Service\r
+from yacstypes import corba_rtn_type,moduleTypes\r
+from hxx_awk import parse01,parse1,parse2,parse3\r
+from hxx_awk import cpp2idl_mapping\r
+# these tables contain the part of code which depends upon c++ types\r
+from hxx_awk import cpp_impl_a,cpp_impl_b,cpp_impl_c \r
+from hxx_awk import cpp2yacs_mapping\r
+from tempfile import mkdtemp\r
+from hxx_tmpl_gui import hxxgui_cxx, hxxgui_h, hxxgui_icon_ts\r
+from hxx_tmpl_gui import hxxgui_message_en, hxxgui_message_fr\r
+from hxx_tmpl_gui import hxxgui_config, hxxgui_xml_fr, hxxgui_xml_en\r
+from gui_tmpl import cppsalomeapp\r
+\r
+# ------------------------------------------------------------------------------\r
+\r
+class HXX2SALOMEComponent(Component):\r
+ def __init__(self, hxxfile , cpplib , cpp_path ):\r
+ # search a file within a directory tree\r
+ def search_file(pattern, root):\r
+ matches = []\r
+ for path, dirs, files in os.walk(os.path.abspath(root)):\r
+ for filename in fnmatch.filter(files, pattern):\r
+ matches.append(os.path.join(path, filename))\r
+ return matches\r
+\r
+ hxxfileful = search_file(hxxfile,cpp_path)\r
+ cpplibful = search_file(cpplib,cpp_path)\r
+ format_error = 'Error in HXX2SALOMEComponent : file %s ot found in %s'\r
+ assert len(hxxfileful) > 0, format_error % (hxxfile, cpp_path)\r
+ assert len(cpplibful) > 0, format_error % (cpplib, cpp_path)\r
+ hxxfile = hxxfileful[0]\r
+ cpplib = cpplibful[0]\r
+\r
+ # grab name of c++ component\r
+ cmd1="""awk '$1 == "class" && $0 !~ /;/ {print $2}' """ + hxxfile +\\r
+ """|awk -F: '{printf "%s",$1}' """\r
+ f=os.popen(cmd1)\r
+ class_name=f.readlines()[0]\r
+ name=class_name\r
+ print "classname=",class_name\r
+ f.close()\r
+\r
+ # create temporary awk files for the parsing\r
+ (fd01,p01n)=mkstemp()\r
+ f01=os.fdopen(fd01,"w")\r
+ f01.write(parse01)\r
+ f01.close()\r
+\r
+ (fd1,p1n)=mkstemp()\r
+ f1=os.fdopen(fd1,"w")\r
+ f1.write(parse1)\r
+ f1.close()\r
+\r
+ (fd2,p2n)=mkstemp()\r
+ f2=os.fdopen(fd2,"w")\r
+ f2.write(parse2)\r
+ f2.close()\r
+\r
+ (fd3,p3n)=mkstemp()\r
+ f3=os.fdopen(fd3,"w")\r
+ f3.write(parse3)\r
+ f3.close()\r
+\r
+ # awk parsing of hxx files - \r
+ # result written in file parse_type_result\r
+ cmd2 = [\r
+ "cat %s" % hxxfile,\r
+ "awk -f %s" % p01n,\r
+ "sed 's/virtual //g'",\r
+ "sed 's/MEDMEM_EXPORT//g'",\r
+ "sed 's/throw.*;/;/g'",\r
+ "awk -f %s" % p1n,\r
+ "awk -f %s" % p2n,\r
+ "awk -v class_name=%s -f %s" % (class_name, p3n) ]\r
+ cmd2 = ' | '.join(cmd2)\r
+\r
+ #os.system(cmd2)\r
+ import subprocess, sys\r
+ subprocess.call(cmd2, shell=True, stdout=sys.stdout, stderr=subprocess.STDOUT)\r
+ os.remove(p01n)\r
+ os.remove(p1n)\r
+ os.remove(p2n)\r
+ os.remove(p3n)\r
+\r
+ # Retrieve the information which was generated in \r
+ # the file parse_type_result.\r
+ # The structure of the file is :\r
+ #\r
+ # Function return_type function_name\r
+ # [arg1_type arg1_name]\r
+ # [arg2_type arg2_name]\r
+ # ...\r
+ # The service names are stored in list_of_services\r
+ # The information relative to a service (called service_name) is stored in\r
+ # the dictionnary service_definition[service_name]\r
+ list_of_services=[]\r
+ service_definition={}\r
+ result_parsing=open("parse_type_result","r")\r
+ for line in result_parsing.readlines():\r
+ line=line[0:-1] # get rid of trailing \n\r
+ words = string.split(line,';')\r
+\r
+ if len(words) >=3 and words[0] == "Function": # detect a new service\r
+ function_name=words[2]\r
+ # store the name of new service\r
+ list_of_services.append(function_name) \r
+ # create a dict to store informations relative to this service\r
+ service_definition[function_name]={} \r
+ service_definition[function_name]["ret"]=words[1] # return type\r
+ service_definition[function_name]["inports"]=[]\r
+ service_definition[function_name]["outports"]=[]\r
+ service_definition[function_name]["ports"]=[]\r
+ service_definition[function_name]["impl"]=[]\r
+\r
+ # an argument type and argument name of the current service\r
+ if len(words) == 2: \r
+ current_service=list_of_services[-1]\r
+ current_service_dict=service_definition[current_service]\r
+ typename=words[0]\r
+ argname=words[1]\r
+ # store in c++ order the arg names\r
+ current_service_dict["ports"].append( (argname,typename) ) \r
+\r
+ # separate in from out parameters\r
+ inout=cpp2idl_mapping[typename][0:2]\r
+ assert inout=="in" or inout=="ou",'Error in table cpp2idl_mapping'\r
+ if inout == "in":\r
+ current_service_dict["inports"].append((argname, typename) )\r
+ else:\r
+ current_service_dict["outports"].append((argname, typename) )\r
+ #\r
+ # For each service : \r
+ # - generate implementation of c++ servant\r
+ # - store it in service_definition[serv]["impl"]\r
+ for serv in list_of_services:\r
+ if debug:\r
+ print "service : ",serv\r
+ print " inports -> ",service_definition[serv]["inports"]\r
+ print " outports -> ",service_definition[serv]["outports"]\r
+ print " return -> ",service_definition[serv]["ret"]\r
+\r
+\r
+ # Part 1 : Argument pre-processing\r
+ s_argument_processing="//\tArguments processing\n"\r
+ for (argname,argtype) in service_definition[serv]["inports"] + \\r
+ service_definition[serv]["outports"]:\r
+ format=cpp_impl_a[argtype]\r
+ s_argument_processing += format % {"arg" : argname }\r
+\r
+ # if there was no args\r
+ if s_argument_processing=="//\tArguments processing\n": \r
+ s_argument_processing=""\r
+\r
+\r
+ # Part 2 : Call to the underlying c++ function\r
+ s_call_cpp_function="//\tCall cpp component\n\t"\r
+ rtn_type=service_definition[serv]["ret"]\r
+\r
+ # if return type is void, the call syntax is different\r
+ if rtn_type == "void" : \r
+ s_call_cpp_function += "cppCompo_->%s(" % serv\r
+ else:\r
+ s_call_cpp_function +=\\r
+ "%s _rtn_cpp = cppCompo_->%s(" % (rtn_type ,serv )\r
+\r
+ for (argname,argtype) in service_definition[serv]["ports"]:\r
+ # special treatment for some arguments\r
+ post=""\r
+ pre=""\r
+\r
+ if string.find(cpp_impl_a[argtype],"auto_ptr" ) != -1 :\r
+ # for auto_ptr argument, retrieve the raw pointer behind\r
+ post=".get()" \r
+ if argtype == "const MEDMEM::MESH&" or \\r
+ argtype == "const MEDMEM::SUPPORT&" : \r
+ # we cannot create MESHClient on the stack \r
+ # (private constructor!), \r
+ # so we create it on the heap and dereference it\r
+ pre="*" \r
+\r
+ post+="," # separator between arguments\r
+ s_call_cpp_function += " %s_%s%s" % ( pre,argname,post)\r
+ if s_call_cpp_function[-1]==',':\r
+ # get rid of trailing comma\r
+ s_call_cpp_function=s_call_cpp_function[0:-1] \r
+\r
+ s_call_cpp_function=s_call_cpp_function+');\n'\r
+\r
+ # Part 3.a : Out Argument Post-processing\r
+ s_argument_postprocessing="//\tPost-processing & return\n"\r
+ for (argname,argtype) in service_definition[serv]["outports"]:\r
+ format=cpp_impl_c[argtype]\r
+ # the treatment of %(module) is postponed in makecxx() \r
+ # because we don't know here the module name\r
+ s_argument_postprocessing += \\r
+ format % {"arg" : argname, "module" : "%(module)s" } \r
+\r
+ # Part 3.b : In Argument Post-processing\r
+ for (argname,argtype) in service_definition[serv]["inports"]:\r
+ # not all in types require a treatment\r
+ if cpp_impl_c.has_key(argtype): \r
+ format=cpp_impl_c[argtype]\r
+ # id : treatment of %(module) is postponed in makecxx\r
+ s_argument_postprocessing += \\r
+ format % {"arg" : argname, "module" : "%(module)s" } \r
+\r
+ # Part 3.c : return processing\r
+ s_rtn_processing=cpp_impl_b[rtn_type]\r
+\r
+ format_end_serv = "\tendService(\"%(class_name)s_i::%(serv_name)s\");"\r
+ format_end_serv += "\n\tEND_OF(\"%(class_name)s_i::%(serv_name)s\");\n"\r
+ s_rtn_processing += format_end_serv %\\r
+ { "serv_name" : serv, "class_name" : class_name }\r
+\r
+ if rtn_type != "void":\r
+ s_rtn_processing += "\treturn _rtn_ior;"\r
+\r
+ service_definition[serv]["impl"] = s_argument_processing + \\r
+ s_call_cpp_function + \\r
+ s_argument_postprocessing + \\r
+ s_rtn_processing\r
+ if debug:\r
+ print "implementation :\n",service_definition[serv]["impl"]\r
+\r
+ #\r
+ # Create a list of Service objects (called services), \r
+ # and give it to Component constructor\r
+ #\r
+ services=[]\r
+ self.use_medmem=False\r
+ self.use_medcoupling=False\r
+ for serv in list_of_services:\r
+ # for inports and outports, Service class expects a list of tuples, \r
+ # each tuple containing the name and the yacs type of the port\r
+ # thus we need to convert c++ types to yacs types \r
+ # (we use for that the cpp2yacs_mapping table)\r
+ inports=[]\r
+ for op in service_definition[serv]["inports"]:\r
+ inports.append([op[0], cpp2yacs_mapping[op[1]] ] )\r
+\r
+ outports = []\r
+ for op in service_definition[serv]["outports"]:\r
+ outports.append([op[0], cpp2yacs_mapping[op[1]] ] )\r
+\r
+ Return="void"\r
+ if service_definition[serv]["ret"] != "void":\r
+ Return=cpp2yacs_mapping[service_definition[serv]["ret"]]\r
+\r
+ # find out if component uses medmem types and/or medcoupling types\r
+ for (argname,argtype) in inports + outports + [("return",Return)]:\r
+ if moduleTypes[argtype]=="MED":\r
+ if argtype.count("CorbaInterface")>0:\r
+ self.use_medcoupling=True\r
+ else:\r
+ self.use_medmem=True\r
+ break\r
+\r
+ code=service_definition[serv]["impl"]\r
+ if debug:\r
+ print "service : ",serv\r
+ print " inports -> ",service_definition[serv]["inports"]\r
+ print " converted inports -> ",inports\r
+ print " outports -> ",service_definition[serv]["outports"]\r
+ print " converted outports -> ",outports\r
+ print " Return -> ",service_definition[serv]["ret"]\r
+ print " converted Return -> ",Return\r
+\r
+ services.append(Service(serv, \r
+ inport=inports, \r
+ outport=outports,\r
+ ret=Return, \r
+ defs="", \r
+ body=code,\r
+ ) )\r
+\r
+ Includes="-I${"+name+"CPP_ROOT_DIR}/include"\r
+ Libs="-L${"+name+"CPP_ROOT_DIR}/lib -l"+name+"CXX"\r
+ Compodefs=""\r
+ Inheritedclass=""\r
+ self.inheritedconstructor=""\r
+ if self.use_medmem:\r
+ Compodefs="""\r
+#include CORBA_CLIENT_HEADER(MED)\r
+#include CORBA_CLIENT_HEADER(MED_Gen)\r
+#include "FIELDClient.hxx"\r
+#include "MESHClient.hxx"\r
+#include "MEDMEM_Support_i.hxx"\r
+#include "MEDMEM_Mesh_i.hxx"\r
+#include "MEDMEM_FieldTemplate_i.hxx"\r
+#include "Med_Gen_Driver_i.hxx"\r
+"""\r
+ Inheritedclass="Med_Gen_Driver_i, public SALOMEMultiComm"\r
+ self.inheritedconstructor="Med_Gen_Driver_i(orb),"\r
+\r
+ if self.use_medcoupling:\r
+ Compodefs+="""\r
+#include CORBA_CLIENT_HEADER(MEDCouplingCorbaServant)\r
+#include CORBA_CLIENT_HEADER(MED_Gen)\r
+#include "MEDCouplingFieldDoubleServant.hxx"\r
+#include "MEDCouplingUMeshServant.hxx"\r
+#include "DataArrayDoubleServant.hxx"\r
+#include "MEDCouplingFieldDouble.hxx"\r
+#include "MEDCouplingUMesh.hxx"\r
+#include "MEDCouplingUMeshClient.hxx"\r
+#include "MEDCouplingFieldDouble.hxx"\r
+#include "MEDCouplingFieldDoubleClient.hxx"\r
+#include "MEDCouplingMemArray.hxx"\r
+#include "DataArrayDoubleClient.hxx"\r
+"""\r
+\r
+ Component.__init__(self, name, services, impl="CPP", libs=Libs,\r
+ rlibs="", includes=Includes, kind="lib",\r
+ sources=None,inheritedclass=Inheritedclass,\r
+ compodefs=Compodefs)\r
+\r
+# ------------------------------------------------------------------------------\r
+ def makeCompo(self, gen):\r
+ """generate files for C++ component\r
+ return a dict where key is the file name and \r
+ value is the content of the file\r
+ """\r
+ cxxfile = "%s_i.cxx" % self.name\r
+ hxxfile = "%s_i.hxx" % self.name\r
+ return {"Makefile.am":gen.makeMakefile(self.getMakefileItems(gen)),\r
+ cxxfile:self.makecxx(gen),\r
+ hxxfile:self.makehxx(gen)\r
+ }\r
+\r
+# ------------------------------------------------------------------------------\r
+ def getMakefileItems(self,gen):\r
+ makefileItems={"header":"""\r
+include $(top_srcdir)/adm_local/make_common_starter.am\r
+\r
+"""}\r
+ makefileItems["lib_LTLIBRARIES"]=["lib"+self.name+"Engine.la"]\r
+ makefileItems["salomeinclude_HEADERS"]=["%s_i.hxx" % self.name]\r
+ makefileItems["body"]=compoMakefile.substitute(module=gen.module.name,\r
+ component=self.name,\r
+ libs=self.libs,\r
+ includes=self.includes)\r
+ return makefileItems\r
+\r
+# ------------------------------------------------------------------------------\r
+ def makehxx(self, gen):\r
+ """return a string that is the content of .hxx file\r
+ """\r
+ services = []\r
+ for serv in self.services:\r
+ service = " %s %s(" % (corba_rtn_type(serv.ret,gen.module.name),\r
+ serv.name)\r
+ service = service+gen.makeArgs(serv)+") throw (SALOME::SALOME_Exception);"\r
+ services.append(service)\r
+ servicesdef = "\n".join(services)\r
+\r
+ inheritedclass=self.inheritedclass\r
+ if self.inheritedclass:\r
+ inheritedclass= " public virtual " + self.inheritedclass + ","\r
+\r
+ return hxxCompo.substitute(component=self.name, \r
+ module=gen.module.name,\r
+ servicesdef=servicesdef, \r
+ inheritedclass=inheritedclass,\r
+ compodefs=self.compodefs)\r
+\r
+# ------------------------------------------------------------------------------\r
+ def makecxx(self, gen, exe=0):\r
+ """return a string that is the content of .cxx file\r
+ """\r
+ services = []\r
+ inits = []\r
+ defs = []\r
+ for serv in self.services:\r
+ defs.append(serv.defs)\r
+ print "CNC bug : ",serv.body\r
+ service = cxxService.substitute(\r
+ component=self.name, \r
+ service=serv.name,\r
+ ret=corba_rtn_type(serv.ret,gen.module.name),\r
+ parameters=gen.makeArgs(serv),\r
+ body=serv.body % {"module":gen.module.name+"_ORB"} )\r
+ services.append(service)\r
+ return cxxCompo.substitute(component=self.name, \r
+ inheritedconstructor=self.inheritedconstructor,\r
+ servicesdef="\n".join(defs),\r
+ servicesimpl="\n".join(services))\r
+\r
+# ------------------------------------------------------------------------------\r
+ def getGUIfilesTemplate(self):\r
+ """generate in a temporary directory files for a generic GUI, \r
+ and return a list with file names.\r
+ it is the responsability of the user to get rid \r
+ of the temporary directory when finished\r
+ """\r
+ gui_cxx=hxxgui_cxx.substitute(component_name=self.name)\r
+ gui_h=hxxgui_h.substitute(component_name=self.name)\r
+ gui_icon_ts=hxxgui_icon_ts.substitute(component_name=self.name)\r
+ gui_message_en=hxxgui_message_en.substitute(component_name=self.name)\r
+ gui_message_fr=hxxgui_message_fr.substitute(component_name=self.name)\r
+ gui_config=hxxgui_config.substitute(component_name=self.name)\r
+ gui_xml_fr=hxxgui_xml_fr.substitute(component_name=self.name)\r
+ gui_xml_en=hxxgui_xml_en.substitute(component_name=self.name)\r
+ gui_salomeapp_gen=cppsalomeapp.substitute(module=self.name,lmodule=self.name.lower())\r
+ # for a salome component generated by hxx2salome from a c++ component, the documentation points at the c++ component documentation\r
+ salome_doc_path=os.path.join("%"+self.name+"_ROOT_DIR%","share","doc","salome","gui",self.name.lower(),"index.html")\r
+ cpp_doc_path=os.path.join("%"+self.name+"CPP_ROOT_DIR%","share","doc",self.name,"index.html")\r
+ gui_salomeapp=gui_salomeapp_gen.replace(salome_doc_path,cpp_doc_path)\r
+ temp_dir=mkdtemp()\r
+ gui_cxx_file_name=os.path.join(temp_dir,self.name+"GUI.cxx")\r
+ gui_h_file_name=os.path.join(temp_dir,self.name+"GUI.h")\r
+ gui_icon_ts_file_name=os.path.join(temp_dir,self.name+"_icons.ts")\r
+ gui_message_en_file_name=os.path.join(temp_dir,self.name+"_msg_en.ts")\r
+ gui_message_fr_file_name=os.path.join(temp_dir,self.name+"_msg_fr.ts")\r
+ gui_config_file_name=os.path.join(temp_dir,"config")\r
+ gui_xml_fr_file_name=os.path.join(temp_dir,self.name+"_en.xml")\r
+ gui_xml_en_file_name=os.path.join(temp_dir,self.name+"_fr.xml")\r
+ gui_salomeapp_file_name=os.path.join(temp_dir,"SalomeApp.xml")\r
+ list_of_gui_names=[]\r
+\r
+ gui_cxx_file=open(gui_cxx_file_name,"w")\r
+ gui_cxx_file.write(gui_cxx)\r
+ gui_cxx_file.close()\r
+ list_of_gui_names.append(gui_cxx_file_name)\r
+\r
+ gui_h_file=open(gui_h_file_name,"w")\r
+ gui_h_file.write(gui_h)\r
+ gui_h_file.close()\r
+ list_of_gui_names.append(gui_h_file_name)\r
+\r
+ gui_icon_ts_file=open(gui_icon_ts_file_name,"w")\r
+ gui_icon_ts_file.write(gui_icon_ts)\r
+ gui_icon_ts_file.close()\r
+ list_of_gui_names.append(gui_icon_ts_file_name)\r
+\r
+ gui_message_en_file=open(gui_message_en_file_name,"w")\r
+ gui_message_en_file.write(gui_message_en)\r
+ gui_message_en_file.close()\r
+ list_of_gui_names.append(gui_message_en_file_name)\r
+\r
+ gui_message_fr_file=open(gui_message_fr_file_name,"w")\r
+ gui_message_fr_file.write(gui_message_fr)\r
+ gui_message_fr_file.close()\r
+ list_of_gui_names.append(gui_message_fr_file_name)\r
+\r
+ gui_config_file=open(gui_config_file_name,"w")\r
+ gui_config_file.write(gui_config)\r
+ gui_config_file.close()\r
+ list_of_gui_names.append(gui_config_file_name)\r
+\r
+ gui_xml_fr_file=open(gui_xml_fr_file_name,"w")\r
+ gui_xml_fr_file.write(gui_xml_fr)\r
+ gui_xml_fr_file.close()\r
+ list_of_gui_names.append(gui_xml_fr_file_name)\r
+\r
+ gui_xml_en_file=open(gui_xml_en_file_name,"w")\r
+ gui_xml_en_file.write(gui_xml_en)\r
+ gui_xml_en_file.close()\r
+ list_of_gui_names.append(gui_xml_en_file_name)\r
+\r
+ gui_salomeapp_file=open(gui_salomeapp_file_name,"w")\r
+ gui_salomeapp_file.write(gui_salomeapp)\r
+ gui_salomeapp_file.close()\r
+ list_of_gui_names.append(gui_salomeapp_file_name)\r
+\r
+\r
+ return list_of_gui_names\r