shell 自动生成 CMakeLists.txt 自动编译c语言

2024-03-15 19:16:59 浏览数 (2)

代码语言: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 



0 人点赞