Salome HOME
Copyright update 2021
[modules/yacs.git] / src / wrappergen / src / hxx2salome
1 #! /bin/bash
2 # Copyright (C) 2006-2021  CEA/DEN, EDF R&D
3 #
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.
8 #
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.
13 #
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
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 BE_QUIET=0
22 # salome2 environment file (.bash or .sh) - can also be specified with -e option
23 ENVIRON_FILE=
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!
27 #
28 # options you want to pass to configure
29 CONFIGURE_OPTION=
30 #
31 # which wrappers to generate
32 declare -a GEN
33
34 iCPP=0
35 iCORBA=1
36 iPython=2
37
38 GEN[${iCPP}]="no"
39 GEN[${iCORBA}]="no"
40 GEN[${iPython}]="no"
41
42
43 #
44 usage()
45 {
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"
59     echo -e "  Options :"
60     echo -e "    -h                    : this help"
61     echo
62     echo -e "    -q                    : be quiet"
63     echo
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"
69     echo
70
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"
77     echo -e "                            before)"
78     echo
79     echo -e "    -s script_extension   : to use if your environment file name doesn't"
80     echo -e "                            have extension"
81     echo
82     echo -e "    -g                    : to create a gui part in your component"
83     echo -e "                            building tree"
84     echo
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" 
90     echo
91     echo -e "    -l                    : to launch salome "
92     exit
93 }
94 #
95 welcome()
96 {
97     echo -e "\n\n"
98     echo  "----------------------------------------------------------------------------"
99     echo
100     echo  "                              hxx2salome"
101     echo
102     echo  "     Automatic generation of a Salome2 component from a C++ component"
103     echo 
104     echo  "----------------------------------------------------------------------------"
105     echo 
106     echo 
107     echo 
108 }
109
110 if [ "x$HXX2SALOME_ROOT_DIR" == "x" ] 
111 then
112     usage
113 fi
114
115 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_check
116 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_corba
117 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_cpp
118
119
120 # retrieve python test file ending up with _test.py
121 get_python_test_file()
122 {
123     cd ${CPP_ROOT_DIR}
124     for file in `find . -name "*_test.py"`
125     do
126        cp $file ${tmp_dir}/${CLASS_NAME}_SRC/src/${CLASS_NAME}
127        python_test_file=${python_test_file}" "`basename $file`
128     done
129     if [ ${BE_QUIET} -lt 1 ] ; then
130         echo -e "\nList of exported python file test : $python_test_file \n"
131     fi
132     cd -
133 }
134
135 create_component_tree()
136 {
137     INSTALL_DIR=${salomeComponentRoot}/${CLASS_NAME}
138
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
142
143     \rm -rf ${NEW_COMPONENT_SRC_DIR}
144     mkdir -p ${NEW_COMPONENT_SRC_DIR}
145 }
146
147
148 get_info_makefile()
149 {
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}}"
152     
153     if [ ${BE_QUIET} -lt 1 ] ; then
154        echo -e "\nlinking option : $makefile_lib"
155        echo -e "include option : $makefile_include"
156     fi
157 }
158
159
160 generate_module_source()
161 {
162
163 #
164 # go in temporary directory to work on code generation
165     cd ${tmp_dir}
166 #
167 #
168 # -------------------------  parse hxx file : generic part  ---------------------------------------
169 #
170     cat ${hxx_file} | \
171     awk -f ${gene_dir}/parse01.awk | \
172     awk -f ${gene_dir}/parse1.awk  | \
173     awk -f ${gene_dir}/parse2.awk  \
174          > temp
175     sed -e "/${CLASS_NAME}/d" < temp > ${CLASS_NAME}_public_functions
176     
177     if [ ${BE_QUIET} -lt 1 ] ; then
178        echo -e "\n-> Extract public functions\n"
179     fi
180     if [ ! -s ${CLASS_NAME}_public_functions ]
181     then
182     echo -e "\nError:"
183     echo -e "  Sorry - No compatible function was found!"
184     echo -e "  Please check your header file\n"
185     exit
186     fi
187
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
191
192     \rm -f hxx2salome_journal && touch hxx2salome_journal
193
194     if [ ${BE_QUIET} -lt 1 ] ; then
195        echo -e "\n-> Duplicate template module" | tee ../hxx2salome_journal
196     fi
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
201
202     GEN=( `validate_generation_choices ${GEN[${iCPP}]} ${GEN[${iCORBA}]} ${GEN[${iPython}]}` )
203     echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]}  CORBA : ${GEN[${iCORBA}]}  Python : ${GEN[${iPython}]}
204     
205     if [ "x${GEN[${iCORBA}]}" == "xyes" ] ; then
206         generate_corba_module_source
207     else
208         clean_corba_module_source
209     fi
210
211     if [ "x${GEN[${iCPP}]}" == "xyes" ] ; then
212         generate_cpp_module_source
213     else
214          clean_cpp_module_source
215     fi
216 }
217
218 compile()
219 {
220     echo "----------------- Configure -------------------"
221     
222     echo "----------------- Compile ---------------------"
223     make 
224     if [ $? -eq 0 ]
225     then
226     # compilation succeeded : we make install
227     echo
228     echo "----------------- Install ---------------------"
229     make install
230     else
231         exit 1
232     fi
233 }
234
235 update_environment()
236 {
237     if [ -z ${ENVIRON_FILE} ]
238     then
239     ENVIRON_FILE="${NEW_COMPONENT_SRC_DIR}/env_${CLASS_NAME}.${SHELL_EXT}"
240     fi
241
242     if [ ${BE_QUIET} -lt 1 ] ; then
243        echo -e "\nEnvironment file : " $ENVIRON_FILE
244     fi
245     if [ -e ${ENVIRON_FILE} ]
246     then
247     cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old
248     fi
249     touch ${ENVIRON_FILE}
250
251     if [ "${SHELL_EXT}" == "csh" ]
252     then
253     grep -q " ${CLASS_NAME}_SRC_DIR" ${ENVIRON_FILE}
254     res=$?
255     if [ $res == 1 ]
256     then
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}
260     fi
261     
262     grep -q " ${CLASS_NAME}_ROOT_DIR" ${ENVIRON_FILE}
263     res=$?
264     if [ $res == 1 ]
265     then
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}
270     fi
271     fi
272     if [ "${SHELL_EXT}" == "sh" ]
273     then
274     grep -q " ${CLASS_NAME}_SRC_DIR=" ${ENVIRON_FILE}
275     res=$?
276     if [ $res == 1 ]
277     then
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}
281     fi
282     
283     grep -q " ${CLASS_NAME}_ROOT_DIR=" ${ENVIRON_FILE}
284     res=$?
285     if [ $res == 1 ]
286     then
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}" \
291         >> ${ENVIRON_FILE}
292     fi
293     
294     fi
295 }
296
297 copy_component_source()
298 {
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}
302 }
303
304 good_bye()
305 {
306     
307     if [ ${BE_QUIET} -gt 0 ] ; then
308        return
309     fi
310     echo -e "\n\nModule was created in ${NEW_COMPONENT_SRC_DIR}"
311 }
312
313
314 #
315 #
316 # ------------------------------------------------------------------------
317 # --------------------------- MAIN PROGRAM -------------------------------
318 # ------------------------------------------------------------------------
319 #
320 CPP_ROOT_DIR=
321 NEW_COMPONENT_ROOT_DIR=
322 NEW_COMPONENT_SRC_DIR=
323 NEW_COMPONENT_BUILD_DIR=
324 SHELL_EXT=sh
325 do_compile=0
326 do_launch=0
327
328 make_gui=0
329
330 #
331 welcome # print some welcome info
332 #
333 while getopts "qcs:e:h:lgx:" Option
334 do
335    case $Option in
336      h) usage
337         exit;;
338      q) BE_QUIET=$[ ${BE_QUIET}+1 ] ;;
339      e) ENVIRON_FILE=$OPTARG;;
340      s) case $OPTARG in
341         bash) SHELL_EXT=sh;;
342         csh)  SHELL_EXT=csh;;      
343         *)    SHELL_EXT=sh;;
344     esac;;
345      g) make_gui=1;;
346      c) do_compile=1;;
347      l) do_launch=1;;
348      x) case $OPTARG in
349             CORBA) GEN[$iCORBA]="yes" ;;
350             python) GEN[$iPython]="yes" ;;
351             C++) GEN[${iCPP}]="yes";;
352             *)   ;;
353         esac;;
354      *) echo "Unimplemented option chosen : $Option."
355         usage
356         exit;;   # DEFAULT
357    esac
358 done
359
360 shift $(($OPTIND - 1))
361
362 # default behaviour is to generate all wrappers
363 #
364 if [ "x${GEN[${iCPP}]}${GEN[${iCORBA}]}${GEN[${iPython}]}" == "xnonono" ] ;  then
365     for i in ${iCPP} ${iCORBA} ${iPython}
366       do
367       GEN[$i]="yes"
368     done
369 fi
370 echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]}  CORBA : ${GEN[${iCORBA}]}  Python : ${GEN[${iPython}]}
371 echo
372 echo
373
374 # check number of other arguments
375 #
376 if [ $# -ne 4 ]
377 then
378    echo -e "\nBad number of arguments\n\n"
379    usage
380    exit
381 fi
382
383 check_arguments $1 $2 $3 $4
384
385 # if there is a sh compatible environment file, source it
386 if [[ -n ${ENVIRON_FILE} && -f ${ENVIRON_FILE} ]]
387 then
388    # analyse extension of environment file
389    case ${ENVIRON_FILE##*\.} in 
390        bash) SHELL_EXT=sh;;
391        ksh)  SHELL_EXT=sh;;
392        csh)  SHELL_EXT=csh;;
393        sh)   SHELL_EXT=sh;;
394    esac
395 fi
396
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} ]
402 then
403    echo -e "\n    Environment file with sh syntax specified => we source ${ENVIRON_FILE}"
404    source ${ENVIRON_FILE}
405 fi
406
407 #
408 if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ]
409 then
410     gene_dir=${HXX2SALOME_ROOT_DIR}
411 else
412     gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory
413 fi
414 OLD_DIR=`pwd`
415 cd $gene_dir
416 gene_dir=`pwd`
417 cd $OLD_DIR
418
419 if [ ${BE_QUIET} -lt 1 ] ; then
420    echo "    hxx2salome directory : $gene_dir"
421 fi
422 if [ ! -f ${gene_dir}/parse1.awk -o ! -f ${gene_dir}/parse2.awk ] # check if script are found
423 then
424     echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy from bin directory"
425     usage
426 fi
427 #
428 # get class name
429 #
430 CLASS_NAME=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}|awk -F: '{print $1}'`
431 echo "    Name of class :" $CLASS_NAME
432 if [ ! $CLASS_NAME ]
433 then
434     echo -e "\nError:\n  Sorry - No class definition was found!\n  Please check your header file\n"
435     exit
436 fi
437
438 #
439 # create temporary working directory
440 #
441 tmp_dir="/tmp/${USER}/${CLASS_NAME}"
442 if [ -d ${tmp_dir} ]
443 then
444     rm -rf ${tmp_dir}/*
445 else
446     mkdir -p ${tmp_dir}
447 fi
448
449 #
450 # ---------------------  Generation of module source from template ------------------------------------------
451 #
452 get_info_makefile
453 generate_module_source
454
455 #
456 # ---------------------- Installation of new module sources  ------------------------------------------------
457 #
458 create_component_tree
459
460 #
461 # ---------------------- Modification of Salome environment file  -------------------------------------------
462 #
463 update_environment
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
466 #
467 # ---------------------- Copy the generated source from temp dir  -------------------------------------------
468 #
469 copy_component_source
470
471 good_bye
472
473
474 echo -e "\nGeneration done\n"