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