代码语言:shell复制
#!/bin/bash
# 自动化编译 c/c
# 开发: wanyang
# 时间: 2023.06.05
bianliang()
{
dir=`pwd` ; echo "欢迎使用自动化汇编程序,当前路径为: $dir"
sudo chmod 777 -R $dir/*
#appName=( anfang tools studay ) # 项目目录
appName=( anfang studay) # 选择性编译,或者全选
Cmake="$dir/CMakeLists.txt" # cmake 路径, 顶级目录 指定编译器
appCmakeFile="$dir/app/CMakeLists.txt" # 二级目录,桥接
toolsRunAppList=(jinzhi test tcp)
toolsCodeList=( src/jinzhi.c src/test.c src/tcp.cpp)
toolsCmakeInclude=( a b)
toolsCmakeIncludeSet=( $dir/app/tools/inc/ /datadisk/eisc/server/mysql/mariadb1011/include/mysql/server/ )
#toolsCmakeSo=( cgicc libm.so Boost )
toolsCmakeSo=(libm.so Boost) # pow 需要引用库: libm.so
anfangRunAppList=(installc login sql )
anfangCodeList=(install.cpp login.cpp sql.cpp )
anfangCmakeInclude=( a b)
anfangCmakeIncludeSet=( $dir/app/anfang/common/include/ /datadisk/eisc/server/mysql/mariadb1011/include/mysql/server/ )
anfangCmakeSo=( /datadisk/eisc/server/mysql/mariadb1011/lib/libmysqlclient.so )
studayRunAppList=( LogicSwitch )
studayCodeList=( src/LogicSwitch.c )
studayCmakeInclude=( a b)
studayCmakeIncludeSet=( $dir/app/studay/include/ /datadisk/eisc/server/mysql/mariadb1011/include/mysql/server/ )
#studayCmakeSo=( cgicc libm.so ) # pow 需要引用库: libm.so
studayCmakeSo=( libm.so )
headCmake="
project(eisc)
#项目名
cmake_minimum_required(VERSION 3.10)
# 编译要求:cmake 要大于最低版本 3.1
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g ")
# 设置编译器, 如果没有配置环境变量,可以改为gcc具体文件路径
cmake_minimum_required(VERSION 3.5)
add_subdirectory(app)
# 引用app 子目录
# 如果 echo 字符串中有 变量,需要加反斜线转义";
}
CMakeListsFile()
{
setCmakefile=$CmakeFile
sudo touch $setCmakefile
echo "" > $setCmakefile ; echo "" ; echo "#### 正在写文件 $setCmakefile #### " ; echo ""
case "$xm" in
"anfang") CmakeInclude=(${anfangCmakeInclude[*]}) ;incList=(${anfangCmakeIncludeSet[*]}) ; RunAppList=(${anfangRunAppList[*]}); CodeList=(${anfangCodeList[*]}) ; CmakeSo=(${anfangCmakeSo[*]}) ;;
"tools") CmakeInclude=(${toolsCmakeInclude[*]}) ;incList=(${toolsCmakeIncludeSet[*]}) ; RunAppList=(${toolsRunAppList[*]} ); CodeList=(${toolsCodeList[*]}) ; CmakeSo=(${toolsCmakeSo[*]} ) ;;
"studay") CmakeInclude=(${studayCmakeInclude[*]}) ;incList=(${studayCmakeIncludeSet[*]}) ; RunAppList=(${studayRunAppList[*]} );CodeList=(${studayCodeList[*]}) ; CmakeSo=(${studayCmakeSo[*]}) ;;
*) echo "未定义项目 数组" ;;
esac
# 数组和变量的定义不一样,CmakeInclude 的值不加 小括号为变量,加 括号为数组
for((i=0;i<${#CmakeInclude[*]} ;i ))
do
echo "include_directories(${CmakeInclude[$i]})" >> $setCmakefile
done
for((i=0;i<${#RunAppList[*]};i ))
do
echo "add_executable(${RunAppList[$i]} ${CodeList[$i]} )" >> $setCmakefile
echo "target_link_libraries(${RunAppList[$i]} ${CmakeSo[*]} )" >> $setCmakefile
done
}
cpBuild()
{
#linName=( Cmake BuildApp Cgibin )
linName=( Cmake BuildApp )
for xm in ${appName[*]}
do
sudo mkdir -p cgi-bin/$xm
sudo chmod 777 -R cgi-bin/$xm
#for((i=0;i<${#appCmakeFile[*]};i ))
for((i=0;i<1;i ))
do # 动态变量的写入
eval ${appName[$i]}${linName[0]}="$dir/app/$xm/CMakeLists.txt" # 三级目录(目前三级是最终目录) 跟随 $xm 项目名字 :anfang 或 tools
eval ${appName[$i]}${linName[1]}="$dir/build/app/$xm" # gcc g 编译二进制文件路径 (由 make.sh 决定 固定目录 )
eval ${appName[$i]}${linName[2]}="$dir/cgi-bin/$xm" # c web 软件运行路径(自定义)
CmakeFile=$(eval echo '$'${appName[$i]}${linName[0]}) # 动态变量里面的数值读取,而不是获取名称
runDirs=$(eval echo '$'${appName[$i]}${linName[1]})
cbinDir=$(eval echo '$'${appName[$i]}${linName[2]})
CMakeListsFile ; autoINCPath ; cmake ./ -Bbuild ; cmake --build build
echo "项目 $xm 当前目录:$runDirs 拷贝到 cbin : $cbinDir "
runSelect=`ls $runDirs | grep -vE "make|Make|file|File"`
for runFiles in ${runSelect[*]}
do
cp -r $runDirs/$runFiles $cbinDir/
echo "复制文件 $runDirs/$runFiles -> $cbinDir/ "
done
done
done
}
autoINCPath(){
file=$setCmakefile
incNumber=`cat -n $file | grep -w include_directories | wc -l` # wc -l 计算个数
echo "[runing] 当前项目 $xm 查看文件 $file 中的 include "
echo "[runing] include 目标修改已经由函数 CMakeListsFile 函数定义 incList 数组 "
# 路径为绝对路径,相对路径会报错. 此数组个数与 CMakeLists.txt 中的 include_directories 个数对应
if [ "$incNumber" != "${#incList[*]}" ]
then
echo "$file 文件 include_directories 定义个数 $incNumber 与 ${#incList[*]} 目标修改个数不相等,无法对应修改。"
echo "请在 touchCMake 和 autoINCPath 函数, 增加或者 删除 include_directories 关键字个数,以达到与目标修改个数一致。然后重新执行脚本"
exit
else
incI=0;
#while :
for((;;))
do
incNumberList=(`cat -n $file | grep -w include_directories | grep -v okset| awk -F" " '{print $1}' `)
Number=${#incNumberList[*]}
NR=${incNumberList[0]}
if [ "$Number" -lt "1" ]
then
echo "[ok] 当前绝对路径已经全部修正, 正在执行 CMakeLists.txt 自动化编译。 "
break
fi
echo "[runing] 当前游标:$incI 当前修改行:$NR 当前剩余总修改次数: $Number 文件:$file 所有行:${incNumberList[*]} 目标内容:${incList[$incI]} "
sed -i "$NR a include_directories( ${incList[$incI]} ) # [eisc.cn_okset]" $file
sed -i "$NR d " $file
# 始终修改第一个元素,然后由于循环再去查找行号
# 错误方式,删除一行后,其他内容行号会变,因此每次删除,需要重新扫描行号
# [okset] 修改了的地方做标记
let "incI "
# 先获取 0 后,再自动增加。而不是 先增加: 0 1 第一次为 1
sleep 0.01
done
fi
}
qiaoCMakeLists()
{
sudo touch CMakeLists.txt ; sudo chmod 777 CMakeLists.txt ;
echo "" > $appCmakeFile;
echo " $headCmake" > $Cmake
for i in ${appName[*]}
do
echo "add_subdirectory($i)" >> $appCmakeFile
done
echo "已经在目录 $appCmakeFile 创建二级 cmake 桥 " ; cat $appCmakeFile
echo "
#-----------------------------------------------------------------------------------------------------------#
# 重点: eval 动态变量 给带美元符号的变量赋值。一般情况: 加美元符号的变量 是获取打印 其值,而不能被定义值) #
#-----------------------------------------------------------------------------------------------------------#
$a$b$c=$y$k # 带美元符号的变量 这样赋值会报错:有歧义的重定向
eval $a$b$c=$y$k # 加参数 eval 则合规 动态变量 ";
echo "";
}
canguan()
{
echo "
anfangCmake="$dir/app/anfang/CMakeLists.txt" # 三级目录(目前三级是最终目录)
anfangBuildApp="$dir/build/app/anfang" # gcc g 编译路径 (由 make.sh 决定 固定目录 )
anfangCgibin="$dir/cgi-bin/anfang" # c web 软件运行路径(自定义)
toolsCmake="$dir/app/tools/CMakeLists.txt"
toolsBuildApp="$dir/build/app/tools"
toolsCgibin="$dir/cgi-bin/tools"
" ;
}
main()
{
sudo rm -rf ./build ./cgi-bin/*;
bianliang ; qiaoCMakeLists ; cpBuild;
#$dir/cgi-bin/anfang/installc
#$dir/cgi-bin/anfang/sql
#$dir/cgi-bin/anfang/login
#$dir/cgi-bin/tools/jinzhi
}
main