4 # salome2 environment file (.bash or .sh) - can also be specified with -e option
6 # if present, hxx2salome will try to compile new module, by sourcing ENVIRON_FILE file, and executing
7 # build_configure, configure, make & make install
8 # remark : hxx2salome has to be lanched with clean PATH, LD_LIBRARY_PATH & PYTHONPATH variables!
10 # options you want to pass to configure
16 echo -e "\n Usage :\n"
17 echo -e " Set HXX2SALOME_ROOT_DIR variable"
18 echo -e " ${HXX2SALOME_ROOT_DIR}/hxx2salome [options] "
19 echo -e " cppComponent_root_dir cppComponent.hxx"
20 echo -e " libcppComponent.so salomeComponentRoot\n"
21 echo -e " - cppComponent_root_dir : install directory (absolute path)"
22 echo -e " of the c++ component\n"
23 echo -e " - cppComponent.hxx : header of the component"
24 echo -e " - libcppComponent.so : library\n"
25 echo -e " (cppComponent.hxx and libcppComponent.so have to be found"
26 echo -e " in cppComponent_root_dir)\n"
27 echo -e " - salomeComponentRoot : directory of the source/build/install"
28 echo -e " of the Salome component\n"
29 echo -e "\n Options :"
31 echo -e " -e environment_script : to specify the name of a environment file that will be source for compiling"
32 echo -e " -s script_extension : to use if your environment file name doesn't have extension"
33 echo -e " -c : to compile after generation"
34 echo -e " (use this option only if you don't have dependencies in your header or libraries"
35 echo -e " if it is the case, you'll have to adapt your Makefile.in"
36 echo -e " -l : to launch salome "
43 echo "----------------------------------------------------------------------------"
47 echo " Automatic generation of a Salome2 component from a C++ component"
49 echo "----------------------------------------------------------------------------"
58 # check if $1 is a directory
59 echo -e "-> check arguments\n"
62 echo -e "Error : directory $1 does not exist!\n"
65 CPP_ROOT_DIR=${1%%/} # remove trailing slash if present
66 echo " C++ Component directory : ${CPP_ROOT_DIR}"
68 # look for include file $2 - check number of files found and extension
69 nb=`find ${CPP_ROOT_DIR} -name $2 | wc -l` # number of files found, should be equal to 1
73 echo -e "\n Error:\n Include file $2 not found in $1 directory!\n"
77 echo -e "\n Error:\n More than one file named $2 was found in $1!\n Include file should be unique!"
79 elif [ $extension != "hxx" -a $extension != "hh" -a $extension != "h" ]
81 echo -e "\n Error:\n Extension=$extension\n Include file $2 should have extension .hxx .hh or .h !\n"
84 hxx_file=`find ${CPP_ROOT_DIR} -name $2` # name of c++ header we will parse to generate salome module
86 echo " C++ Component header : ${hxx_file}"
87 hxx_dir=`dirname ${hxx_file}`
90 nb=`find ${CPP_ROOT_DIR} -name $3 | wc -l` # number of files found, should be equal to 1
93 echo -e "\n Error:\n Library file $3 not found in $1 directory!\n"
97 echo -e "\n Error:\n More than one file named $3 was found in $1!\n Library file should be unique!"
100 so_file=`find ${CPP_ROOT_DIR} -name $3` # absolute path of library containing c++ module
101 echo " C++ Component library : ${so_file}"
102 lib_dir=`dirname ${so_file}`
103 lib_file=${3%.so} # name without .so
104 lib_file=${lib_file#lib} # name of library without lib and .so (needed by makefile)
106 # installation directory
111 salomeComponentRoot=${4%%/} # remove trailing slash
112 echo " Salome Component directory : ${salomeComponentRoot}"
115 # retrieve python test file ending up with _test.py
116 get_python_test_file()
119 for file in `find . -name "*_test.py"`
121 cp $file ${tmp_dir}/${CLASS_NAME}_SRC/src/${CLASS_NAME}
122 python_test_file=${python_test_file}" "`basename $file`
124 echo -e "\nList of exported python file test : $python_test_file \n"
128 create_component_tree()
130 INSTALL_DIR=${salomeComponentRoot}/${CLASS_NAME}
132 export NEW_COMPONENT_SRC_DIR=${INSTALL_DIR}/${CLASS_NAME}_SRC
133 export NEW_COMPONENT_BUILD_DIR=${INSTALL_DIR}/${CLASS_NAME}_BUILD
134 export NEW_COMPONENT_ROOT_DIR=${INSTALL_DIR}/${CLASS_NAME}_INSTALL
136 \rm -rf ${NEW_COMPONENT_SRC_DIR}
137 mkdir -p ${NEW_COMPONENT_SRC_DIR}
143 makefile_lib="-L\${${CLASS_NAME}_CPP_ROOT}${lib_dir#${CPP_ROOT_DIR}} -l${lib_file}"
144 makefile_include="-I\${${CLASS_NAME}_CPP_ROOT}${hxx_dir#${CPP_ROOT_DIR}}"
146 echo -e "\nlinking option : $makefile_lib"
147 echo -e "include option : $makefile_include"
150 generate_module_source()
153 # go in temporary directory to work on code generation
157 # ------------------------- parse hxx file and generate code ---------------------------------------
159 echo -e "\n-> Extract public functions\n"
160 cat ${hxx_file} | awk -f ${gene_dir}/parse01.awk | awk -f ${gene_dir}/parse1.awk > ${CLASS_NAME}_public_functions
161 cat ${CLASS_NAME}_public_functions
162 if [ ! -s ${CLASS_NAME}_public_functions ]
164 echo -e "\nError:\n Sorry - No compatible function was found!\n Please check your header file\n"
168 echo -e "\n\n-> Parse public functions and generate Salome2 files\n\n compatibility function\n"
169 cat ${CLASS_NAME}_public_functions | awk -f ${gene_dir}/parse2.awk |\
170 awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse3.awk
173 echo -e "\n IDL file:"
174 cat parse_result > hxx2salome_journal
175 echo -e "\n----------------- IDL file ------------------\n">>hxx2salome_journal
176 cat code_idl >> hxx2salome_journal
178 echo -e "\n----------------- hxx file ------------------\n" >> hxx2salome_journal
179 cat code_hxx >> hxx2salome_journal
180 echo -e "\n----------------- cxx file ------------------\n" >> hxx2salome_journal
181 cat code_cxx >> hxx2salome_journal
185 # ------------------- duplicates template module and insert generated code ------------------------------
187 echo -e "\n-> Duplicate template module" | tee hxx2salome_journal
188 tar xvfz ${gene_dir}/template_src.tgz >> hxx2salome_journal
189 mv TEMPLATE_SRC ${CLASS_NAME}_SRC
190 ${gene_dir}/renameSalomeModule -i TEMPLATE ${CLASS_NAME} ${CLASS_NAME}_SRC >> hxx2salome_journal
192 echo -e "\n-> Substitute generated code in idl file"
193 echo "// this idl file was generated by hxx2salome" > tmpfile
194 cat ${CLASS_NAME}_SRC/idl/${CLASS_NAME}_Gen.idl |awk '
195 $0 ~ "HXX2SALOME_IDL_CODE" {system("cat code_idl >> tmpfile")}
196 $0 != "HXX2SALOME_IDL_CODE" { print $0 >> "tmpfile" }'
197 mv tmpfile ${CLASS_NAME}_SRC/idl/${CLASS_NAME}_Gen.idl
199 echo -e "\n-> Substitute generated code in hxx file"
200 echo "// this hxx file was generated by hxx2salome" > tmpfile
201 cat ${CLASS_NAME}_SRC/src/${CLASS_NAME}/${CLASS_NAME}_i.hxx |awk '
202 $0 ~ "HXX2SALOME_HXX_CODE" {system("cat code_hxx >> tmpfile")}
203 $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }'
204 mv tmpfile ${CLASS_NAME}_SRC/src/${CLASS_NAME}/${CLASS_NAME}_i.hxx
206 echo -e "\n-> Substitute generated code in cxx file"
207 echo "// this cxx file was generated by hxx2salome" > tmpfile
208 cat ${CLASS_NAME}_SRC/src/${CLASS_NAME}/${CLASS_NAME}_i.cxx |awk -v cpp_include=$hxx '
209 $0 ~ "HXX2SALOME_CXX_CODE" {system("cat code_cxx >> tmpfile")}
210 $0 ~ "HXX2SALOME_CPP_INCLUDE" { printf "#include \"%s\"\n",cpp_include >> "tmpfile" }
211 $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }'
212 mv tmpfile ${CLASS_NAME}_SRC/src/${CLASS_NAME}/${CLASS_NAME}_i.cxx
214 # add flags in makefile
218 echo -e "\n-> Substitute flags in Makefile.in"
219 sed "s?HXX2SALOME_INCLUDE?${makefile_include}?g
220 s?HXX2SALOME_PYTHON_FILE?${python_test_file}?g
221 s?HXX2SALOME_LIB?${makefile_lib}?g
222 " ${CLASS_NAME}_SRC/src/${CLASS_NAME}/Makefile.in > tmpfile
223 mv tmpfile ${CLASS_NAME}_SRC/src/${CLASS_NAME}/Makefile.in
225 # generate component catalog
226 echo -e "\n-> Generate component catalog" | tee hxx2salome_journal
227 if [ -f ${KERNEL_ROOT_DIR}/bin/salome/runIDLparser ]
229 idlparser=${KERNEL_ROOT_DIR}/bin/salome/runIDLparser
231 idlparser=${gene_dir}/runIDLparser
233 cd ${CLASS_NAME}_SRC/resources
234 VER=`cat ${KERNEL_ROOT_DIR}/bin/salome/VERSION | awk ' { print $NF }'` # extract number of version
235 ${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 >& /dev/null | tee hxx2salome_journal
236 cat tmp.xml | sed 's/_Gen//g' > ${CLASS_NAME}Catalog.xml
243 echo "----------------- Configure -------------------"
245 echo "----------------- Compile ---------------------"
249 # compilation succeeded : we make install
251 echo "----------------- Install ---------------------"
260 if [ -z ${ENVIRON_FILE} ]
262 ENVIRON_FILE="${NEW_COMPONENT_SRC_DIR}/env_${CLASS_NAME}.${SHELL_EXT}"
265 echo -e "\nEnvironment file : ", $ENVIRON_FILE
266 if [ -e ${ENVIRON_FILE} ]
268 cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old
270 touch ${ENVIRON_FILE}
272 if [ "${SHELL_EXT}" == "csh" ]
274 grep -q " ${CLASS_NAME}_SRC_DIR" ${ENVIRON_FILE}
278 echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE}
279 echo -e "setenv ${CLASS_NAME}_BASE ${INSTALL_DIR}" >> ${ENVIRON_FILE}
280 echo -e "setenv ${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 "setenv ${CLASS_NAME}_ROOT_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE}
289 echo -e "setenv ${CLASS_NAME}_CPP_ROOT ${CPP_ROOT_DIR}" >> ${ENVIRON_FILE}
290 echo -e "setenv LD_LIBRARY_PATH \${${CLASS_NAME}_CPP_ROOT}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE}
293 if [ "${SHELL_EXT}" == "sh" ]
295 grep -q " ${CLASS_NAME}_SRC_DIR=" ${ENVIRON_FILE}
299 echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE}
300 echo -e "export ${CLASS_NAME}_BASE=${INSTALL_DIR}" >> ${ENVIRON_FILE}
301 echo -e "export ${CLASS_NAME}_SRC_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE}
304 grep -q " ${CLASS_NAME}_ROOT_DIR=" ${ENVIRON_FILE}
308 echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE}
309 echo -e "export ${CLASS_NAME}_ROOT_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE}
310 echo -e "export ${CLASS_NAME}_CPP_ROOT=${CPP_ROOT_DIR}" >> ${ENVIRON_FILE}
311 echo -e "export LD_LIBRARY_PATH=\${${CLASS_NAME}_CPP_ROOT}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" \
318 copy_component_source()
320 mv ${tmp_dir}/${CLASS_NAME}_SRC/* ${NEW_COMPONENT_SRC_DIR}
325 echo -e "\n\nModule was created in ${NEW_COMPONENT_SRC_DIR}"
326 echo -e "\nTo compile it, do the following : \n"
327 echo -e "\tsource ${ENVIRON_FILE}"
328 echo -e "\tcd \${${CLASS_NAME}_SRC_DIR}"
329 echo -e "\t./build_configure"
330 echo -e "\tmkdir -p \${${CLASS_NAME}_BUILD_DIR}"
331 echo -e "\tcd \${${CLASS_NAME}_BUILD_DIR}"
332 echo -e "\t\${${CLASS_NAME}_SRC_DIR}/configure ${CONFIGURE_OPTION} --prefix=\${${CLASS_NAME}_ROOT_DIR}"
334 echo -e "\tmake install"
335 echo -e "\nTo use it :\n"
336 echo -e "\tsource the Salome environment"
337 echo -e "\tsource the component environment file (${ENVIRON_FILE})"
338 echo -e "\trun Salome"
339 echo -e "\tadd ${CLASS_NAME} to the Salome modules list"
340 echo -e "\t\t(with the --modules option of the runSalome command or"
341 echo -e "\t\tby editing the ~/.salome_2.2.4/salome.launch file)"
342 echo -e "\nIf the header of your component includes other headers that are not in the same directories,"
343 echo -e "or if yout library has dependencies you want to specify,"
344 echo -e "you'll have to modify the following Makefile:in : "
345 echo -e "\t\${${CLASS_NAME}_SRC_DIR}/src/${CLASS_NAME}/Makefile.in"
350 ${KERNEL_ROOT_DIR}/bin/salome/runSalome --gui --modules=GEOM,SMESH,VISU,SUPERV,MED,`echo ${CLASS_NAME}` --containers=cpp,python --killall
355 if [ ! -d ${NEW_COMPONENT_BUILD_DIR} ]
357 mkdir -p ${NEW_COMPONENT_BUILD_DIR}
359 if [ ! -d ${NEW_COMPONENT_ROOT_DIR} ]
361 mkdir -p ${NEW_COMPONENT_ROOT_DIR}
363 \rm -rf ${NEW_COMPONENT_ROOT_DIR}/* ${NEW_COMPONENT_BUILD_DIR}/*
365 # source ${ENVIRON_FILE}
367 echo -e "\n-> Build Configure"
368 cd ${NEW_COMPONENT_SRC_DIR}
370 cd ${NEW_COMPONENT_BUILD_DIR}
371 echo -e "\n-> Configure in ${NEW_COMPONENT_BUILD_DIR}"
372 echo -e "\n-> Install in ${NEW_COMPONENT_ROOT_DIR}"
373 ${NEW_COMPONENT_SRC_DIR}/configure ${CONFIGURE_OPTION} --prefix=${NEW_COMPONENT_ROOT_DIR}
376 if [[ $do_compile -eq 1 ]]
381 if [[ $do_launch -eq 1 ]]
388 # ------------------------------------------------------------------------
389 # --------------------------- MAIN PROGRAM -------------------------------
390 # ------------------------------------------------------------------------
393 NEW_COMPONENT_ROOT_DIR=
394 NEW_COMPONENT_SRC_DIR=
395 NEW_COMPONENT_BUILD_DIR=
399 welcome # print some welcome info
401 while getopts "cs:e:h:l" Option
406 e) ENVIRON_FILE=$OPTARG;;
414 *) echo "Unimplemented option chosen : $Option."
420 shift $(($OPTIND - 1))
422 # check number of other arguments
426 echo -e "\nBad number of arguments\n\n"
431 check_arguments $1 $2 $3 $4
433 # if there is a sh compatible environment file, source it
434 if [[ -n ${ENVIRON_FILE} && -f ${ENVIRON_FILE} ]]
436 # analyse extension of environment file
437 case ${ENVIRON_FILE##*\.} in
445 if [ ${KERNEL_ROOT_DIR} ] && [ -d ${KERNEL_ROOT_DIR} ] && [ ${OMNIORBDIR} ] && [ -d ${OMNIORBDIR} ]
447 # if KERNEL_ROOT_DIR ans OMNIORBDIR are defined, we consider that environment is set
448 echo -e "\n Environment already set"
450 # if KERNEL_ROOT_DIR is not defined :
451 # - sh file : we source environment file
452 # - csh file : we do not compile
453 if [ "${SHELL_EXT}" == "sh" ] && [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ]
455 echo -e "\n Environment not set : source ${ENVIRON_FILE}"
456 source ${ENVIRON_FILE}
458 if [ $do_compile -eq 1 ]
460 echo -e "\n Warning - Cannot compile : Environment shoud be set up for compiling!\n"
467 if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ]
469 gene_dir=${HXX2SALOME_ROOT_DIR}
471 gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory
473 echo " hxx2salome directory : $gene_dir"
474 if [ ! -f ${gene_dir}/parse1.awk -o ! -f ${gene_dir}/parse2.awk ] # check if script are found
476 echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy from bin directory"
482 CLASS_NAME=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}`
483 echo " Name of class :" $CLASS_NAME
486 echo -e "\nError:\n Sorry - No class definition was found!\n Please check your header file\n"
491 # create temporary working directory
493 tmp_dir="/tmp/${USER}/${CLASS_NAME}"
502 # --------------------- Generation of module source from template ------------------------------------------
505 generate_module_source
508 # ---------------------- Installation of new module sources ------------------------------------------------
510 create_component_tree
513 # ---------------------- Modification of Salome environment file -------------------------------------------
516 export `echo ${CLASS_NAME}`_ROOT_DIR=${NEW_COMPONENT_ROOT_DIR} # to avoid resource env for compiling and launching salome
517 export `echo ${CLASS_NAME}`_CPP_ROOT=${CPP_ROOT_DIR} # idem
519 # ---------------------- Copy the generated source from temp dir -------------------------------------------
521 copy_component_source
524 # ---------------------- If requested, compilation of the Salome component ----------------------------------
525 if [ ${do_compile} -eq 1 ]
532 echo -e "\nGeneration done\n"