Salome HOME
c1852afba130a71500ee7ac674870a4fde82f9ff
[tools/hxx2salome.git] / scripts / hxx2salome
1 #!/bin/bash
2 #
3 # directory where SALOME2 modules sources are stored. if present, generated module is created inside.
4 SALOME_SRC_DIR=
5 #
6 # directory where you want to put build & install directories. may be the same than SALOME_SRC_DIR
7 SALOME_BUILD_DIR=
8 #
9 # salome2 environment file (.bash or .sh)
10 # if present, hxx2salome will try to compile new module, by sourcing ENVIRON_FILE file, and executing
11 # build_configure, configure, make & make install
12 # remark : hxx2salome has to be lanched with clean PATH, LD_LIBRARY_PATH & PYTHONPATH variables!
13 ENVIRON_FILE=
14 CONFIGURE_OPTION=--disable-debug
15 #
16 #
17 usage()
18 {
19     echo -e "\n  Usage :\n"
20     echo -e "  $HXX2SALOME_ROOT_DIR/hxx2salome cppComponent_root_dir cppComponent.hxx libcppComponent.so\n"
21     echo -e "     - cppComponent_root_dir : install directory (absolute path) of the c++ component"
22     echo -e "     - cppComponent.hxx : header of the component"
23     echo -e "     - libcppComponent.so : library\n"
24     echo -e "       (cppComponent.hxx and libcppComponent.so have to be found in cppComponent_root_dir)\n"
25     exit
26 }
27 #
28 welcome()
29 {
30     clear
31     echo -e "\n\n"
32     echo  "------------------------------------------------------------------------------------"
33     echo
34     echo  "                                hxx2salome"
35     echo
36     echo  "     Generation automatique d'un composant salome 2 à partir d'un composant C++"
37     echo 
38     echo  "------------------------------------------------------------------------------------"
39     echo 
40     echo 
41     echo 
42 }
43 check_arguments()
44 {
45
46     # check if $1 is a directory
47     echo -e "-> check arguments\n"
48     if [ ! -d $1 ]
49     then
50        echo -e "Error : directory $1 does not exist!\n"
51        usage
52     fi
53     cpp_root_dir=$1
54     echo "    C++ Component directory : ${cpp_root_dir}"
55
56     # look for include file $2
57     nb=`find ${cpp_root_dir} -name $2 | wc -l` # number of files found, should be equal to 1
58     extension=${2##*\.}
59     if [ $nb -eq 0 ]
60     then
61           echo -e "\n  Error:\n  Include file $2 not found in $1 directory!\n"
62           usage
63     elif [ $nb -ge 2 ]
64     then
65          echo -e "\n  Error:\n  More than one file named $2 was found in $1!\n  Include file should be unique!"
66          usage
67     elif [ $extension != "hxx" -a $extension != "hh" -a $extension != "h" ]
68     then
69          echo -e "\n  Error:\n  Extension=$extension\n  Include file $2 should have extension .hxx .hh or .h !\n"
70          usage
71     fi
72     hxx_file=`find ${cpp_root_dir} -name $2` # name of c++ header we will parse to generate salome module
73     echo "    C++ Component header    : ${hxx_file}"
74     hxx_dir=`dirname ${hxx_file}`
75
76     # look for library $3
77     nb=`find ${cpp_root_dir} -name $3 | wc -l` # number of files found, should be equal to 1
78     if [ $nb -eq 0 ]
79     then
80         echo -e "\n  Error:\n  Library file $3 not found in $1 directory!\n"
81         usage
82     elif [ $nb -ge 2 ]
83     then
84         echo -e "\n  Error:\n  More than one file named $3 was found in $1!\n  Library file should be unique!"
85         usage
86     fi
87     so_file=`find ${cpp_root_dir} -name $3` # absolute path of library containing c++ module
88     echo "    C++ Component library   : ${so_file}"
89     lib_dir=`dirname ${so_file}`
90     lib_file=${3%.so} # name without .so
91     lib_file=${lib_file#lib} # name of library without lib an .so (needed by makefile)
92 }
93
94 # retrieve python test file ending up with _test.py
95 get_python_test_file()
96 {
97     cd ${cpp_root_dir}
98     python_test_file=`ls *_test.py 2>/dev/null`
99     if [ $? -eq 0 ]  # if there is python test file, copy them
100     then
101         cp ${python_test_file} ${tmp_dir}/${class_name}_SRC/src/${class_name}
102     else
103         python_test_file=""
104     fi
105     cd -
106 }
107 read_makefile_option()
108 {
109      echo -e -n "\n\nEnter new linking option :"
110      read makefile_lib
111      echo -e -n "\n\nEnter new include option :"
112      read makefile_include
113      
114 }
115 get_info_makefile()
116 {
117     makefile_lib="-L\${${class_name}_CPP_ROOT}${lib_dir#${cpp_root_dir}} -l${lib_file}"
118     makefile_include="-I\${${class_name}_CPP_ROOT}${hxx_dir#${cpp_root_dir}}"
119     echo -e "\n\n[QUESTION]"
120     echo -e "\nThe following option was generated to indicate where to find"
121     echo -e "the needed libraries and include files when compiling and linking the c++ component :\n\n\t${makefile_lib}\n\t${makefile_include}"
122     echo -e "\n\t(with \${${class_name}_CPP_ROOT} set to ${cpp_root_dir} at compile time)\n"
123     echo -e "Do you want to modify it? (answer yes if something is wrong or a library is missing): "
124     echo -e "                           answer no if flags are OK ):"
125     read answer
126     case $answer in 
127        y* | Y* | o* | O* ) read_makefile_option ;;
128     esac
129     
130     echo -e  "\nlinking option : $makefile_lib"
131     echo -e  "include option : $makefile_include"
132 }
133
134 compile()
135 {
136     clear
137     echo "----------------- Compile ---------------------"
138     make 
139     if [ $? -eq 0 ]
140     then
141         # compilation succeeded : we make install
142         echo
143         echo "----------------- Install ---------------------"
144         make install
145     else
146         exit 1
147     fi
148 }
149
150 update_environ()
151 {
152     cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old
153     echo -e "##\n#------ ${class_name}-Src ------\nexport ${class_name}_SRC_DIR=${install_dir}/${class_name}_SRC" >> ${ENVIRON_FILE}
154     echo -e "##\n#------ ${class_name}-Bin ------\nexport ${class_name}_ROOT_DIR=${SALOME_BUILD_DIR}/${class_name}_INSTALL" >> ${ENVIRON_FILE}
155     echo -e "export ${class_name}_CPP_ROOT=${cpp_root_dir}" >> ${ENVIRON_FILE}
156     echo -e "export LD_LIBRARY_PATH=\${${class_name}_CPP_ROOT}${lib_dir#${cpp_root_dir}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE}
157 }
158
159 good_bye()
160 {
161     echo -e "\n\nModule was created in ${install_dir}\nTo compile it, do the following : \n"
162     echo -e "\tsetenv ${class_name}_CPP_ROOT ${cpp_root_dir}"
163     echo -e "\tsetenv LD_LIBRARY_PATH \${${class_name}_CPP_ROOT}${lib_dir#${cpp_root_dir}}:\${LD_LIBRARY_PATH}"
164     echo -e "\tcd ${install_dir}"
165     echo -e "\t./build_configure"
166     echo -e "\tcd build_directory"
167     echo -e "\t${install_dir}/configure ${CONFIGURE_OPTION} --prefix=install_directory"
168     echo -e "\tmake"
169     echo -e "\tmake install"
170     echo -e "\tsetenv ${class_name}_ROOT_DIR install_directory"
171     echo -e "\tsource salome environment and run it"
172     exit
173 }
174
175 launch_salome()
176 {
177     ${KERNEL_ROOT_DIR}/bin/salome/runSalome --gui --modules=GEOM,SMESH,VISU,SUPERV,MED,`echo ${class_name}`  --containers=cpp,python --killall
178 }
179
180 compile_module()
181 {
182     echo -e "\n-> Create build and install directories"
183     if [ ! -d ${SALOME_BUILD_DIR} ]
184     then
185         SALOME_BUILD_DIR=${install_dir}
186     else 
187         SALOME_BUILD_DIR=${SALOME_BUILD_DIR}/${class_name}
188     fi
189     if [ ! -d ${SALOME_BUILD_DIR} ]
190     then
191         mkdir ${SALOME_BUILD_DIR}
192     fi
193     if [ ! -d ${SALOME_BUILD_DIR}/${class_name}_BUILD ]
194     then
195         mkdir ${SALOME_BUILD_DIR}/${class_name}_BUILD
196     fi
197     if [ ! -d ${SALOME_BUILD_DIR}/${class_name}_INSTALL ]
198     then
199         mkdir ${SALOME_BUILD_DIR}/${class_name}_INSTALL
200     fi
201     rm -rf ${SALOME_BUILD_DIR}/${class_name}_INSTALL/* ${SALOME_BUILD_DIR}/${class_name}_BUILD/*
202
203
204     echo -e "\n-> Source environment file ${ENVIRON_FILE}"
205     export `echo ${class_name}`_ROOT_DIR=${SALOME_BUILD_DIR}/${class_name}_INSTALL
206     export `echo ${class_name}`_CPP_ROOT=${cpp_root_dir}
207     export LD_LIBRARY_PATH=${lib_dir}:${LD_LIBRARY_PATH}
208     echo $CALC_CPP_DIR
209     echo $CALC_ROOT_DIR
210     echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH
211     echo 
212     echo -e "\n-> Build Configure"
213     cd ${install_dir}/${class_name}_SRC
214     ./build_configure
215     cd ${SALOME_BUILD_DIR}/${class_name}_BUILD
216     echo -e "\n-> Configure in ${SALOME_BUILD_DIR}/${class_name}_BUILD"
217     ${install_dir}/${class_name}_SRC/configure ${CONFIGURE_OPTION} --prefix=${SALOME_BUILD_DIR}/${class_name}_INSTALL
218    echo "Compile ?"
219    echo
220    read answer
221    case $answer in
222      y* | Y* | o* | O* )  compile ;;
223      *) exit 1 ;;
224    esac
225    cd $SALOME_DIR
226    export `echo ${SOURCE_NAME}`_ROOT_DIR=${INSTALL_ROOT_DIR}/${module}/${SOURCE_NAME}_INSTALL
227 #  Mise à jour du script d'environnement
228    echo -e "\n\n[QUESTION] Would you like to update your environment scrip  ${ENVIRON_FILE}?"
229    echo -e -n "(add environment vaiable necessary to run and compile your salome component) : "
230    read answer
231    case $answer in
232      y* | Y* | o* | O* )  update_environ ;;
233    esac
234
235    echo -e -n "\n\n[QUESTION] Would you like to launch salome ?"
236    read answer
237    case $answer in
238      y* | Y* | o* | O* )  launch_salome ;;
239    esac
240    echo "Good Bye!"
241    exit
242 }
243 #
244 #
245 # ------------------------------------------------------------------------
246 # --------------------------- MAIN PROGRAM -------------------------------
247 # ------------------------------------------------------------------------
248 #
249 welcome # print some welcome info
250 # check number of arguments
251 #
252 if [ $# -ne 3 ]
253 then
254    echo -e "\nBad number of arguments\n\n"
255    usage
256    exit
257 fi
258 check_arguments $1 $2 $3
259
260 # if there is an anvironment file, source it and set compilation flag
261 if [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ]
262 then
263    source ${ENVIRON_FILE}
264    do_compile=1  # there is an environment file, we can compile
265 else
266    echo -e "\n[REMARK] NO environment file was specified, automatic compilation will not be done.\n\n"
267 fi
268 #
269 if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ]
270 then
271     gene_dir=${HXX2SALOME_ROOT_DIR}
272 else
273     if [ ! -f parse1.awk -o ! -f parse2.awk ]
274     then
275         echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy"
276         usage
277     else
278         gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory
279     fi
280 fi
281 #
282 # get class' name
283 #
284 class_name=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}`
285 echo "    Name of class :" $class_name
286 if [ ! $class_name ]
287 then
288     echo -e "\nError:\n  Sorry - No class definition was found!\n  Please check your header file\n"
289     exit
290 fi
291 #
292 # create temporary working directory
293 #
294 tmp_dir="/tmp/${class_name}_${USER}"
295 if [ -d ${tmp_dir} ]
296 then
297     rm -rf ${tmp_dir}/*
298 else
299     mkdir ${tmp_dir}
300 fi
301 #
302 # go in temporary directory to work on code generation
303 cd ${tmp_dir}
304 #
305 #
306 # -------------------------  parse hxx file and generate code  ---------------------------------------
307 #
308 echo -e "\n-> Extract public functions\n"
309 cat ${hxx_file} | awk -f ${gene_dir}/parse1.awk > ${class_name}_public_functions
310 cat ${class_name}_public_functions
311 if [ ! -s ${class_name}_public_functions ]
312 then
313     echo -e "\nError:\n  Sorry - No compatible function was found!\n  Please check your header file\n"
314     exit
315 fi
316 #
317 echo -e "\n\n-> Parse public functions and generate Salome2 files\n\n  compatibility      function\n"
318 cat ${class_name}_public_functions | awk -f ${gene_dir}/parse2.awk |\
319 awk -v class_name=${class_name} -f ${gene_dir}/parse3.awk
320 #
321 # outputs
322 echo -e "\n  IDL file:"
323 cat parse_result > hxx2salome_journal
324 echo -e "\n----------------- IDL file ------------------\n">>hxx2salome_journal
325 cat code_idl >> hxx2salome_journal
326 cat code_idl
327 echo -e "\n----------------- hxx file ------------------\n" >> hxx2salome_journal
328 cat code_hxx >> hxx2salome_journal
329 echo -e "\n----------------- cxx file ------------------\n" >> hxx2salome_journal
330 cat code_cxx >> hxx2salome_journal
331 echo
332 #
333 #
334 # -------------------  duplicates template module and insert generated code  ------------------------------
335 #
336 echo -e "\n-> Duplicate template module"
337 cp -r ${gene_dir}/TEMPLATE_SRC ${class_name}_SRC
338 ${gene_dir}/renameSalomeModule -i TEMPLATE ${class_name} ${class_name}_SRC >> hxx2salome_journal
339 #
340 echo -e "\n-> Substitute generated code in idl file"
341 echo "// this idl file was generated by hxx2salome" > tmpfile
342 cat ${class_name}_SRC/idl/${class_name}_Gen.idl |awk ' 
343     $0 ~ "HXX2SALOME_IDL_CODE" {system("cat code_idl >> tmpfile")} 
344     $0 != "HXX2SALOME_IDL_CODE" { print $0 >> "tmpfile" }'
345 mv tmpfile ${class_name}_SRC/idl/${class_name}_Gen.idl
346 #
347 echo -e "\n-> Substitute generated code in hxx file"
348 echo "// this hxx file was generated by hxx2salome" > tmpfile
349 cat ${class_name}_SRC/src/${class_name}/${class_name}_i.hxx |awk '
350     $0 ~ "HXX2SALOME_HXX_CODE" {system("cat code_hxx >> tmpfile")}
351     $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }'
352 mv tmpfile ${class_name}_SRC/src/${class_name}/${class_name}_i.hxx
353 #
354 echo -e "\n-> Substitute generated code in cxx file"
355 echo "// this cxx file was generated by hxx2salome" > tmpfile
356 cat ${class_name}_SRC/src/${class_name}/${class_name}_i.cxx |awk -v cpp_include=$2 '
357     $0 ~ "HXX2SALOME_CXX_CODE" {system("cat code_cxx >> tmpfile")}
358     $0 ~ "HXX2SALOME_CPP_INCLUDE" { printf "#include \"%s\"\n",cpp_include >> "tmpfile" }
359     $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }'
360 mv tmpfile ${class_name}_SRC/src/${class_name}/${class_name}_i.cxx
361 #
362 # add flags in makefile
363 get_python_test_file
364 get_info_makefile
365 echo -e "\n-> Substitute flags in Makefile.in"
366 sed "s?HXX2SALOME_INCLUDE?${makefile_include}?g
367      s?HXX2SALOME_PYTHON_FILE?${python_test_file}?g
368      s?HXX2SALOME_LIB?${makefile_lib}?g
369     " ${class_name}_SRC/src/${class_name}/Makefile.in > tmpfile
370 mv tmpfile ${class_name}_SRC/src/${class_name}/Makefile.in
371 #
372 # generate component catalog
373 if  [ $KERNEL_ROOT_DIR ]
374 then
375     echo -e "\n-> Generate component catalog\n\n" | tee hxx2salome_journal
376     idlparser=${KERNEL_ROOT_DIR}/bin/salome/runIDLparser
377     cd ${class_name}_SRC/resources
378     VER=`cat ${KERNEL_ROOT_DIR}/bin/salome/VERSION | awk ' { print $NF }'` # extract number of version 
379     ${idlparser} -Wbcatalog=tmp.xml,icon=${class_name}.png,version=${VER} -I${KERNEL_ROOT_DIR}/idl/salome -I${MED_ROOT_DIR}/idl/salome ../idl/${class_name}_Gen.idl >> hxx2salome_journal 2>&1
380     cat tmp.xml | sed 's/_Gen//g' > ${class_name}Catalog.xml
381     rm tmp.xml
382 else
383     echo -e "\n-> CANNOT GENERATE component catalog : variable KERNEL_ROOT_DIR in not defined\n\n" | tee hxx2salome_journal
384 fi
385 #
386 #
387 # ---------------------  Installation of new module sources  ------------------------------------------------
388 #
389 today=`date +%b%d_%Hh%M`
390 if [ ! -d ${SALOME_SRC_DIR} ] # ask for installation directory if not specified by SALOME_SRC_DIR
391 then
392    echo -e "\n\nThe new module ${class_name}_SRC was generated in ${tmp_dir}"
393    echo -e -n "[QUESTION] In which directory do you want to move it? "
394    read install_dir
395 else
396    install_dir=${SALOME_SRC_DIR}/${class_name}
397    if [ ! -d ${install_dir} ] # create module directory if necessary
398    then
399       mkdir ${install_dir}
400    fi
401 fi
402 if [ -d ${install_dir} ]
403 then
404     if [ -d ${install_dir}/${class_name}_SRC ]
405     then
406        echo -e "A module ${install_dir}/${class_name}_SRC already exist!"
407        echo -e "It will be renamed ${class_name}_SRC_${today}"
408        mv ${install_dir}/${class_name}_SRC ${install_dir}/${class_name}_SRC_${today}
409     fi
410     echo -> Create module ${class_name}_SRC in ${install_dir}
411     mv ${tmp_dir}/${class_name}_SRC ${install_dir}
412 fi
413 #
414 #
415 # ------------------- Modification of Salome environment file  ---------------------------------------------
416 #
417 if [ ${do_compile} -eq 1 ]
418 then
419     echo -e -n "\n\n[QUESTION] Do you want to compile new module? "
420     read answer
421     case $answer in 
422        y* | Y* | o* | O* ) compile_module ;;
423     esac
424 fi
425 good_bye
426