#! /bin/bash # Copyright (C) 2006-2016 CEA/DEN, EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # BE_QUIET=0 # salome2 environment file (.bash or .sh) - can also be specified with -e option ENVIRON_FILE= # 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! # # options you want to pass to configure CONFIGURE_OPTION= # # which wrappers to generate declare -a GEN iCPP=0 iCORBA=1 iPython=2 GEN[${iCPP}]="no" GEN[${iCORBA}]="no" GEN[${iPython}]="no" # usage() { echo -e "\n Usage :\n" echo -e " Set HXX2SALOME_ROOT_DIR variable" echo -e " ${HXX2SALOME_ROOT_DIR}/hxx2salome [options] " echo -e " cppComponent_root_dir cppComponent.hxx" echo -e " libcppComponent.so salomeComponentRoot\n" echo -e " - cppComponent_root_dir : install directory (absolute path)" echo -e " of the c++ component\n" 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" echo -e " in cppComponent_root_dir)\n" echo -e " - salomeComponentRoot : directory of the source/build/install" echo -e " of the Salome component\n" echo -e " Options :" echo -e " -h : this help" echo echo -e " -q : be quiet" echo echo -e " -x Lang : generate a wrapper to use the component" echo -e " from language Lang where Lang can be " echo -e " any of CORBA,C++,python" echo -e " (several -x options can be specified)" echo -e " default : generate all wrappers" echo echo -e " -e environment_script : to specify the name of a environment file" echo -e " that will be updated with new necessary commands" echo -e " (this file is also used for sourcing environment" echo -e " before compilation if it has sh or bash syntax," echo -e " if the syntax is csh, it is not sourced and for" echo -e " compiling (-c option) environment must be set up" echo -e " before)" echo echo -e " -s script_extension : to use if your environment file name doesn't" echo -e " have extension" echo echo -e " -g : to create a gui part in your component" echo -e " building tree" echo echo -e " -c : to compile after generation" echo -e " (use this option only if you don't have" echo -e " dependencies in your header or libraries" echo -e " if it is the case, you'll have to adapt" echo -e " your Makefile.am" echo echo -e " -l : to launch salome " exit } # welcome() { echo -e "\n\n" echo "----------------------------------------------------------------------------" echo echo " hxx2salome" echo echo " Automatic generation of a Salome2 component from a C++ component" echo echo "----------------------------------------------------------------------------" echo echo echo } if [ "x$HXX2SALOME_ROOT_DIR" == "x" ] then usage fi source ${HXX2SALOME_ROOT_DIR}/hxx2salome_check source ${HXX2SALOME_ROOT_DIR}/hxx2salome_corba source ${HXX2SALOME_ROOT_DIR}/hxx2salome_cpp # retrieve python test file ending up with _test.py get_python_test_file() { cd ${CPP_ROOT_DIR} for file in `find . -name "*_test.py"` do cp $file ${tmp_dir}/${CLASS_NAME}_SRC/src/${CLASS_NAME} python_test_file=${python_test_file}" "`basename $file` done if [ ${BE_QUIET} -lt 1 ] ; then echo -e "\nList of exported python file test : $python_test_file \n" fi cd - } create_component_tree() { INSTALL_DIR=${salomeComponentRoot}/${CLASS_NAME} export NEW_COMPONENT_SRC_DIR=${INSTALL_DIR}/${CLASS_NAME}_SRC export NEW_COMPONENT_BUILD_DIR=${INSTALL_DIR}/${CLASS_NAME}_BUILD export NEW_COMPONENT_ROOT_DIR=${INSTALL_DIR}/${CLASS_NAME}_INSTALL \rm -rf ${NEW_COMPONENT_SRC_DIR} mkdir -p ${NEW_COMPONENT_SRC_DIR} } get_info_makefile() { makefile_lib="-L\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}} -l${lib_file}" makefile_include="-I\${${CLASS_NAME}CPP_ROOT_DIR}${hxx_dir#${CPP_ROOT_DIR}}" if [ ${BE_QUIET} -lt 1 ] ; then echo -e "\nlinking option : $makefile_lib" echo -e "include option : $makefile_include" fi } generate_module_source() { # # go in temporary directory to work on code generation cd ${tmp_dir} # # # ------------------------- parse hxx file : generic part --------------------------------------- # cat ${hxx_file} | \ awk -f ${gene_dir}/parse01.awk | \ awk -f ${gene_dir}/parse1.awk | \ awk -f ${gene_dir}/parse2.awk \ > temp sed -e "/${CLASS_NAME}/d" < temp > ${CLASS_NAME}_public_functions if [ ${BE_QUIET} -lt 1 ] ; then echo -e "\n-> Extract public functions\n" fi if [ ! -s ${CLASS_NAME}_public_functions ] then echo -e "\nError:" echo -e " Sorry - No compatible function was found!" echo -e " Please check your header file\n" exit fi echo -e "\n\n-> Compatibility function\n" cat ${CLASS_NAME}_public_functions | \ awk -v class_name=${CLASS_NAME} -f ${gene_dir}/parse30.awk \rm -f hxx2salome_journal && touch hxx2salome_journal if [ ${BE_QUIET} -lt 1 ] ; then echo -e "\n-> Duplicate template module" | tee ../hxx2salome_journal fi cp -rf ${gene_dir}/HXX2SALOME_GENERIC_CLASS_NAME_SRC ${CLASS_NAME}_SRC cp -f ${gene_dir}/compile_HXX2SALOME_GENERIC_CLASS_NAME.sh compile_${CLASS_NAME}.sh ${gene_dir}/renameSalomeModule -i HXX2SALOME_GENERIC_CLASS_NAME \ ${CLASS_NAME} ${CLASS_NAME}_SRC >> ../hxx2salome_journal GEN=( `validate_generation_choices ${GEN[${iCPP}]} ${GEN[${iCORBA}]} ${GEN[${iPython}]}` ) echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]} CORBA : ${GEN[${iCORBA}]} Python : ${GEN[${iPython}]} if [ "x${GEN[${iCORBA}]}" == "xyes" ] ; then generate_corba_module_source else clean_corba_module_source fi if [ "x${GEN[${iCPP}]}" == "xyes" ] ; then generate_cpp_module_source else clean_cpp_module_source fi } compile() { echo "----------------- Configure -------------------" echo "----------------- Compile ---------------------" make if [ $? -eq 0 ] then # compilation succeeded : we make install echo echo "----------------- Install ---------------------" make install else exit 1 fi } update_environment() { if [ -z ${ENVIRON_FILE} ] then ENVIRON_FILE="${NEW_COMPONENT_SRC_DIR}/env_${CLASS_NAME}.${SHELL_EXT}" fi if [ ${BE_QUIET} -lt 1 ] ; then echo -e "\nEnvironment file : " $ENVIRON_FILE fi if [ -e ${ENVIRON_FILE} ] then cp ${ENVIRON_FILE} ${ENVIRON_FILE}.old fi touch ${ENVIRON_FILE} if [ "${SHELL_EXT}" == "csh" ] then grep -q " ${CLASS_NAME}_SRC_DIR" ${ENVIRON_FILE} res=$? if [ $res == 1 ] then echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE} echo -e "setenv ${CLASS_NAME}_BASE ${INSTALL_DIR}" >> ${ENVIRON_FILE} echo -e "setenv ${CLASS_NAME}_SRC_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE} fi grep -q " ${CLASS_NAME}_ROOT_DIR" ${ENVIRON_FILE} res=$? if [ $res == 1 ] then echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE} echo -e "setenv ${CLASS_NAME}_ROOT_DIR \${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE} echo -e "setenv ${CLASS_NAME}CPP_ROOT_DIR ${CPP_ROOT_DIR}" >> ${ENVIRON_FILE} echo -e "setenv LD_LIBRARY_PATH \${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" >> ${ENVIRON_FILE} fi fi if [ "${SHELL_EXT}" == "sh" ] then grep -q " ${CLASS_NAME}_SRC_DIR=" ${ENVIRON_FILE} res=$? if [ $res == 1 ] then echo -e "###\n#------ ${CLASS_NAME}-Src ------" >> ${ENVIRON_FILE} echo -e "export ${CLASS_NAME}_BASE=${INSTALL_DIR}" >> ${ENVIRON_FILE} echo -e "export ${CLASS_NAME}_SRC_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_SRC\n" >> ${ENVIRON_FILE} fi grep -q " ${CLASS_NAME}_ROOT_DIR=" ${ENVIRON_FILE} res=$? if [ $res == 1 ] then echo -e "###\n#------ ${CLASS_NAME}-Bin ------" >> ${ENVIRON_FILE} echo -e "export ${CLASS_NAME}_ROOT_DIR=\${${CLASS_NAME}_BASE}/${CLASS_NAME}_INSTALL" >> ${ENVIRON_FILE} echo -e "export ${CLASS_NAME}CPP_ROOT_DIR=${CPP_ROOT_DIR}" >> ${ENVIRON_FILE} echo -e "export LD_LIBRARY_PATH=\${${CLASS_NAME}CPP_ROOT_DIR}${lib_dir#${CPP_ROOT_DIR}}:\${LD_LIBRARY_PATH}" \ >> ${ENVIRON_FILE} fi fi } copy_component_source() { mv ${tmp_dir}/${CLASS_NAME}_SRC/* ${NEW_COMPONENT_SRC_DIR} mkdir -p ${NEW_COMPONENT_BUILD_DIR} mkdir -p ${NEW_COMPONENT_ROOT_DIR} } good_bye() { if [ ${BE_QUIET} -gt 0 ] ; then return fi echo -e "\n\nModule was created in ${NEW_COMPONENT_SRC_DIR}" } # # # ------------------------------------------------------------------------ # --------------------------- MAIN PROGRAM ------------------------------- # ------------------------------------------------------------------------ # CPP_ROOT_DIR= NEW_COMPONENT_ROOT_DIR= NEW_COMPONENT_SRC_DIR= NEW_COMPONENT_BUILD_DIR= SHELL_EXT=sh do_compile=0 do_launch=0 make_gui=0 # welcome # print some welcome info # while getopts "qcs:e:h:lgx:" Option do case $Option in h) usage exit;; q) BE_QUIET=$[ ${BE_QUIET}+1 ] ;; e) ENVIRON_FILE=$OPTARG;; s) case $OPTARG in bash) SHELL_EXT=sh;; csh) SHELL_EXT=csh;; *) SHELL_EXT=sh;; esac;; g) make_gui=1;; c) do_compile=1;; l) do_launch=1;; x) case $OPTARG in CORBA) GEN[$iCORBA]="yes" ;; python) GEN[$iPython]="yes" ;; C++) GEN[${iCPP}]="yes";; *) ;; esac;; *) echo "Unimplemented option chosen : $Option." usage exit;; # DEFAULT esac done shift $(($OPTIND - 1)) # default behaviour is to generate all wrappers # if [ "x${GEN[${iCPP}]}${GEN[${iCORBA}]}${GEN[${iPython}]}" == "xnonono" ] ; then for i in ${iCPP} ${iCORBA} ${iPython} do GEN[$i]="yes" done fi echo "-> Wrappers generation : " C++ : ${GEN[${iCPP}]} CORBA : ${GEN[${iCORBA}]} Python : ${GEN[${iPython}]} echo echo # check number of other arguments # if [ $# -ne 4 ] then echo -e "\nBad number of arguments\n\n" usage exit fi check_arguments $1 $2 $3 $4 # # if there is a sh compatible environment file, source it if [[ -n ${ENVIRON_FILE} && -f ${ENVIRON_FILE} ]] then # analyse extension of environment file case ${ENVIRON_FILE##*\.} in bash) SHELL_EXT=sh;; ksh) SHELL_EXT=sh;; csh) SHELL_EXT=csh;; sh) SHELL_EXT=sh;; esac fi # Environment policy : # - an existing sh file was specified : we source environment file # - else (no file or csh syntax) : we don't source environment file, and do compile # only if KERNEL_ROOT_DIR and MED_ROOT_DIR are defined if [ "${SHELL_EXT}" == "sh" ] && [ ${ENVIRON_FILE} ] && [ -f ${ENVIRON_FILE} ] then echo -e "\n Environment file with sh syntax specified => we source ${ENVIRON_FILE}" source ${ENVIRON_FILE} fi # if [ ${HXX2SALOME_ROOT_DIR} ] && [ -d ${HXX2SALOME_ROOT_DIR} ] then gene_dir=${HXX2SALOME_ROOT_DIR} else gene_dir=`pwd` # case where hxx2salome was launched from HXX2SALOME directory fi OLD_DIR=`pwd` cd $gene_dir gene_dir=`pwd` cd $OLD_DIR if [ ${BE_QUIET} -lt 1 ] ; then echo " hxx2salome directory : $gene_dir" fi if [ ! -f ${gene_dir}/parse1.awk -o ! -f ${gene_dir}/parse2.awk ] # check if script are found then echo -e "\nError : Variable HXX2SALOME_ROOT_DIR shoud be set, or hxx2salome should be launched localy from bin directory" usage fi # # get class name # CLASS_NAME=`awk '$1 == "class" && $0 !~ /;/ {print $2}' ${hxx_file}|awk -F: '{print $1}'` 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/${USER}/${CLASS_NAME}" if [ -d ${tmp_dir} ] then rm -rf ${tmp_dir}/* else mkdir -p ${tmp_dir} fi # # --------------------- Generation of module source from template ------------------------------------------ # get_info_makefile generate_module_source # # ---------------------- Installation of new module sources ------------------------------------------------ # create_component_tree # # ---------------------- Modification of Salome environment file ------------------------------------------- # update_environment export `echo ${CLASS_NAME}`_ROOT_DIR=${NEW_COMPONENT_ROOT_DIR} # to avoid resource env for compiling and launching salome export `echo ${CLASS_NAME}`CPP_ROOT_DIR=${CPP_ROOT_DIR} # idem # # ---------------------- Copy the generated source from temp dir ------------------------------------------- # copy_component_source good_bye echo -e "\nGeneration done\n"