BASH脚本 自动编译

BASH脚本 自动编译

目标

为这个椭圆检测(Github)程序实现自动编译。

思路流程

• 1. 自动下载代码
• 2. 为代码生成 makefile
• 3. 检测 opencv 是否安装和版本,如果版本过低则通过脚本自动安装
比较的方法。
• 4. 编译生成可执行文件并执行

生成makefile

这里makefile 是按照GenericMakefile Github模板修改的,直接写在sh脚本里边。这里有几个注意事项,首先是makefile 文件中有许多的特殊字符与sh脚本中的重复,这里我们要用转义符进行保护。

\->\\      `->\`  $->\$

写入多行文本

cat>Makefile<<EOF
#### PROJECT SETTINGS ####
# Function used to check variables. Use on the command line:
print-%: ; @echo \$*=\$(\$*)
#多行文本
EOF

版本号获取与比较

思路是先获取版本号,然后和要求的版本号用 sort函数进行排序,并判断第一个与要求的是否一致。调用

# 比较版本号大小
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
#调用方法
require_opencv_version="2.4.9"
opencv_version=`pkg-config --modversion opencv` #获取版本号
if version_ge $opencv_version $require_opencv_version; then
   echo "current opencv version: $opencv_version is satisified"
else 
    echo "current opencv is not satisified"
    cd setup
    bash install-opencv-2.4.13.sh
    cd ..
fi
#!/bin/bash
 
VERSION=$1
VERSION2=$2
 
function version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }   #大于
function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" == "$1"; }   #小于等于
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }  #小于
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }  #大于等于
 
if version_gt $VERSION $VERSION2; then
   echo "$VERSION is greater than $VERSION2"
fi
 
if version_le $VERSION $VERSION2; then
   echo "$VERSION is less than or equal to $VERSION2"
fi
 
if version_lt $VERSION $VERSION2; then
   echo "$VERSION is less than $VERSION2"
fi
 
if version_ge $VERSION $VERSION2; then
   echo "$VERSION is greater than or equal to $VERSION2"
fi

流程图

Created with Raphaël 2.2.0 开始 检测是否有参数? 按照参数执行对应的程序 检测目录下文件是否存在? 提示是否删除? 下载代码 写入makefile 编译 结束 yes no yes no yes no

代码

#!/bin/bash

require_opencv_version="2.4.9"

# 比较版本号大小
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }

function showpatherror()
{
    
    echo "The dir doesn't exsit! Please check!"
    echo "Uisng 'install_auto.sh -h' to show help"
    # echo "Create by Li Haojia(Derek Lee) 2019.11.25"
    exit
}

function showhelp()
{
    
    echo "Uisng 'install_auto.sh' to build and install the program in current dir."
    echo "Uisng 'install_auto.sh [dir]' to build and install the program in the path you want."
    echo "Uisng 'install_auto.sh -h' to show help"
    # echo "Create by Li Haojia(Derek Lee) 2019.11.25"
    exit
}

# 生成makefile
function write_makefile()  
{
    ADDLIBS=$@  #添加依赖库
    FILE_BIN_NAME=EllipseDetector  #产生的应用程序名
    echo "Create Makefile"
cat>Makefile<<EOF
#### PROJECT SETTINGS ####
# The name of the executable to be created
BIN_NAME := ${FILE_BIN_NAME}
# Compiler used
CXX ?= g++
# Extension of source files used in the project
SRC_EXT = cpp
# Path to the source directory, relative to the makefile
SRC_PATH = .
# Space-separated pkg-config libraries used by this project
LIBS = ${ADDLIBS}
# General compiler flags
COMPILE_FLAGS = -std=c++11 -Wall -Wextra -g
# Additional release-specific flags
RCOMPILE_FLAGS = -D NDEBUG
# Additional debug-specific flags
DCOMPILE_FLAGS = -D DEBUG
# Add additional include paths
INCLUDES = -I \$(SRC_PATH)
# General linker settings
LINK_FLAGS =
# Additional release-specific linker settings
RLINK_FLAGS =
# Additional debug-specific linker settings
DLINK_FLAGS =
# Destination directory, like a jail or mounted system
DESTDIR = /
# Install path (bin/ is appended automatically)
INSTALL_PREFIX = usr/local
#### END PROJECT SETTINGS ####

# Optionally you may move the section above to a separate config.mk file, and
# uncomment the line below
# include config.mk

# Generally should not need to edit below this line

# Obtains the OS type, either 'Darwin' (OS X) or 'Linux'
UNAME_S:=\$(shell uname -s)

# Function used to check variables. Use on the command line:
# make print-VARNAME
# Useful for debugging and adding features
print-%: ; @echo \$*=\$(\$*)

# Shell used in this makefile
# bash is used for 'echo -en'
SHELL = /bin/bash
# Clear built-in rules
.SUFFIXES:
# Programs for installation
INSTALL = install
INSTALL_PROGRAM = \$(INSTALL)
INSTALL_DATA = \$(INSTALL) -m 644

# Append pkg-config specific libraries if need be
ifneq (\$(LIBS),)
	COMPILE_FLAGS += \$(shell pkg-config --cflags \$(LIBS))
	LINK_FLAGS += \$(shell pkg-config --libs \$(LIBS))
endif

# Verbose option, to output compile and link commands
export V := false
export CMD_PREFIX := @
ifeq (\$(V),true)
	CMD_PREFIX :=
endif

# Combine compiler and linker flags
release: export CXXFLAGS := \$(CXXFLAGS) \$(COMPILE_FLAGS) \$(RCOMPILE_FLAGS)
release: export LDFLAGS := \$(LDFLAGS) \$(LINK_FLAGS) \$(RLINK_FLAGS)
debug: export CXXFLAGS := \$(CXXFLAGS) \$(COMPILE_FLAGS) \$(DCOMPILE_FLAGS)
debug: export LDFLAGS := \$(LDFLAGS) \$(LINK_FLAGS) \$(DLINK_FLAGS)

# Build and output paths
release: export BUILD_PATH := build/release
release: export BIN_PATH := bin/release
debug: export BUILD_PATH := build/debug
debug: export BIN_PATH := bin/debug
install: export BIN_PATH := bin/release

# Find all source files in the source directory, sorted by most
# recently modified
ifeq (\$(UNAME_S),Darwin)
	SOURCES = \$(shell find \$(SRC_PATH) -name '*.\$(SRC_EXT)' | sort -k 1nr | cut -f2-)
else
	SOURCES = \$(shell find \$(SRC_PATH) -name '*.\$(SRC_EXT)' -printf '%T@\t%p\n' \\
						| sort -k 1nr | cut -f2-)
endif

# fallback in case the above fails
rwildcard = \$(foreach d, \$(wildcard \$1*), \$(call rwildcard,\$d/,\$2) \\
						\$(filter \$(subst *,%,\$2), \$d))
ifeq (\$(SOURCES),)
	SOURCES := \$(call rwildcard, \$(SRC_PATH), *.\$(SRC_EXT))
endif

# Set the object file names, with the source directory stripped
# from the path, and the build path prepended in its place
OBJECTS = \$(SOURCES:\$(SRC_PATH)/%.\$(SRC_EXT)=\$(BUILD_PATH)/%.o)
# Set the dependency files that will be used to add header dependencies
DEPS = \$(OBJECTS:.o=.d)

# Macros for timing compilation
ifeq (\$(UNAME_S),Darwin)
	CUR_TIME = awk 'BEGIN{srand(); print srand()}'
	TIME_FILE = \$(dir \$@).\$(notdir \$@)_time
	START_TIME = \$(CUR_TIME) > \$(TIME_FILE)
	END_TIME = read st < \$(TIME_FILE) ; \\
		\$(RM) \$(TIME_FILE) ; \\
		st=\$\$((\`\$(CUR_TIME)\` - \$\$st)) ; \\
		echo \$\$st
else
	TIME_FILE = \$(dir \$@).\$(notdir \$@)_time
	START_TIME = date '+%s' > \$(TIME_FILE)
	END_TIME = read st < \$(TIME_FILE) ; \\
		\$(RM) \$(TIME_FILE) ; \\
		st=\$\$((\`date '+%s'\` - \$\$st - 86400)) ; \\
		echo \`date -u -d @\$\$st '+%H:%M:%S'\`
endif

# Standard, non-optimized release build
.PHONY: release
release: dirs
ifeq (\$(USE_VERSION), true)
	@echo "Beginning release build v\$(VERSION_STRING)"
else
	@echo "Beginning release build"
endif
	@\$(START_TIME)
	@\$(MAKE) all --no-print-directory
	@echo -n "Total build time: "
	@\$(END_TIME)

# Debug build for gdb debugging
.PHONY: debug
debug: dirs
ifeq (\$(USE_VERSION), true)
	@echo "Beginning debug build v\$(VERSION_STRING)"
else
	@echo "Beginning debug build"
endif
	@\$(START_TIME)
	@\$(MAKE) all --no-print-directory
	@echo -n "Total build time: "
	@\$(END_TIME)

# Create the directories used in the build
.PHONY: dirs
dirs:
	@echo "Creating directories"
	@mkdir -p \$(dir \$(OBJECTS))
	@mkdir -p \$(BIN_PATH)

# Installs to the set path
.PHONY: install
install:
	@echo "Installing to \$(DESTDIR)\$(INSTALL_PREFIX)/bin"
	@\$(INSTALL_PROGRAM) \$(BIN_PATH)/\$(BIN_NAME) \$(DESTDIR)\$(INSTALL_PREFIX)/bin

# Uninstalls the program
.PHONY: uninstall
uninstall:
	@echo "Removing \$(DESTDIR)\$(INSTALL_PREFIX)/bin/\$(BIN_NAME)"
	@\$(RM) \$(DESTDIR)\$(INSTALL_PREFIX)/bin/\$(BIN_NAME)

# Removes all build files
.PHONY: clean
clean:
	@echo "Deleting \$(BIN_NAME) symlink"
	@\$(RM) \$(BIN_NAME)
	@echo "Deleting directories"
	@\$(RM) -r build
	@\$(RM) -r bin

# Main rule, checks the executable and symlinks to the output
all: \$(BIN_PATH)/\$(BIN_NAME)
	@echo "Making symlink: \$(BIN_NAME) -> \$<"
	@\$(RM) \$(BIN_NAME)
	@ln -s \$(BIN_PATH)/\$(BIN_NAME) \$(BIN_NAME)

# Link the executable
\$(BIN_PATH)/\$(BIN_NAME): \$(OBJECTS)
	@echo "Linking: \$@"
	@\$(START_TIME)
	\$(CMD_PREFIX)\$(CXX) \$(OBJECTS) \$(LDFLAGS) -o \$@
	@echo -en "\t Link time: "
	@\$(END_TIME)

# Add dependency files, if they exist
-include \$(DEPS)

# Source file rules
# After the first compilation they will be joined with the rules from the
# dependency files to provide header dependencies
\$(BUILD_PATH)/%.o: \$(SRC_PATH)/%.\$(SRC_EXT)
	@echo "Compiling: \$< -> \$@"
	@\$(START_TIME)
	\$(CMD_PREFIX)\$(CXX) \$(CXXFLAGS) \$(INCLUDES) -MP -MMD -c \$< -o \$@
	@echo -en "\t Compile time: "
	@\$(END_TIME)

EOF
}


###########################################################################
##  main
echo "Create by Li Haojia(Derek Lee) 2019.11.25"
if [[ -n $1 ]]; then
    if [[ $1 == "-h" ]]||[[ $1 == "--help" ]]; then
        showhelp
    elif [ ! -d $1 ]; then
        showpatherror
    else  
        folder=$1
        echo "We will download and build at ${folder}"
        cd ${folder}
    fi
else
	echo "We will download and build at ${PWD}"

fi

if [ -d "fast_ellipse_detector" ]
then
    echo -e "fast_ellipse_detector floder exists."
    read -r -p "Do you want to delet it and download again?[Y/n]" input
    case $input in 
        [yY][eE][sS]|[yY])
            echo "Delet"
            rm -r -f fast_ellipse_detector
            echo "Get source files"
            git clone https://github.com/h3ct0r/fast_ellipse_detector.git
            ;;
    esac

else
    echo "Get source files"
    git clone https://github.com/h3ct0r/fast_ellipse_detector.git
fi
echo "Dowload finished"

cd fast_ellipse_detector
opencv_version=`pkg-config --modversion opencv`

if version_ge $opencv_version $require_opencv_version; then
   echo "current opencv version: $opencv_version is satisified"
else 
    echo "current opencv is not satisified"
    cd setup
    bash install-opencv-2.4.13.sh
    cd ..
fi

write_makefile opencv
make
echo "Finished!"



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值