前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >shell 自动生成 CMakeLists.txt 自动编译c语言

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

原创
作者头像
eisc
修改2024-03-15 19:16:59
1.1K0
修改2024-03-15 19:16:59
举报
文章被收录于专栏:linux 自动化运维
代码语言: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 



原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档