本帖最后由 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 ""
|