1. 安装打包工具

apt-get install -y build-essential
apt-get install -y ruby rubygems ruby-dev
#gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
#gem sources -l
gem install fpm

2. 构建目录结构

tree文件

root@gmzhang-dev:/home/gmzhang/work/dongfeng/deb-build/5gc-c-build# tree
.
├── build.sh
├── README.md
└── source
    ├── 5gc-c.service
    ├── amf
    │   └── amf1
    │       ├── bin
    │       │   └── amf
    │       ├── config
    │       │   ├── amf.conf
    │       │   └── asn.log.properties
    │       ├── context
    │       │   └── SystemVersionDB
    │       ├── data
    │       │   └── statistics
    │       ├── licensefile -> ../../licensefile
    │       ├── log
    │       ├── startup.sh
    │       └── xml
    │           ├── amfInfo.xml
    │           ├── ausf.xml
    │           ├── guami.xml
    │           ├── nrf.xml
    │           ├── pcf-am-policy-data.xml
    │           ├── pcf-ue.xml
    │           ├── udm-am-subscription-data.xml
    │           ├── udm-smf-selection.xml
    │           └── udm-ue.xml
    ├── ausf
    │   └── ausf1
    │       ├── bin
    │       │   └── ausf
    │       ├── config
    │       │   ├── asn.log.properties
    │       │   └── ausf.conf
    │       ├── context
    │       │   └── SystemVersionDB
    │       ├── data
    │       │   └── statistics
    │       ├── licensefile -> ../../licensefile
    │       ├── log
    │       └── xml
    │           ├── ausf-example.xml
    │           ├── guami-example.xml
    │           ├── nrf-example.xml
    │           ├── pcf-am-policy-data-example.xml
    │           ├── pcf-ue-example.xml
    │           ├── udm-am-subscription-data-example.xml
    │           ├── udm-smf-seleciont-example.xml
    │           └── udm-ue-example.xml
    ├── init.sh
    ├── lib
    │   ├── grpc
    │   │   ├── libaddress_sorting.a
    │   │   ├── libgpr.a
    │   │   ├── libgrpc.a
    │   │   ├── libgrpc++.a
    │   │   ├── libgrpc_cronet.a
    │   │   ├── libgrpc++_cronet.a
    │   │   ├── libgrpc++_error_details.a
    │   │   ├── libgrpcpp_channelz.a
    │   │   ├── libgrpc++_reflection.a
    │   │   ├── libgrpc_unsecure.a
    │   │   ├── libgrpc++_unsecure.a
    │   │   ├── libprotobuf.a
    │   │   ├── libprotobuf-lite.a
    │   │   └── libprotoc.a
    │   ├── libboost_filesystem.a
    │   ├── libboost_system.a
    │   ├── libboost_thread.a
    │   ├── libcdr.a
    │   ├── libcrypto.a
    │   ├── libcrypto.so
    │   ├── libcrypto.so.1.0.0
    │   ├── libcrypto.so.1.1
    │   ├── libcurl.a
    │   ├── libev.a
    │   ├── libev.so
    │   ├── libev.so.3
    │   ├── libev.so.3.0.0
    │   ├── libhiredis.a
    │   ├── liblog4cplus.a
    │   ├── liblog4cplus.so
    │   ├── liblog4cplus.so.2
    │   ├── liblog4cplus.so.2.0.0
    │   ├── libngapR15.a
    │   ├── libnghttp2.a
    │   ├── libssl.a
    │   ├── libssl.so
    │   ├── libssl.so.1.0.0
    │   ├── libssl.so.1.1
    │   ├── libusrsctp.a
    │   ├── libusrsctp.so
    │   ├── libusrsctp.so.1
    │   ├── libusrsctp.so.1.0.0
    │   ├── libxerces-c.a
    │   └── opensaf46
    │       ├── libopensaf_core.a
    │       ├── libopensaf_core.so
    │       ├── libopensaf_core.so.0
    │       ├── libopensaf_core.so.0.2.0
    │       ├── librda.a
    │       ├── librda.so
    │       ├── librda.so.0
    │       ├── librda.so.0.0.0
    │       ├── libSaAmf.a
    │       ├── libSaAmf.so
    │       ├── libSaAmf.so.0
    │       ├── libSaAmf.so.0.2.1
    │       ├── libSaCkpt.a
    │       ├── libSaCkpt.so
    │       ├── libSaCkpt.so.1
    │       ├── libSaCkpt.so.1.0.2
    │       ├── libSaClm.a
    │       ├── libSaClm.so
    │       ├── libSaClm.so.0
    │       ├── libSaClm.so.0.0.0
    │       ├── libSaEvt.a
    │       ├── libSaEvt.so
    │       ├── libSaEvt.so.1
    │       ├── libSaEvt.so.1.0.3
    │       ├── libSaImmOi.a
    │       ├── libSaImmOi.so
    │       ├── libSaImmOi.so.0
    │       ├── libSaImmOi.so.0.3.0
    │       ├── libSaImmOm.a
    │       ├── libSaImmOm.so
    │       ├── libSaImmOm.so.0
    │       ├── libSaImmOm.so.0.4.0
    │       ├── libSaLck.a
    │       ├── libSaLck.so
    │       ├── libSaLck.so.0
    │       ├── libSaLck.so.0.0.0
    │       ├── libSaLog.a
    │       ├── libSaLog.so
    │       ├── libSaLog.so.1
    │       ├── libSaLog.so.1.0.2
    │       ├── libSaMsg.a
    │       ├── libSaMsg.so
    │       ├── libSaMsg.so.1
    │       ├── libSaMsg.so.1.0.2
    │       ├── libSaNtf.a
    │       ├── libSaNtf.so
    │       ├── libSaNtf.so.0
    │       ├── libSaNtf.so.0.1.2
    │       ├── libSaSmf.a
    │       ├── libSaSmf.so
    │       ├── libSaSmf.so.0
    │       ├── libSaSmf.so.0.0.0
    │       ├── libsmfsv_common.a
    │       ├── libsmfsv_common.so
    │       ├── libsmfsv_common.so.0
    │       └── libsmfsv_common.so.0.0.0
    ├── licensefile
    │   └── collect
    ├── network.conf
    ├── smf
    │   └── smf1
    │       ├── bin
    │       │   └── smf
    │       ├── config
    │       │   ├── asn.log.properties
    │       │   └── smf.conf
    │       ├── context
    │       │   └── SystemVersionDB
    │       ├── data
    │       │   ├── replay
    │       │   │   └── backup
    │       │   └── statistics
    │       ├── licensefile -> ../../licensefile
    │       ├── log
    │       ├── startup.sh
    │       └── xml
    │           ├── dnn.xml
    │           ├── pfd.xml
    │           ├── sm-policy-data.xml
    │           ├── udm.xml
    │           └── upf.xml
    └── udm
        └── udm1
            ├── bin
            │   └── udm
            ├── config
            │   ├── asn.log.properties
            │   └── udm.conf
            ├── context
            │   ├── SystemVersionDB
            │   └── UeSecContext
            ├── data
            │   └── statistics
            ├── licensefile -> ../../licensefile
            ├── log
            └── xml
                ├── guami.xml
                ├── pcf-am-policy-data.xml
                ├── pcf-ue.xml
                ├── udm-am-subscription-data.xml
                ├── udm-session-management-subscription-data.xml
                ├── udm-smf-selection.xml
                ├── udm-snssai.xml
                ├── udm-ue-100k.xml
                └── udm-ue.xml

52 directories, 150 files

3. 关键文件

root@baicells-virtual-machine:~/5gc-c-build/source# cat /home/baicells/5gc-c/run.sh 
#!/bin/bash -

INSTALL_PATH=/home/baicells/5gc-c
action=$1
module_take=${2:-"amf smf ausf udm"}
param=$*
param_num=$#

function init_net() {
    if [[ -f network.conf ]];then
        while read line
        do
            if [[ "${line:0:1}" != "#" ]]; then
                [[ -z "$line" ]] && continue
                $line 2>&1>/dev/null
            fi
        done < network.conf
    fi
}

function init_system() {
    ulimit -c unlimited
    export LD_LIBRARY_PATH=${INSTALL_PATH}/lib
}

check_param() {
    if [ $param_num != 1 ] && [ $param_num != 2 ]; then
        echo -e "\033[31mInput error.\033[0m"
        echo -e "\033[31mUsage: $0 {start|stop|status|restart} [Optional: amf|smf].\033[0m"
        exit 1
    else
        if [ "$action" != "start" ] && \
		[ "$action" != "stop" ] && [ "$action" != "status" ] && [ "$action" != "restart" ]; then
            echo -e "\033[31mError action: $action\033[0m"
            echo -e "\033[31mUsage: $0 {start|stop|status|restart} [Optional: amf|smf].\033[0m"
            exit 2
        fi
        if  [ -n "$module" ]; then
            if [ "$module" != "amf" ] && [ "$module" != "smf" ]; then
                echo -e "\033[31mError module: $module\033[0m"
                echo -e "\033[31mUsage: $0 {start|stop|status|restart} [Optional: amf|smf].\033[0m"
                exit 3
            fi
        fi
    fi
}

function start_module() {
    for module in $module_take
    do
        cd $INSTALL_PATH/$module/${module}1
        bin/$module -s -c config/$module.conf -l config/asn.log.properties &
    done
}

function stop_module() {
    for module in $module_take
    do
    	pkill -9 $module
    	sleep 1
    done
}

function status_module() {
    for module in $module_take
    do
        if [ -n "$(pgrep $module)" ]; then
	    echo "$module is running..."
	else
	    echo "$module is NOT running..."
        fi
    done
}

function init() {
    init_system
    init_net
}

function main() {
    check_param $param
    case $action in 
        start|restart)
	    init
	    stop_module
	    start_module
	    status_module
	    echo
	    ;;
        stop)
	    echo "Stop $module_take..."
	    stop_module
	    ;;
	status)
            status_module
	    ;;
	*)
	    echo -e "\033[31mError action: $action\033[0m"
	    echo -e "\033[31mUsage: $0 {start|stop|status|restart} [Optional: amf|smf].\033[0m"
	    exit
	    ;;
   esac
};main

root@gmzhang-dev:/home/gmzhang/work/dongfeng/deb-build/5gc-c-build# cat source/5gc-c.service 
[Unit]
Description=BAICELLS-5GC-C
Requires=network.target multi-user.target 
After=network.target multi-user.target

[Service]
Type=forking
ExecStart=/home/baicells/5gc-c/init.sh
#ExecStop=

[Install]
WantedBy=multi-user.target


root@gmzhang-dev:/home/gmzhang/work/dongfeng/deb-build/5gc-c-build# cat source/network.conf 
#sudo ip link add name vpp1out type veth peer name vpp1host
  
#sudo ip link set dev vpp1out up

#sudo ip link set dev vpp1host up

#sudo ip addr add 192.168.0.1/24 dev vpp1host


4. 构建脚本

root@gmzhang-dev:/home/gmzhang/work/dongfeng/deb-build/5gc-c-build# cat build.sh 
#!/bin/bash -

install_path=/home/baicells/5gc-c

function usage() {
    cat << EOF

----------------------------------------------------
Baicells 5gc-c Builder.

The script can build Baicells 5gc-c related software.

Warning: you should use root to build. 

Usage: ./build.sh [options] [args]

Options:
  -h --help      Show this help
  -r --release   set the release of the deb
  -v --version   set the version of the deb
  -c --control   build 5gc-c deb
  -l --lib       build 5gc-c-lib deb

---------
Examples:
--

Print help message.
# ./build.sh -h

--

Build.

Build specified version of 5gc-c deb:
# ./build.sh -c -v 2.0.0

Build specified release of 5gc-c deb:
# ./build.sh -c -r 2

Build specified version and release of 5gc-c deb:
# ./build.sh -c -v 2.0.0 -r 2

Build specified version of 5gc-c-lib deb:
# ./build.sh -l -v 2.0.0

Build specified release of 5gc-c-lib deb:
# ./build.sh -l -r 2

Build specified version and release of 5gc-c-lib deb:
# ./build.sh -l -v 2.0.0 -r 2

Build specified version and release of 5gc-c and 5gc-c-lib deb:
# ./build.sh -cl -v 2.0.0 -r 2

note: if version or release not be specified,they will be "1.0.0" or "1" by default.
--


EOF
exit 0
}



function install_deps() {
    if [[ ! $(which fpm) ]];then
        apt-get install -y ruby rubygems ruby-dev
        #gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
        #gem sources -l
        gem install fpm
    fi
}


function build_5gc_c() {
    VERSION=$1
    RELEASE=$2
    sed -i "s#\(INSTALL_PATH=\).*#\1$install_path#" "source"/init.sh
    sed -i "s#\(ExecStart=\).*#\1$install_path/init.sh#" "source"/5gc-c.service
    fpm -f -s dir -t deb -C "source" -n "baicells-5gc-c" -v "$VERSION" --iteration "$RELEASE" -p . \
	    --verbose \
	    --description "BAICELLS-5GC-C" \
	    --maintainer "dongfeng@baicells.com" \
	    --vendor "baicells" \
	    --deb-no-default-config-files \
	    --config-files $install_path/amf/amf1/config/ \
	    --config-files $install_path/amf/amf1/xml \
	    --config-files $install_path/smf/smf1/config \
	    --config-files $install_path/smf/smf1/xml \
	    --config-files $install_path/ausf/ausf1/config \
	    --config-files $install_path/ausf/ausf1/xml \
	    --config-files $install_path/udm/udm1/config \
	    --config-files $install_path/udm/udm1/xml \
	    --config-files $install_path/network.conf \
	    amf=$install_path/ \
	    smf=$install_path/ \
	    ausf=$install_path/ \
	    udm=$install_path/ \
	    licensefile=$install_path/ \
	    init.sh=$install_path/ \
	    network.conf=$install_path/ \
	    5gc-c.service=/lib/systemd/system/
}

function build_5gc_c_lib() {
    VERSION=$1
    RELEASE=$2
    fpm -f -s dir -t deb -n "baicells-5gc-c-lib" -v "$VERSION" --iteration "$RELEASE" -C "source" -p . \
	    --verbose \
	    --description "BAICELLS-5GC-C-LIB" \
	    --maintainer "dongfeng@baicells.com" \
	    --vendor "baicells" \
	    --deb-no-default-config-files \
	    lib=$install_path/	
}



OPTION=$(whiptail --title "5GC Builder" --nocancel --menu "Choose your option" 15 60 4 \
"1" "Build 5gc-c" \
"2" "Build 5gc-c lib" \
"3" "Build 5gc-c and lib" \
"4" "EXIT"  3>&1 1>&2 2>&3)

case $OPTION in
    1)
	version=$(whiptail \
		--title "Version Input Box" \
		--inputbox "Input 5gc-c version(#default:1.0.0)" 15 60 "" \
		3>&1 1>&2 2>&3)
	release=$(whiptail \
		--title "Release Input Box" \
		--inputbox "Input 5gc-c release(#default:1)" 15 60 "" \
		3>&1 1>&2 2>&3)
        version=${version:-"1.0.0"}
        release=${release:-"1"}
	{
	    build_5gc_c $version $release &>/dev/null &
	    for i in {1..100};do
                sleep 0.1
                echo $i
            done
	} |  whiptail --gauge "Building \"baicells-5gc-c_$version-$release-amd64.deb\",please wait..." 6 70 0 \
		&& whiptail --title "Build success note!!!" \
		--msgbox "Congratulations! the package(s) is(are) builded successful~~~" 10 60 
        ;;
    2)
	version=$(whiptail \
		--title "Version Input Box" \
		--inputbox "Input 5gc-c lib version(#default:1.0.0)" 15 60 "" \
		3>&1 1>&2 2>&3)
	release=$(whiptail \
		--title "Release Input Box" \
		--inputbox "Input 5gc-c lib release(#default:1)" 15 60 "" \
		3>&1 1>&2 2>&3)
        version=${version:-"1.0.0"}
        release=${release:-"1"}
        {
	    build_5gc_c_lib $version $release &>/dev/null &
            for i in {1..100};do
                sleep 0.1
                echo $i
            done
        } |  whiptail --gauge "Building \"baicells-5gc-c-lib_$version-$release-amd64.deb\",please wait..." 6 70 0 \
                && whiptail --title "Build success note!!!" \
                --msgbox "Congratulations! the package(s) is(are) builded successful~~~" 10 60
        ;;
    3)
	version=$(whiptail \
		--title "Version Input Box" \
		--inputbox "Input 5gc-c and lib version(#default:1.0.0)" 15 60 "" \
		3>&1 1>&2 2>&3)
	release=$(whiptail \
		--title "Release Input Box" \
		--inputbox "Input 5gc-c and lib release(#default:1)" 15 60 "" \
		3>&1 1>&2 2>&3)
        version=${version:-"1.0.0"}
        release=${release:-"1"}
        {
	    build_5gc_c $version $release &>/dev/null &
	    build_5gc_c_lib $version $release &>/dev/null &
            for i in {1..100};do
                sleep 0.15
                echo $i
            done
    } |  whiptail --gauge "Building \"baicells-5gc-c(-lib)_$version-$release-amd64.deb\",please wait..." 6 70 0 \
                && whiptail --title "Build success note!!!" \
                --msgbox "Congratulations! the package(s) is(are) builded successful~~~" 10 60
        ;;
    4)
	exit 0
        ;;
	
esac





#ARGS=`getopt -o hr:v:cl --long help,release:,version:,control,lib, -- "$@"`
#if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
#eval set -- "$ARGS"
#while true;do
#    case "$1" in
#        -r|--release)
#            release=$2
#            shift 2
#            ;;
#        -v|--version)
#            version=$2
#            shift 2
#            ;;
#        -c|--control)
#	    b1=build_5gc_c
#            shift
#            ;;
#        -l|--lib)
#            b2=build_5gc_c_lib
#            shift
#            ;;
#        -h|--help)
#            usage
#            shift
#            ;;
#        --)
#            shift
#            break
#            ;;
#        *)
#            echo "unknown:{$1}"
#            exit 1
#            ;;
#    esac
#done
#
#version=${version:-"1.0.0"}
#release=${release:-"1"}
#
#for fn in $b1 $b2;do
#    if [[ -n $fn ]];then
#        $fn $version $release
#    fi
#done