使用bakefile编译C工程代码

一、前言

最近有个想法,想把 ineedle 整体架构从头自己编写代码来实现一下,来加深对iNeedle系统的理解,同时加强Linux + C相关知识。由于iNeedle系统的庞大,只能是先把框架搭起来,根据某些功能再往里边添加东西。首先遇到的问题就是每写一部分代码都要进行调试,既不想使用gcc独立的命令来进行调试,这样代码多了或路径复杂就难以控制;又不想使用iNeedle原版的编译文件,于是自己按照旧版本抽取出需要编译iNeedle系统的脚本代码来。这个脚本用来编译iNeedle项目,主要是利用了bakefile工具。bakefile是一个跨平台的自动生成makefile的开源工具,需要在项目中的每个子目录中指定***.bkl配置文件(该配置文件指定需要编译哪些文件,指定头文件等),bakefile利用每个子目录中bkl文件来生成相应的makefile文件;然后在主目录(编译文件所在目录)中生成主makefile文件,由主makefile直接进行系统编译,生成可执行程序。

1、如果CentOS系统安装:

yum install bakefile -y

2、如果debian或ubuntu系统:
需要源码安装,可以到官网下载bakefile-0.2.9.tar.gz版本的即可:

tar -zxvf bakefile-0.2.9.tar.gz; 
cd bakefile-0.2.9; 
./configure; 
make; 
make install

二、bakefile使用

bakefile -f gnu "$folder.bkl" -o "$folder.mk" >/dev/null 2>&1

单独使用使用make命令进行编译:

make -f ineedle.mk install

三、bkl文件参考

 1 <?xml version="1.0"?>
 2 <makefile>
 3     <template id="posT">
 4         <include>../include/pcap</include>
 5         <include>../include/</include>
 6         <include>./</include>
 7         <sources>pos/pos_lib.c</sources>
 8         <sources>pos/pos_var.c</sources>
 9         <sources>pos/db_var.c</sources>
10         <sources>pos/pos_db.c</sources>
11         <sources>pos/hk.c</sources>
12         <sources>pos/hashfunctions.c</sources>
13         <sources>pos/md5.c</sources>
14         <sources>pos/ios_time.c</sources>
15         <sources>pos/pos_ut.c</sources>
16         <sources>pos/ios_sparse.c</sources>
17         <sources>pos/pos_lock.c</sources>
18         <sources>pos/iweb_api.c</sources>
19         <sources>pos/db_clean.c</sources>
20         <sources>pos/pos_mem.c</sources>
21     </template>
22     <exe id="pos_obj" template="posT"></exe>
23 </makefile>

四、iNeedle系统编译脚本

#!/bin/bash
#
#    这个编译文件是从老版本compile.dat中提取出来单独编译ineedle的,目的是用来调试ineedle使用的。
#
project_name="ineedle"
project_modl="root shell pos cfg ilog session sha timer traf filter istat lex monitor cron http report diskdb dll alarm snmp persist system"
project_shuc="nd"
project_targ="ineedle"
project_cmpa="-L../lib/linux -lpcap -lmysqlclient  -lhasp_linux_96828 -rdynamic -ldl -lnetsnmp"
project_macr="DBG DBG2 INEEDLE_ROOT NCURSES _INEEDLE_AMON _INEEDLE_USTAT _INEEDLE_URL _INEEDLE_CIP _INEEDLE_WEBDELAY _INEEDLE_AMON_ABN _INEEDLE_ALARM _INEEDLE_ELOG _INEEDLE_POST _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _LARGEFILE64_SOURCE "

compileFlag="debug"
splitter="------------------------------------------------------"
SECFLAG=`expr 0`

function show_copyright()
{
    tput clear
    tput smso
    echo $splitter
    echo "         iNeedle Compiler &copyright dztec.cn         "
    echo $splitter
    echo
    tput rmso
}

function loopmodules()
{
    modules=$project_modl
    echo $spiltter
    echo "generating module files......"
    echo $spiltter

    for folder in $modules;do
        #echo $folder
        folder=`expr $folder | tr -d ' '`
        filepath="$folder/$folder.bkl"
        #echo $filepath
        if [ ! -r "$filepath" ];then
            echo -n -e "file: '$filepath' doesnot exit!"
            tput blink
            echo -e "	Plz check the file"
            tput sgr0
            SECFLAG=`expr 1`
            continue
        fi
        
        cd "$folder"
        folderlen=`expr length $folder`
        if [ $folderlen -lt 3 ];then
            echo -n -e "generating $folder.mk ......   				"
        else
            echo -n -e "generating $folder.mk ......   			"
        fi

        if ! bakefile -f gnu "$folder.bkl" -o "$folder.mk" >/dev/null 2>&1 ;then
            tput smso
            tput smul
            echo "[FAILED]"
            cd "../"
            tput rmso
            tput sgr0
            SECFLAG=`expr 1`
            continue
        fi
        tput blink
        tput smul
        echo "[OK]"
        tput sgr0
        cd "../"
    done
}

function genemake()
{
    target=ineedle
    compileMacro=$project_macr
    targetMakeFile="ineedle.mk"
    modules=$project_modl
    compile_arg=$project_cmpa
    if [ $compileFlag == "debug" ];then
        CFLAGS="CFLAGS=-g"
        release="-g"
        for flg in $compileMacro
        do
            CFLAGS="$CFLAGS -D$flg"
        done
    fi
    rm $targetMakeFile >/dev/null 2>&1
    echo "TARGET = $target" >> $targetMakeFile
    echo "$CFLAGS" >> $targetMakeFile
    HEAD=""

    for folder in $modules
    do
        FOLD=`expr $folder | tr a-z A-Z`
        HEAD="$HEAD $("$FOLD"_OBJ_OBJECTS)"
        echo "include $folder/$folder.mk" >> $targetMakeFile
    done

    echo >> $targetMakeFile
    echo "install:$target">>$targetMakeFile
    echo >> $targetMakeFile
    echo "$target:$HEAD">>$targetMakeFile
    echo -e -n "	$(CC)$HEAD $release -o $target $compile_arg" >>$targetMakeFile

}

function parseerror()
{
    echo $splitter
    warnings=`cat .temp | grep -E "warning" | wc -l`
    tput smso
    echo -n "WARNINGS: "
    tput rmso
    echo $warnings
    tput smso
    echo -n "ERRORS: "
    echo "--"
    tput rmso
    echo
    cat .temp | grep -E -i "cannot|multiple|undefined|Error|Stop" | sed 's/.*/(.*/.*)/1/'
    echo $splitter
}

function move_compile_files()
{
    target="ineedle"
    mv *.o ../obj >/dev/null 2>&1
    mv *.d ../obj >/dev/null 2>&1
    mv ./$target ../release/ >/dev/null 2>&1
    chmod u+s ../release/$target
    chmod g+s ../release/$target
}

function compile()
{
    target=ineedle
    targetMakeFile=ineedle.mk
    if make -f $targetMakeFile install >.temp 2>&1 ;then
        echo $splitter
        tput smso
        echo "Compiled successfully!"
        tput rmso
        echo $splitter
        echo
    else
        parseerror
        tput smso
        echo "Compiling failed!"
        tput rmso
        echo $spiltter
    fi
    cat .temp | grep -V ".mk|gcc -c -o" >.warning
}


function run()
{
    pnn="ineedle"

    tput smso
    echo $splitter
    tput rmso
    tput smso
    echo "compiling $pnn......"
    tput rmso
    tput smso
    echo $splitter
    tput rmso
    
    loopmodules

    if [ $SECFLAG == 1 ]; then
        echo $splitter
        tput smso
        echo "error happened"
        tput rmso
        echo $splitter
        exit
    fi

    genemake
    compile
    move_compile_files   
}

function load_header_file()
{
    if [ -r "./ineedle-linux.h" ];then
        cp ineedle-linux.h ineedle.h
    fi
}

load_header_file
show_copyright
run
原文地址:https://www.cnblogs.com/liwei0526vip/p/4977396.html