2 # Copyright (C) 2006-2022 CEA/DEN, EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 # salome2 environment file (.bash or .sh) - can also be specified with -e option
24 # if present, hxx2salome will try to compile new module, by sourcing ENVIRON_FILE file, and executing
25 # build_configure, configure, make & make install
26 # remark : hxx2salome has to be lanched with clean PATH, LD_LIBRARY_PATH & PYTHONPATH variables!
28 # options you want to pass to configure
31 # which wrappers to generate
46 echo -e "\n Usage :\n"
47 echo -e " Set HXX2SALOME_ROOT_DIR variable"
48 echo -e " ${HXX2SALOME_ROOT_DIR}/hxx2salome [options] "
49 echo -e " cppComponent_root_dir cppComponent.hxx"
50 echo -e " libcppComponent.so salomeComponentRoot\n"
51 echo -e " - cppComponent_root_dir : install directory (absolute path)"
52 echo -e " of the c++ component\n"
53 echo -e " - cppComponent.hxx : header of the component"
54 echo -e " - libcppComponent.so : library\n"
55 echo -e " (cppComponent.hxx and libcppComponent.so have to be found"
56 echo -e " in cppComponent_root_dir)\n"
57 echo -e " - salomeComponentRoot : directory of the source/build/install"
58 echo -e " of the Salome component\n"
60 echo -e " -h : this help"
62 echo -e " -q : be quiet"
64 echo -e " -x Lang : generate a wrapper to use the component"
65 echo -e " from language Lang where Lang can be "
66 echo -e " any of CORBA,C++,python"
67 echo -e " (several -x options can be specified)"
68 echo -e " default : generate all wrappers"
71 echo -e " -e environment_script : to specify the name of a environment file"
72 echo -e " that will be updated with new necessary commands"
73 echo -e " (this file is also used for sourcing environment"
74 echo -e " before compilation if it has sh or bash syntax,"
75 echo -e " if the syntax is csh, it is not sourced and for"
76 echo -e " compiling (-c option) environment must be set up"
79 echo -e " -s script_extension : to use if your environment file name doesn't"
80 echo -e " have extension"
82 echo -e " -g : to create a gui part in your component"
83 echo -e " building tree"
85 echo -e " -c : to compile after generation"
86 echo -e " (use this option only if you don't have"
87 echo -e " dependencies in your header or libraries"
88 echo -e " if it is the case, you'll have to adapt"
89 echo -e " your Makefile.am"
91 echo -e " -l : to launch salome "
98 echo "----------------------------------------------------------------------------"
102 echo " Automatic generation of a Salome2 component from a C++ component"
104 echo "----------------------------------------------------------------------------"
110 if [ "x$HXX2SALOME_ROOT_DIR" == "x" ]
115 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_check
116 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_corba
117 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_cpp
120 # retrieve python test file ending up with _test.py
121 get_python_test_file()
124 for file in `find . -name "*_test.py"`
126 cp $file ${tmp_dir}/${CLASS_NAME}_SRC/src/${CLASS_NAME}
127 python_test_file=${python_test_file}" "`basename $file`
129 if [ ${BE_QUIET} -lt 1 ] ; then
130 echo -e "\nList of exported python file test : $python_test_file \n"
135 create_component_tree()
137 INSTALL_DIR=${salomeComponentRoot}/${CLASS_NAME}
139 export NEW_COMPONENT_SRC_DIR=${INSTALL_DIR}/${CLASS_NAME}_SRC
140 export NEW_COMPONENT_BUILD_DIR=${INSTALL_DIR}/${CLASS_NAME}_BUILD
141 export NEW_COMPONENT_ROOT_DIR=${INSTALL_DIR}/${CLASS_NAME}_INSTALL
143 \rm -rf ${NEW_COMPONENT_SRC_DIR}
144 mkdir -p ${NEW_COMPONENT_SRC_DIR}
150 makefile_lib="-L\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}} -l${lib_file}"
151 makefile_include="-I\${${CLASS_NAME}CPP_ROOT_DIR}${hxx_dir#${CPP_ROOT_DIR}}"
153 if [ ${BE_QUIET} -lt 1 ] ; then
154 echo -e "\nlinking option : $makefile_lib"
155 echo -e "include option : $makefile_include"
160 generate_module_source()
164 # go in temporary directory to work on code generation
168 # ------------------------- parse hxx file : generic part ---------------------------------------
171 awk -f ${gene_dir}/parse01.awk | \
172 awk -f ${gene_dir}/parse1.awk | \
173 awk -f ${gene_dir}/parse2.awk \
175 sed -e "/${CLASS_NAME}/d" < temp > ${CLASS_NAME}_public_functions
177 if [ ${BE_QUIET} -lt 1 ] ; then
178 echo -e "\n-> Extract public functions\n"
180 if [ ! -s ${CLASS_NAME}_public_functions ]
183 echo -e " Sorry - No compatible function was found!"
184 echo -e " Please check your header file\n"
188 echo -e "\n\n-> Compatibility function\n"
189 cat ${CLASS_NAME}_public_functions | \
190 awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse30.awk
192 \rm -f hxx2salome_journal && touch hxx2salome_journal
194 if [ ${BE_QUIET} -lt 1 ] ; then
195 echo -e "\n-> Duplicate template module" | tee ../hxx2salome_journal
197 cp -rf ${gene_dir}/HXX2SALOME_GENERIC_CLASS_NAME_SRC ${CLASS_NAME}_SRC
198 cp -f ${gene_dir}/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh compile_${CLASS_NAME}.sh
199 ${gene_dir}/renameSalomeModule -i HXX2SALOME_GENERIC_CLASS_NAME \
200 ${CLASS_NAME} ${CLASS_NAME}_SRC >> ../hxx2salome_journal
202 GEN=( `validate_generation_choices ${GEN[${iCPP}]} ${GEN[${iCORBA}]} ${GEN[${iPython}]}` )
203 echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]} CORBA : ${GEN[${iCORBA}]} Python : ${GEN[${iPython}]}
205 if [ "x${GEN[${iCORBA}]}" == "xyes" ] ; then
206 generate_corba_module_source
208 clean_corba_module_source
211 if [ "x${GEN[${iCPP}]}" == "xyes" ] ; then
212 generate_cpp_module_source
214 clean_cpp_module_source
220 echo "----------------- Configure -------------------"
222 echo "----------------- Compile ---------------------"
226 # compilation succeeded : we make install
228 echo "----------------- Install ---------------------"
237 if [ -z ${ENVIRON_FILE} ]
239 ENVIRON_FILE="${NEW_COMPONENT_SRC_DIR}/env_${CLASS_NAME}.${SHELL_EXT}"
242 if [ ${BE_QUIET} -lt 1 ] ; then
243 echo -e "\nEnvironment file : " $ENVIRON_FILE
245 if [ -e ${ENVIRON_FILE} ]
247 cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old
249 touch ${ENVIRON_FILE}
251 if [ "${SHELL_EXT}" == "csh" ]
253 grep -q " ${CLASS_NAME}_SRC_DIR" ${ENVIRON_FILE}
257 echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE}
258 echo -e "setenv ${CLASS_NAME}_BASE ${INSTALL_DIR}" >> ${ENVIRON_FILE}
259 echo -e "setenv ${CLASS_NAME}_SRC_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE}
262 grep -q " ${CLASS_NAME}_ROOT_DIR" ${ENVIRON_FILE}
266 echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE}
267 echo -e "setenv ${CLASS_NAME}_ROOT_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE}
268 echo -e "setenv ${CLASS_NAME}CPP_ROOT_DIR ${CPP_ROOT_DIR}" >> ${ENVIRON_FILE}
269 echo -e "setenv LD_LIBRARY_PATH \${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE}
272 if [ "${SHELL_EXT}" == "sh" ]
274 grep -q " ${CLASS_NAME}_SRC_DIR=" ${ENVIRON_FILE}
278 echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE}
279 echo -e "export ${CLASS_NAME}_BASE=${INSTALL_DIR}" >> ${ENVIRON_FILE}
280 echo -e "export ${CLASS_NAME}_SRC_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE}
283 grep -q " ${CLASS_NAME}_ROOT_DIR=" ${ENVIRON_FILE}
287 echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE}
288 echo -e "export ${CLASS_NAME}_ROOT_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE}
289 echo -e "export ${CLASS_NAME}CPP_ROOT_DIR=${CPP_ROOT_DIR}" >> ${ENVIRON_FILE}
290 echo -e "export LD_LIBRARY_PATH=\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" \
297 copy_component_source()
299 mv ${tmp_dir}/${CLASS_NAME}_SRC/* ${NEW_COMPONENT_SRC_DIR}
300 mkdir -p ${NEW_COMPONENT_BUILD_DIR}
301 mkdir -p ${NEW_COMPONENT_ROOT_DIR}
307 if [ ${BE_QUIET} -gt 0 ] ; then
310 echo -e "\n\nModule was created in ${NEW_COMPONENT_SRC_DIR}"
316 # ------------------------------------------------------------------------
317 # --------------------------- MAIN PROGRAM -------------------------------
318 # ------------------------------------------------------------------------
321 NEW_COMPONENT_ROOT_DIR=
322 NEW_COMPONENT_SRC_DIR=
323 NEW_COMPONENT_BUILD_DIR=
331 welcome # print some welcome info
333 while getopts "qcs:e:h:lgx:" Option
338 q) BE_QUIET=$[ ${BE_QUIET}+1 ] ;;
339 e) ENVIRON_FILE=$OPTARG;;
349 CORBA) GEN[$iCORBA]="yes" ;;
350 python) GEN[$iPython]="yes" ;;
351 C++) GEN[${iCPP}]="yes";;
354 *) echo "Unimplemented option chosen : $Option."
360 shift $(($OPTIND - 1))
362 # default behaviour is to generate all wrappers
364 if [ "x${GEN[${iCPP}]}${GEN[${iCORBA}]}${GEN[${iPython}]}" == "xnonono" ] ; then
365 for i in ${iCPP} ${iCORBA} ${iPython}
370 echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]} CORBA : ${GEN[${iCORBA}]} Python : ${GEN[${iPython}]}
374 # check number of other arguments
378 echo -e "\nBad number of arguments\n\n"
383 check_arguments $1 $2 $3 $4
385 # if there is a sh compatible environment file, source it
386 if [[ -n ${ENVIRON_FILE} && -f ${ENVIRON_FILE} ]]
388 # analyse extension of environment file
389 case ${ENVIRON_FILE##*\.} in
397 # Environment policy :
398 # - an existing sh file was specified : we source environment file
399 # - else (no file or csh syntax) : we don't source environment file, and do compile
400 # only if KERNEL_ROOT_DIR and MED_ROOT_DIR are defined
401 if [ "${SHELL_EXT}" == "sh" ] && [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ]
403 echo -e "\n Environment file with sh syntax specified => we source ${ENVIRON_FILE}"
404 source ${ENVIRON_FILE}
408 if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ]
410 gene_dir=${HXX2SALOME_ROOT_DIR}
412 gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory
419 if [ ${BE_QUIET} -lt 1 ] ; then
420 echo " hxx2salome directory : $gene_dir"
422 if [ ! -f ${gene_dir}/parse1.awk -o ! -f ${gene_dir}/parse2.awk ] # check if script are found
424 echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy from bin directory"
430 CLASS_NAME=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}|awk -F: '{print $1}'`
431 echo " Name of class :" $CLASS_NAME
434 echo -e "\nError:\n Sorry - No class definition was found!\n Please check your header file\n"
439 # create temporary working directory
441 tmp_dir="/tmp/${USER}/${CLASS_NAME}"
450 # --------------------- Generation of module source from template ------------------------------------------
453 generate_module_source
456 # ---------------------- Installation of new module sources ------------------------------------------------
458 create_component_tree
461 # ---------------------- Modification of Salome environment file -------------------------------------------
464 export `echo ${CLASS_NAME}`_ROOT_DIR=${NEW_COMPONENT_ROOT_DIR} # to avoid resource env for compiling and launching salome
465 export `echo ${CLASS_NAME}`CPP_ROOT_DIR=${CPP_ROOT_DIR} # idem
467 # ---------------------- Copy the generated source from temp dir -------------------------------------------
469 copy_component_source
474 echo -e "\nGeneration done\n"