#!/bin/bash # # directory where SALOME2 modules sources are stored. if present, generated module is created inside. SALOME_SRC_DIR= # # directory where you want to put build & install directories. may be the same than SALOME_SRC_DIR SALOME_BUILD_DIR= # # salome2 environment file (.bash or .sh) # if present, hxx2salome will try to compile new module, by sourcing ENVIRON_FILE file, and executing # build_configure, configure, make & make install # remark : hxx2salome has to be lanched with clean PATH, LD_LIBRARY_PATH & PYTHONPATH variables! ENVIRON_FILE= CONFIGURE_OPTION=--disable-debug # # usage() { echo -e "\n Usage :\n" echo -e " $HXX2SALOME_ROOT_DIR/hxx2salome cppComponent_root_dir cppComponent.hxx libcppComponent.so\n" echo -e " - cppComponent_root_dir : install directory (absolute path) of the c++ component" echo -e " - cppComponent.hxx : header of the component" echo -e " - libcppComponent.so : library\n" echo -e " (cppComponent.hxx and libcppComponent.so have to be found in cppComponent_root_dir)\n" exit } # welcome() { clear echo -e "\n\n" echo "------------------------------------------------------------------------------------" echo echo " hxx2salome" echo echo " Generation automatique d'un composant salome 2 à partir d'un composant C++" echo echo "------------------------------------------------------------------------------------" echo echo echo } check_arguments() { # check if $1 is a directory echo -e "-> check arguments\n" if [ ! -d $1 ] then echo -e "Error : directory $1 does not exist!\n" usage fi cpp_root_dir=$1 echo " C++ Component directory : ${cpp_root_dir}" # look for include file $2 nb=`find ${cpp_root_dir} -name $2 | wc -l` # number of files found, should be equal to 1 extension=${2##*\.} if [ $nb -eq 0 ] then echo -e "\n Error:\n Include file $2 not found in $1 directory!\n" usage elif [ $nb -ge 2 ] then echo -e "\n Error:\n More than one file named $2 was found in $1!\n Include file should be unique!" usage elif [ $extension != "hxx" -a $extension != "hh" -a $extension != "h" ] then echo -e "\n Error:\n Extension=$extension\n Include file $2 should have extension .hxx .hh or .h !\n" usage fi hxx_file=`find ${cpp_root_dir} -name $2` # name of c++ header we will parse to generate salome module echo " C++ Component header : ${hxx_file}" hxx_dir=`dirname ${hxx_file}` # look for library $3 nb=`find ${cpp_root_dir} -name $3 | wc -l` # number of files found, should be equal to 1 if [ $nb -eq 0 ] then echo -e "\n Error:\n Library file $3 not found in $1 directory!\n" usage elif [ $nb -ge 2 ] then echo -e "\n Error:\n More than one file named $3 was found in $1!\n Library file should be unique!" usage fi so_file=`find ${cpp_root_dir} -name $3` # absolute path of library containing c++ module echo " C++ Component library : ${so_file}" lib_dir=`dirname ${so_file}` lib_file=${3%.so} # name without .so lib_file=${lib_file#lib} # name of library without lib an .so (needed by makefile) } # retrieve python test file ending up with _test.py get_python_test_file() { cd ${cpp_root_dir} python_test_file=`ls *_test.py 2>/dev/null` if [ $? -eq 0 ] # if there is python test file, copy them then cp ${python_test_file} ${tmp_dir}/${class_name}_SRC/src/${class_name} else python_test_file="" fi cd - } read_makefile_option() { echo -e -n "\n\nEnter new linking option :" read makefile_lib echo -e -n "\n\nEnter new include option :" read makefile_include } get_info_makefile() { makefile_lib="-L\${${class_name}_CPP_ROOT}${lib_dir#${cpp_root_dir}} -l${lib_file}" makefile_include="-I\${${class_name}_CPP_ROOT}${hxx_dir#${cpp_root_dir}}" echo -e "\n\n[QUESTION]" echo -e "\nThe following option was generated to indicate where to find" echo -e "the needed libraries and include files when compiling and linking the c++ component :\n\n\t${makefile_lib}\n\t${makefile_include}" echo -e "\n\t(with \${${class_name}_CPP_ROOT} set to ${cpp_root_dir} at compile time)\n" echo -e "Do you want to modify it? (answer yes if something is wrong or a library is missing): " echo -e " answer no if flags are OK ):" read answer case $answer in y* | Y* | o* | O* ) read_makefile_option ;; esac echo -e "\nlinking option : $makefile_lib" echo -e "include option : $makefile_include" } compile() { clear echo "----------------- Compile ---------------------" make if [ $? -eq 0 ] then # compilation succeeded : we make install echo echo "----------------- Install ---------------------" make install else exit 1 fi } update_environ() { cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old echo -e "##\n#------ ${class_name}-Src ------\nexport ${class_name}_SRC_DIR=${install_dir}/${class_name}_SRC" >> ${ENVIRON_FILE} echo -e "##\n#------ ${class_name}-Bin ------\nexport ${class_name}_ROOT_DIR=${SALOME_BUILD_DIR}/${class_name}_INSTALL" >> ${ENVIRON_FILE} echo -e "export ${class_name}_CPP_ROOT=${cpp_root_dir}" >> ${ENVIRON_FILE} echo -e "export LD_LIBRARY_PATH=\${${class_name}_CPP_ROOT}${lib_dir#${cpp_root_dir}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE} } good_bye() { echo -e "\n\nModule was created in ${install_dir}\nTo compile it, do the following : \n" echo -e "\tsetenv ${class_name}_CPP_ROOT ${cpp_root_dir}" echo -e "\tsetenv LD_LIBRARY_PATH \${${class_name}_CPP_ROOT}${lib_dir#${cpp_root_dir}}:\${LD_LIBRARY_PATH}" echo -e "\tcd ${install_dir}" echo -e "\t./build_configure" echo -e "\tcd build_directory" echo -e "\t${install_dir}/configure ${CONFIGURE_OPTION} --prefix=install_directory" echo -e "\tmake" echo -e "\tmake install" echo -e "\tsetenv ${class_name}_ROOT_DIR install_directory" echo -e "\tsource salome environment and run it" exit } launch_salome() { ${KERNEL_ROOT_DIR}/bin/salome/runSalome --gui --modules=GEOM,SMESH,VISU,SUPERV,MED,`echo ${class_name}` --containers=cpp,python --killall } compile_module() { echo -e "\n-> Create build and install directories" if [ ! -d ${SALOME_BUILD_DIR} ] then SALOME_BUILD_DIR=${install_dir} else SALOME_BUILD_DIR=${SALOME_BUILD_DIR}/${class_name} fi if [ ! -d ${SALOME_BUILD_DIR} ] then mkdir ${SALOME_BUILD_DIR} fi if [ ! -d ${SALOME_BUILD_DIR}/${class_name}_BUILD ] then mkdir ${SALOME_BUILD_DIR}/${class_name}_BUILD fi if [ ! -d ${SALOME_BUILD_DIR}/${class_name}_INSTALL ] then mkdir ${SALOME_BUILD_DIR}/${class_name}_INSTALL fi rm -rf ${SALOME_BUILD_DIR}/${class_name}_INSTALL/* ${SALOME_BUILD_DIR}/${class_name}_BUILD/* echo -e "\n-> Source environment file ${ENVIRON_FILE}" export `echo ${class_name}`_ROOT_DIR=${SALOME_BUILD_DIR}/${class_name}_INSTALL export `echo ${class_name}`_CPP_ROOT=${cpp_root_dir} export LD_LIBRARY_PATH=${lib_dir}:${LD_LIBRARY_PATH} echo $CALC_CPP_DIR echo $CALC_ROOT_DIR echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH echo echo -e "\n-> Build Configure" cd ${install_dir}/${class_name}_SRC ./build_configure cd ${SALOME_BUILD_DIR}/${class_name}_BUILD echo -e "\n-> Configure in ${SALOME_BUILD_DIR}/${class_name}_BUILD" ${install_dir}/${class_name}_SRC/configure ${CONFIGURE_OPTION} --prefix=${SALOME_BUILD_DIR}/${class_name}_INSTALL echo "Compile ?" echo read answer case $answer in y* | Y* | o* | O* ) compile ;; *) exit 1 ;; esac cd $SALOME_DIR export `echo ${SOURCE_NAME}`_ROOT_DIR=${INSTALL_ROOT_DIR}/${module}/${SOURCE_NAME}_INSTALL # Mise à jour du script d'environnement echo -e "\n\n[QUESTION] Would you like to update your environment scrip ${ENVIRON_FILE}?" echo -e -n "(add environment vaiable necessary to run and compile your salome component) : " read answer case $answer in y* | Y* | o* | O* ) update_environ ;; esac echo -e -n "\n\n[QUESTION] Would you like to launch salome ?" read answer case $answer in y* | Y* | o* | O* ) launch_salome ;; esac echo "Good Bye!" exit } # # # ------------------------------------------------------------------------ # --------------------------- MAIN PROGRAM ------------------------------- # ------------------------------------------------------------------------ # welcome # print some welcome info # check number of arguments # if [ $# -ne 3 ] then echo -e "\nBad number of arguments\n\n" usage exit fi check_arguments $1 $2 $3 # # if there is an anvironment file, source it and set compilation flag if [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ] then source ${ENVIRON_FILE} do_compile=1 # there is an environment file, we can compile else echo -e "\n[REMARK] NO environment file was specified, automatic compilation will not be done.\n\n" fi # if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ] then gene_dir=${HXX2SALOME_ROOT_DIR} else if [ ! -f parse1.awk -o ! -f parse2.awk ] then echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy" usage else gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory fi fi # # get class' name # class_name=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}` echo " Name of class :" $class_name if [ ! $class_name ] then echo -e "\nError:\n Sorry - No class definition was found!\n Please check your header file\n" exit fi # # create temporary working directory # tmp_dir="/tmp/${class_name}_${USER}" if [ -d ${tmp_dir} ] then rm -rf ${tmp_dir}/* else mkdir ${tmp_dir} fi # # go in temporary directory to work on code generation cd ${tmp_dir} # # # ------------------------- parse hxx file and generate code --------------------------------------- # echo -e "\n-> Extract public functions\n" cat ${hxx_file} | awk -f ${gene_dir}/parse1.awk > ${class_name}_public_functions cat ${class_name}_public_functions if [ ! -s ${class_name}_public_functions ] then echo -e "\nError:\n Sorry - No compatible function was found!\n Please check your header file\n" exit fi # echo -e "\n\n-> Parse public functions and generate Salome2 files\n\n compatibility function\n" cat ${class_name}_public_functions | awk -f ${gene_dir}/parse2.awk |\ awk -v class_name=${class_name} -f ${gene_dir}/parse3.awk # # outputs echo -e "\n IDL file:" cat parse_result > hxx2salome_journal echo -e "\n----------------- IDL file ------------------\n">>hxx2salome_journal cat code_idl >> hxx2salome_journal cat code_idl echo -e "\n----------------- hxx file ------------------\n" >> hxx2salome_journal cat code_hxx >> hxx2salome_journal echo -e "\n----------------- cxx file ------------------\n" >> hxx2salome_journal cat code_cxx >> hxx2salome_journal echo # # # ------------------- duplicates template module and insert generated code ------------------------------ # echo -e "\n-> Duplicate template module" cp -r ${gene_dir}/TEMPLATE_SRC ${class_name}_SRC ${gene_dir}/renameSalomeModule -i TEMPLATE ${class_name} ${class_name}_SRC >> hxx2salome_journal # echo -e "\n-> Substitute generated code in idl file" echo "// this idl file was generated by hxx2salome" > tmpfile cat ${class_name}_SRC/idl/${class_name}_Gen.idl |awk ' $0 ~ "HXX2SALOME_IDL_CODE" {system("cat code_idl >> tmpfile")} $0 != "HXX2SALOME_IDL_CODE" { print $0 >> "tmpfile" }' mv tmpfile ${class_name}_SRC/idl/${class_name}_Gen.idl # echo -e "\n-> Substitute generated code in hxx file" echo "// this hxx file was generated by hxx2salome" > tmpfile cat ${class_name}_SRC/src/${class_name}/${class_name}_i.hxx |awk ' $0 ~ "HXX2SALOME_HXX_CODE" {system("cat code_hxx >> tmpfile")} $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }' mv tmpfile ${class_name}_SRC/src/${class_name}/${class_name}_i.hxx # echo -e "\n-> Substitute generated code in cxx file" echo "// this cxx file was generated by hxx2salome" > tmpfile cat ${class_name}_SRC/src/${class_name}/${class_name}_i.cxx |awk -v cpp_include=$2 ' $0 ~ "HXX2SALOME_CXX_CODE" {system("cat code_cxx >> tmpfile")} $0 ~ "HXX2SALOME_CPP_INCLUDE" { printf "#include \"%s\"\n",cpp_include >> "tmpfile" } $0 !~ "HXX2SALOME" { print $0 >> "tmpfile" }' mv tmpfile ${class_name}_SRC/src/${class_name}/${class_name}_i.cxx # # add flags in makefile get_python_test_file get_info_makefile echo -e "\n-> Substitute flags in Makefile.in" sed "s?HXX2SALOME_INCLUDE?${makefile_include}?g s?HXX2SALOME_PYTHON_FILE?${python_test_file}?g s?HXX2SALOME_LIB?${makefile_lib}?g " ${class_name}_SRC/src/${class_name}/Makefile.in > tmpfile mv tmpfile ${class_name}_SRC/src/${class_name}/Makefile.in # # generate component catalog if [ $KERNEL_ROOT_DIR ] then echo -e "\n-> Generate component catalog\n\n" | tee hxx2salome_journal idlparser=${KERNEL_ROOT_DIR}/bin/salome/runIDLparser cd ${class_name}_SRC/resources VER=`cat ${KERNEL_ROOT_DIR}/bin/salome/VERSION | awk ' { print $NF }'` # extract number of version ${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 cat tmp.xml | sed 's/_Gen//g' > ${class_name}Catalog.xml rm tmp.xml else echo -e "\n-> CANNOT GENERATE component catalog : variable KERNEL_ROOT_DIR in not defined\n\n" | tee hxx2salome_journal fi # # # --------------------- Installation of new module sources ------------------------------------------------ # today=`date +%b%d_%Hh%M` if [ ! -d ${SALOME_SRC_DIR} ] # ask for installation directory if not specified by SALOME_SRC_DIR then echo -e "\n\nThe new module ${class_name}_SRC was generated in ${tmp_dir}" echo -e -n "[QUESTION] In which directory do you want to move it? " read install_dir else install_dir=${SALOME_SRC_DIR}/${class_name} if [ ! -d ${install_dir} ] # create module directory if necessary then mkdir ${install_dir} fi fi if [ -d ${install_dir} ] then if [ -d ${install_dir}/${class_name}_SRC ] then echo -e "A module ${install_dir}/${class_name}_SRC already exist!" echo -e "It will be renamed ${class_name}_SRC_${today}" mv ${install_dir}/${class_name}_SRC ${install_dir}/${class_name}_SRC_${today} fi echo -> Create module ${class_name}_SRC in ${install_dir} mv ${tmp_dir}/${class_name}_SRC ${install_dir} fi # # # ------------------- Modification of Salome environment file --------------------------------------------- # if [ ${do_compile} -eq 1 ] then echo -e -n "\n\n[QUESTION] Do you want to compile new module? " read answer case $answer in y* | Y* | o* | O* ) compile_module ;; esac fi good_bye