Fortran Coder

查看: 5288|回复: 2
打印 上一主题 下一主题

[编译器] 自动生成makefile脚本

[复制链接]

2

帖子

2

主题

0

精华

入门

F 币
45 元
贡献
22 点
跳转到指定楼层
楼主
发表于 2021-10-1 21:18:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Zouyk 于 2021-10-2 22:40 编辑

脚本说明:
    本脚本用于自动扫描源程序文件中的语句,自动生成makefile,方便项目的开发。对于fortran,程序中使用了模块,将会在编
译时生成*.mod文件。对于使用makefile编译项目带来一定的麻烦,网上存在解决的办法,但并不满意,特别是出现模块嵌套会出现
编译错误的问题。为此只能手工为每个原程序写makefile语句解决这种难缠的依赖问题。

    使用这个脚本智能度较低,只能委屈各尊修改下文件名方便脚本程序的识别,和一些编程习惯;只有这样才能自动生成一份令
大家满意,并用的快乐的makefile。
    一、每个源文件 “ 只能放一个模块过程 ”
    二、源文件名必须按照格式:mod_[模块名].xxx 格式,例如在源文件是:
           module mod_Example
               implicit none
               real :: xxx
                    *
                    *
                    *
           end module mod_Example
        那么,这个源文件名必须是:mod_Example.f95,后缀可以自便。
    三、主程序文件必须命名为:Main,例如Main.f95,注意大小写,必须是Main。
    四、本脚本在Fedora 31下开发,bash版本为5.0.17,其他平台可能需要根据你的bash做些少改动。




[Fortran] 纯文本查看 复制代码
/bin/bash
#====================================  参  数  设  置  ===========================================

Suff='f03'                      #源文件后缀
MkFile='makefile'               #makefile文件名
TargetName='debug'              #目标程序名
FortComp='gfortran'             #编译器
FortFlag='-c -O2 -std=f2003'    #编译器选项

#=================================================================================================

#检查有没有makefile文件。如有,删掉
if [ -e ${MkFile} ];then
     rm -rf ${MkFile}
fi

#写入编译器和编译器选项信息到makefile
echo 'FC='${FortComp} > ${MkFile}
echo 'Flag='${FortFlag} >> ${MkFile}

#写入目标程序名称到makefile
echo '' >> ${MkFile}
echo 'target='${TargetName} >> ${MkFile}



#----------------------------------------------------------------------------------------------------------------
#读入所有的源文件名称,并写到源码目录里
NameTmp=Files.lst
ls *.${Suff} > ${NameTmp}

#扫描文件,获取所有的模块程序文件文件
All_Mods=""
while read lines
do
   FileName=$(echo ${lines} | awk -F. '{print $1}')            #从源文件目录中按扩展名提取文件名
   FileType=$(echo ${FileName} | awk -F_ '{print $1}' )        #获取文件性质,mod还是其他
   ModName=$(echo ${FileName} | awk -F_ '{print $2}' )         #获取模块名称

   if [ x${ModName} != 'x' ];then
     All_Mods=${All_Mods}mod_${ModName}.o" "
   fi
done < ${NameTmp}

#写入所有依赖模块到makefile
echo "All="${All_Mods} >> ${MkFile}
echo "" >> ${MkFile}


#----------------------------------------------------------------------------------------------------------------
#写入主程序的依赖信息到makefile
if [ -e Main.${Suff} ];then
   echo '$'{target}":Main.o "'$'{All} >> ${MkFile}
   echo -e '\t''$'{FC} '$'^ -o '$'@ >> ${MkFile}
   echo "" >> ${MkFile}
fi


#----------------------------------------------------------------------------------------------------------------
#依次打开原文件查找依赖的模块
while read Lines
do
   Mod_Used=''
   echo ""
   echo "检查源文件《"${Lines}"》所依赖的模块文件:"
   theName=$(echo ${Lines} | awk -F. '{print $1}')             #提取本行源文件程序名(去除扩展名)

   #打开原文件,逐行检查,发现use字眼,提取模块的名称
   while read SrcLine
   do
     isUsed=$(echo ${SrcLine} | awk -F' ' '{print $1}')
     if [ x${isUsed} == "xuse" ];then 
       WhichMod=$(echo ${SrcLine} | awk -F' ' '{print $2}')

       #检查是否存在模块名称对应的源码文件,若存在源文件则统计记录
       if [ -e ${WhichMod}.${Suff} ];then
         echo "    找到源文件:"${WhichMod}.${Suff}
         Mod_Used=${Mod_Used}${WhichMod}.o" "
       else
         echo "    !!!  警告,未找到模块"${Mod_Used}"的源文件  -> "${Mod_Used}.${Suff}
       fi

     fi
   done < ${Lines}

    #写入本源文件和依赖关系到makefile
    if [ x${Lines} != 'x' ];then
        echo ${theName}.o : ${Lines} ${Mod_Used} >> ${MkFile}
        echo -e '\t''$'{FC} '$'{Flag} '$''<' -o '$'@ >> ${MkFile}
        echo "" >> ${MkFile}
    fi
done < ${NameTmp}


#----------------------------------------------------------------------------------------------------------------
#写入makefile的命令部分
echo ".PHONY:" >> ${MkFile}

#make run 部分
echo "run:" >> ${MkFile}
echo -e "\t-./"'$'{target} >> ${MkFile}

#make Clean 部分
echo "clean:" >> ${MkFile}
echo -e "\trm -rf *.o" >> ${MkFile}
echo -e "\trm -rf *.mod" >> ${MkFile}

#make CleanAll 部分
echo "CleanAll:" >> ${MkFile}
echo -e "\trm -rf *.o" >> ${MkFile}
echo -e "\trm -rf *.mod" >> ${MkFile}
echo -e "\trm -rf "'$'{target} >> ${MkFile}     #连目标程序一并铲除

#----------------------------------------------------------------------------------------------------------------
#清除临时文件:
rm -rf ${NameTmp}
echo ""
echo "    =================================================================="
echo "    =                                                          ="
echo "    =            现在,可以执行make命令编译这个工程了。                ="
echo "    =                                                                                  ="
echo "    =================================================================="
echo ""



分享到:  微信微信
收藏收藏1 点赞点赞1 点踩点踩

80

帖子

26

主题

0

精华

专家

F 币
280 元
贡献
150 点
沙发
发表于 2024-5-13 16:36:41 | 只看该作者
您这个强大。我对脚本不熟悉,请问是把你这个代码保存为PreMake.sh,然后就可以在shell里 ./PreMake.sh 就可以了?

80

帖子

26

主题

0

精华

专家

F 币
280 元
贡献
150 点
板凳
发表于 2024-5-13 17:45:47 | 只看该作者
您这个是在Ubuntu上运行./PreMake.sh吗?我在Ubuntu上运行,没有任何反应,关闭终端时,会显示有一个脚 本正在运行,强制关掉后,会输出一个makefile,接下来make,会提 示各种错误。请问,您这个脚本是在什么环境下运行呢?
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-24 20:54

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表