]> SALOME platform Git repositories - modules/yacs.git/blob - src/wrappergen/src/hxx2salome
Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / wrappergen / src / hxx2salome
1 #! /bin/bash
2 #  Copyright (C) 2006-2008  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.
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 #
22 BE_QUIET=0
23 # salome2 environment file (.bash or .sh) - can also be specified with -e option
24 ENVIRON_FILE=
25 # if present, hxx2salome will try to compile new module, by sourcing ENVIRON_FILE file, and executing
26 # build_configure, configure, make & make install
27 # remark : hxx2salome has to be lanched with clean PATH, LD_LIBRARY_PATH & PYTHONPATH variables!
28 #
29 # options you want to pass to configure
30 CONFIGURE_OPTION=
31 #
32 # which wrappers to generate
33 declare -a GEN
34
35 iCPP=0
36 iCORBA=1
37 iPython=2
38
39 GEN[${iCPP}]="no"
40 GEN[${iCORBA}]="no"
41 GEN[${iPython}]="no"
42
43
44 #
45 usage()
46 {
47     echo -e "\n  Usage :\n"
48     echo -e "  Set HXX2SALOME_ROOT_DIR variable"
49     echo -e "  ${HXX2SALOME_ROOT_DIR}/hxx2salome [options] "
50     echo -e "             cppComponent_root_dir cppComponent.hxx"
51     echo -e "             libcppComponent.so salomeComponentRoot\n"
52     echo -e "     - cppComponent_root_dir : install directory (absolute path)"
53     echo -e "                               of the c++ component\n"
54     echo -e "     - cppComponent.hxx      : header of the component"
55     echo -e "     - libcppComponent.so    : library\n"
56     echo -e "       (cppComponent.hxx and libcppComponent.so have to be found"
57     echo -e "        in cppComponent_root_dir)\n"
58     echo -e "     - salomeComponentRoot   : directory of the source/build/install"
59     echo -e "                               of the Salome component\n"
60     echo -e "  Options :"
61     echo -e "    -h                    : this help"
62     echo
63     echo -e "    -q                    : be quiet"
64     echo
65     echo -e "    -x Lang               : generate a wrapper to use the component"
66     echo -e "                            from language Lang where Lang can be "
67     echo -e "                            any of CORBA,C++,python"
68     echo -e "                            (several -x options can be specified)"
69     echo -e "                            default : generate all wrappers"
70     echo
71
72     echo -e "    -e environment_script : to specify the name of a environment file"
73     echo -e "                            that will be updated with new necessary commands"
74     echo -e "                            (this file is also used for sourcing environment"
75     echo -e "                            before compilation if it has sh or bash syntax,"
76     echo -e "                            if the syntax is csh, it is not sourced and for"
77     echo -e "                            compiling (-c option) environment must be set up"
78     echo -e "                            before)"
79     echo
80     echo -e "    -s script_extension   : to use if your environment file name doesn't"
81     echo -e "                            have extension"
82     echo
83     echo -e "    -g                    : to create a gui part in your component"
84     echo -e "                            building tree"
85     echo
86     echo -e "    -c                    : to compile after generation"
87     echo -e "                            (use this option only if you don't have"
88     echo -e "                            dependencies in your header or libraries"
89     echo -e "                            if it is the case, you'll have to adapt"
90     echo -e "                            your Makefile.am" 
91     echo
92     echo -e "    -l                    : to launch salome "
93     exit
94 }
95 #
96 welcome()
97 {
98     echo -e "\n\n"
99     echo  "----------------------------------------------------------------------------"
100     echo
101     echo  "                              hxx2salome"
102     echo
103     echo  "     Automatic generation of a Salome2 component from a C++ component"
104     echo 
105     echo  "----------------------------------------------------------------------------"
106     echo 
107     echo 
108     echo 
109 }
110
111 if [ "x$HXX2SALOME_ROOT_DIR" == "x" ] 
112 then
113     usage
114 fi
115
116 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_check
117 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_corba
118 source ${HXX2SALOME_ROOT_DIR}/hxx2salome_cpp
119
120
121 # retrieve python test file ending up with _test.py
122 get_python_test_file()
123 {
124     cd ${CPP_ROOT_DIR}
125     for file in `find . -name "*_test.py"`
126     do
127        cp $file ${tmp_dir}/${CLASS_NAME}_SRC/src/${CLASS_NAME}
128        python_test_file=${python_test_file}" "`basename $file`
129     done
130     if [ ${BE_QUIET} -lt 1 ] ; then
131         echo -e "\nList of exported python file test : $python_test_file \n"
132     fi
133     cd -
134 }
135
136 create_component_tree()
137 {
138     INSTALL_DIR=${salomeComponentRoot}/${CLASS_NAME}
139
140     export NEW_COMPONENT_SRC_DIR=${INSTALL_DIR}/${CLASS_NAME}_SRC
141     export NEW_COMPONENT_BUILD_DIR=${INSTALL_DIR}/${CLASS_NAME}_BUILD
142     export NEW_COMPONENT_ROOT_DIR=${INSTALL_DIR}/${CLASS_NAME}_INSTALL
143
144     \rm -rf ${NEW_COMPONENT_SRC_DIR}
145     mkdir -p ${NEW_COMPONENT_SRC_DIR}
146 }
147
148
149 get_info_makefile()
150 {
151     makefile_lib="-L\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}} -l${lib_file}"
152     makefile_include="-I\${${CLASS_NAME}CPP_ROOT_DIR}${hxx_dir#${CPP_ROOT_DIR}}"
153     
154     if [ ${BE_QUIET} -lt 1 ] ; then
155        echo -e "\nlinking option : $makefile_lib"
156        echo -e "include option : $makefile_include"
157     fi
158 }
159
160
161 generate_module_source()
162 {
163
164 #
165 # go in temporary directory to work on code generation
166     cd ${tmp_dir}
167 #
168 #
169 # -------------------------  parse hxx file : generic part  ---------------------------------------
170 #
171     cat ${hxx_file} | \
172     awk -f ${gene_dir}/parse01.awk | \
173     awk -f ${gene_dir}/parse1.awk  | \
174     awk -f ${gene_dir}/parse2.awk  \
175          > temp
176     sed -e "/${CLASS_NAME}/d" < temp > ${CLASS_NAME}_public_functions
177     
178     if [ ${BE_QUIET} -lt 1 ] ; then
179        echo -e "\n-> Extract public functions\n"
180     fi
181     if [ ! -s ${CLASS_NAME}_public_functions ]
182     then
183     echo -e "\nError:"
184     echo -e "  Sorry - No compatible function was found!"
185     echo -e "  Please check your header file\n"
186     exit
187     fi
188
189     echo -e "\n\n-> Compatibility      function\n"
190     cat ${CLASS_NAME}_public_functions | \
191     awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse30.awk
192
193     \rm -f hxx2salome_journal && touch hxx2salome_journal
194
195     if [ ${BE_QUIET} -lt 1 ] ; then
196        echo -e "\n-> Duplicate template module" | tee ../hxx2salome_journal
197     fi
198     cp -rf ${gene_dir}/HXX2SALOME_GENERIC_CLASS_NAME_SRC ${CLASS_NAME}_SRC
199     cp -f ${gene_dir}/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh compile_${CLASS_NAME}.sh
200     ${gene_dir}/renameSalomeModule -i HXX2SALOME_GENERIC_CLASS_NAME \
201     ${CLASS_NAME} ${CLASS_NAME}_SRC >> ../hxx2salome_journal
202
203     GEN=( `validate_generation_choices ${GEN[${iCPP}]} ${GEN[${iCORBA}]} ${GEN[${iPython}]}` )
204     echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]}  CORBA : ${GEN[${iCORBA}]}  Python : ${GEN[${iPython}]}
205     
206     if [ "x${GEN[${iCORBA}]}" == "xyes" ] ; then
207         generate_corba_module_source
208     else
209         clean_corba_module_source
210     fi
211
212     if [ "x${GEN[${iCPP}]}" == "xyes" ] ; then
213         generate_cpp_module_source
214     else
215          clean_cpp_module_source
216     fi
217 }
218
219 compile()
220 {
221     echo "----------------- Configure -------------------"
222     
223     echo "----------------- Compile ---------------------"
224     make 
225     if [ $? -eq 0 ]
226     then
227     # compilation succeeded : we make install
228     echo
229     echo "----------------- Install ---------------------"
230     make install
231     else
232         exit 1
233     fi
234 }
235
236 update_environment()
237 {
238     if [ -z ${ENVIRON_FILE} ]
239     then
240     ENVIRON_FILE="${NEW_COMPONENT_SRC_DIR}/env_${CLASS_NAME}.${SHELL_EXT}"
241     fi
242
243     if [ ${BE_QUIET} -lt 1 ] ; then
244        echo -e "\nEnvironment file : " $ENVIRON_FILE
245     fi
246     if [ -e ${ENVIRON_FILE} ]
247     then
248     cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old
249     fi
250     touch ${ENVIRON_FILE}
251
252     if [ "${SHELL_EXT}" == "csh" ]
253     then
254     grep -q " ${CLASS_NAME}_SRC_DIR" ${ENVIRON_FILE}
255     res=$?
256     if [ $res == 1 ]
257     then
258         echo -e "###\n#------ ${CLASS_NAME}-Src ------" >>  ${ENVIRON_FILE}
259         echo -e "setenv ${CLASS_NAME}_BASE ${INSTALL_DIR}" >> ${ENVIRON_FILE}
260         echo -e "setenv ${CLASS_NAME}_SRC_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE}
261     fi
262     
263     grep -q " ${CLASS_NAME}_ROOT_DIR" ${ENVIRON_FILE}
264     res=$?
265     if [ $res == 1 ]
266     then
267         echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >>  ${ENVIRON_FILE}
268         echo -e "setenv ${CLASS_NAME}_ROOT_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE}
269         echo -e "setenv ${CLASS_NAME}CPP_ROOT_DIR ${CPP_ROOT_DIR}" >> ${ENVIRON_FILE}
270         echo -e "setenv LD_LIBRARY_PATH \${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE}
271     fi
272     fi
273     if [ "${SHELL_EXT}" == "sh" ]
274     then
275     grep -q " ${CLASS_NAME}_SRC_DIR=" ${ENVIRON_FILE}
276     res=$?
277     if [ $res == 1 ]
278     then
279         echo -e "###\n#------ ${CLASS_NAME}-Src ------" >>  ${ENVIRON_FILE}
280         echo -e "export ${CLASS_NAME}_BASE=${INSTALL_DIR}" >> ${ENVIRON_FILE}
281         echo -e "export ${CLASS_NAME}_SRC_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE}
282     fi
283     
284     grep -q " ${CLASS_NAME}_ROOT_DIR=" ${ENVIRON_FILE}
285     res=$?
286     if [ $res == 1 ]
287     then
288         echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >>  ${ENVIRON_FILE}
289         echo -e "export ${CLASS_NAME}_ROOT_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE}
290         echo -e "export ${CLASS_NAME}CPP_ROOT_DIR=${CPP_ROOT_DIR}" >> ${ENVIRON_FILE}
291         echo -e "export LD_LIBRARY_PATH=\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" \
292         >> ${ENVIRON_FILE}
293     fi
294     
295     fi
296 }
297
298 copy_component_source()
299 {
300     mv ${tmp_dir}/${CLASS_NAME}_SRC/* ${NEW_COMPONENT_SRC_DIR}
301     mkdir -p ${NEW_COMPONENT_BUILD_DIR}
302     mkdir -p ${NEW_COMPONENT_ROOT_DIR}
303 }
304
305 good_bye()
306 {
307     
308     if [ ${BE_QUIET} -gt 0 ] ; then
309        return
310     fi
311     echo -e "\n\nModule was created in ${NEW_COMPONENT_SRC_DIR}"
312 }
313
314
315 #
316 #
317 # ------------------------------------------------------------------------
318 # --------------------------- MAIN PROGRAM -------------------------------
319 # ------------------------------------------------------------------------
320 #
321 CPP_ROOT_DIR=
322 NEW_COMPONENT_ROOT_DIR=
323 NEW_COMPONENT_SRC_DIR=
324 NEW_COMPONENT_BUILD_DIR=
325 SHELL_EXT=sh
326 do_compile=0
327 do_launch=0
328
329 make_gui=0
330
331 #
332 welcome # print some welcome info
333 #
334 while getopts "qcs:e:h:lgx:" Option
335 do
336    case $Option in
337      h) usage
338         exit;;
339      q) BE_QUIET=$[ ${BE_QUIET}+1 ] ;;
340      e) ENVIRON_FILE=$OPTARG;;
341      s) case $OPTARG in
342         bash) SHELL_EXT=sh;;
343         csh)  SHELL_EXT=csh;;      
344         *)    SHELL_EXT=sh;;
345     esac;;
346      g) make_gui=1;;
347      c) do_compile=1;;
348      l) do_launch=1;;
349      x) case $OPTARG in
350             CORBA) GEN[$iCORBA]="yes" ;;
351             python) GEN[$iPython]="yes" ;;
352             C++) GEN[${iCPP}]="yes";;
353             *)   ;;
354         esac;;
355      *) echo "Unimplemented option chosen : $Option."
356         usage
357         exit;;   # DEFAULT
358    esac
359 done
360
361 shift $(($OPTIND - 1))
362
363 # default behaviour is to generate all wrappers
364 #
365 if [ "x${GEN[${iCPP}]}${GEN[${iCORBA}]}${GEN[${iPython}]}" == "xnonono" ] ;  then
366     for i in ${iCPP} ${iCORBA} ${iPython}
367       do
368       GEN[$i]="yes"
369     done
370 fi
371 echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]}  CORBA : ${GEN[${iCORBA}]}  Python : ${GEN[${iPython}]}
372 echo
373 echo
374
375 # check number of other arguments
376 #
377 if [ $# -ne 4 ]
378 then
379    echo -e "\nBad number of arguments\n\n"
380    usage
381    exit
382 fi
383
384 check_arguments $1 $2 $3 $4
385
386 # if there is a sh compatible environment file, source it
387 if [[ -n ${ENVIRON_FILE} && -f ${ENVIRON_FILE} ]]
388 then
389    # analyse extension of environment file
390    case ${ENVIRON_FILE##*\.} in 
391        bash) SHELL_EXT=sh;;
392        ksh)  SHELL_EXT=sh;;
393        csh)  SHELL_EXT=csh;;
394        sh)   SHELL_EXT=sh;;
395    esac
396 fi
397
398 # Environment policy :
399 #   - an existing sh file was specified : we source environment file
400 #   - else (no file or csh syntax)      : we don't source environment file, and do compile 
401 #                                         only if KERNEL_ROOT_DIR and MED_ROOT_DIR are defined
402 if [ "${SHELL_EXT}" == "sh" ] && [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ]
403 then
404    echo -e "\n    Environment file with sh syntax specified => we source ${ENVIRON_FILE}"
405    source ${ENVIRON_FILE}
406 fi
407
408 #
409 if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ]
410 then
411     gene_dir=${HXX2SALOME_ROOT_DIR}
412 else
413     gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory
414 fi
415 OLD_DIR=`pwd`
416 cd $gene_dir
417 gene_dir=`pwd`
418 cd $OLD_DIR
419
420 if [ ${BE_QUIET} -lt 1 ] ; then
421    echo "    hxx2salome directory : $gene_dir"
422 fi
423 if [ ! -f ${gene_dir}/parse1.awk -o ! -f ${gene_dir}/parse2.awk ] # check if script are found
424 then
425     echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy from bin directory"
426     usage
427 fi
428 #
429 # get class name
430 #
431 CLASS_NAME=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}|awk -F: '{print $1}'`
432 echo "    Name of class :" $CLASS_NAME
433 if [ ! $CLASS_NAME ]
434 then
435     echo -e "\nError:\n  Sorry - No class definition was found!\n  Please check your header file\n"
436     exit
437 fi
438
439 #
440 # create temporary working directory
441 #
442 tmp_dir="/tmp/${USER}/${CLASS_NAME}"
443 if [ -d ${tmp_dir} ]
444 then
445     rm -rf ${tmp_dir}/*
446 else
447     mkdir -p ${tmp_dir}
448 fi
449
450 #
451 # ---------------------  Generation of module source from template ------------------------------------------
452 #
453 get_info_makefile
454 generate_module_source
455
456 #
457 # ---------------------- Installation of new module sources  ------------------------------------------------
458 #
459 create_component_tree
460
461 #
462 # ---------------------- Modification of Salome environment file  -------------------------------------------
463 #
464 update_environment
465 export `echo ${CLASS_NAME}`_ROOT_DIR=${NEW_COMPONENT_ROOT_DIR}  # to avoid resource env for compiling and launching salome
466 export `echo ${CLASS_NAME}`CPP_ROOT_DIR=${CPP_ROOT_DIR}  # idem
467 #
468 # ---------------------- Copy the generated source from temp dir  -------------------------------------------
469 #
470 copy_component_source
471
472 good_bye
473
474
475 echo -e "\nGeneration done\n"