【makefile】自动生成Makefile工程

6 篇文章 0 订阅

0.环境、内容、汇总、自动部署脚本

1.编译环境、运行环境

ubuntu-1804
qca_IPQ6018 , openwrt

2.文章内容

  1. 编写本地程序
  2. 指定toolchain,交叉编译
  3. 多级文件如何定义、生成Makefile相关文件

3.汇总

1.步骤汇总

1.autoscanf:生成configure.scan
1.1 修改.scan为.ac并修改相关内容
2.aclocal:生成m4文件
3.autoconf:生成configure程序
4.新建Makefile.am文件定义Makefile生成规则
4.1 automake --add-missing : 生成Makefile.in文件
5. ./configure : 生成Makefile文件
6. 编译、执行。

2.命令汇总

# cmd 
autoscan
# cmd :
mv configure.scan configure.ac
vi configure.ac
aclocal
autoconf
# cmd :
touch Makefile.am
vi Makefile.am
automake
# cmd :
./configure // 交叉编译需要指定toolchain,如下:
/*
./configure --host=arm-openwrt-linux --prefix=/......./toolchain/qca/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi
*/

1.编译环境即为目标环境

1.参考步骤:

1 工程结构

test_1/
└── main.c

2 生成、修改configure.scan

# cmd : 
autoscan
# ret : 生成configure.ascn文件
.
├── autoscan.log
├── configure.scan
└── main.c
# cmd : 修改上述文件,并修改后缀为.ac
mv configure.scan configure.ac
# ret : 修改后,参考如下:
cat configure.ac
/*
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([test_1], [1.0], [liam@liam.com])
AC_CONFIG_SRCDIR([main.c])
#AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT(Makefile)
*/
# M-1 : 添加宏:AM_INIT_AUTOMAKE
# M-2 :注释头文件,#AC_CONFIG_HEADERS([config.h])
# M-3 :修改工程信息,AC_INIT([test_1], [1.0], [liam@liam.com])
# M-4 :定义输出文件,AC_OUTPUT(Makefile)

3 生成acloacl.m4、configure

# ret :生成configure程序
# cmd :
aclocal
# log : 生成了.m4文件
/*
├── aclocal.m4   // 生成
├── autom4te.cache
│   ├── output.0
│   ├── requests
│   └── traces.0
├── autoscan.log
├── configure.ac
└── main.c
*/
# cmd :
autoconf
# log : 生成configure
/*
.
├── aclocal.m4
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── autoscan.log
├── configure		// 生成
├── configure.ac
└── main.c
*/

4 添加 Makefile.am 文件

添加Makefile.am,作为每个整个工程Makefile的生成规则

# PS:在顶层添加Makefile.am文件,添加Makefile生成规则。
# cmd : 新建文件.am
touch Makefile.am
# data : 内容如下
cat Makefile.am
/*
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=test_1
test_1_SOURCES=main.c
*/
# ps : bin_..=最终生成程序名字
# ps .._SOURCES=需要的源文件
# PS :INCLUDES=-I...   需要头文件的话,指定优先查找头文件的路径

5 生成Makefile.in文件

# cmd 
$ automake --add-missing
/*
configure.ac:11: installing './compile'
configure.ac:8: installing './install-sh'
configure.ac:8: installing './missing'
Makefile.am: installing './depcomp'
*/
# ret : 生成Makefile.in文件
/*
.
├── aclocal.m4
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── autoscan.log
├── compile -> /usr/share/automake-1.15/compile
├── configure
├── configure.ac
├── depcomp -> /usr/share/automake-1.15/depcomp
├── install-sh -> /usr/share/automake-1.15/install-sh
├── main.c
├── Makefile.am
├── Makefile.in   // 生成
└── missing -> /usr/share/automake-1.15/missing
*/

6 生成最终的Makefile

# cmd :
./configure
/* 
config.status: creating Makefile // 类似这种log
*/

7 添加测试代码

main.c 中添加测试代码,能编译过就行,参考如下:

#include <stdio.h>
int main(){
        printf("test_1\n");
        return 0;
}

8 编译、运行

# cmd :
make ;./test
/*
test_1
*/

2. issue

# issue : 

# cmd :
./configure US_CPPFLAGS="-03"

2.交叉编译链

0.环境

1.编译环境:
ubunut-1804:x86_64
2.运行环境:
qca-IPQ6018:arm、arm64
openwrt

1.toolchain路径

准备好自定义的toolchain,本文参考路径为:
/…/toolchain/qca/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi/

2.步骤(基于上一小节)

参考上一小结内容,在上一小节执行

./configure

时,指定交叉编译环境即可,如:

./configure --host=arm-openwrt-linux --prefix=/......./toolchain/qca/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi

3. 多级文件生成Makefile

1.当前工程结构

├── bin
├── include
│   └── common.h
└── src
    ├── func.c
    └── main.c

2.步骤汇总

1.configur.ac 修改SRCDIR与OUTPUT
2.Makefile需要在每个子文件夹下定义.am文件

// 添加测试代码,测试用源码:见附录-1
autoscan
vi configure.scan
mv configure.scan configure.ac
cat configure.ac
/*
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([test_2], [1.0], [liam@liam.com])
AC_CONFIG_SRCDIR([src/main.c])
#AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_OUTPUT(Makefile src/Makefile)
*/  
aclocal
autoconf
tree
/*
.
├── aclocal.m4
├── autom4te.cache
│   ├── output.0
│   ├── output.1
│   ├── requests
│   ├── traces.0
│   └── traces.1
├── autoscan.log
├── bin
├── configure
├── configure.ac
├── include
│   └── common.h
└── src
    ├── func.c
    └── main.c
*/
touch Makefile.am
vi Makefile.am
cat Makefile.am
/*
AUTOMAKE_OPTIONS=foreign
SUBDIRS=src
*/
touch src/Makefile.am
vi src/Makefile.am
cat src/Makefile.am
/*
AM_CPPFLAGS=-I$(top_srcdir)/include
bin_PROGRAMS=$(top_srcdir)/bin/test
__top_srcdir__bin_test_SOURCES=main.c func.c
*/
automake --add-missing 
./configure  //交叉编译需要指定toolchain,参考命令如下:
/*
./configure --host=arm-openwrt-linux --prefix=/......./toolchain/qca/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi
*/
make
./bin/test
/*
ver:1.0.0
*/

PS;
默认指定交叉编译链,可以将路径等写死在下文文件中:

vi config.status
cat config.status
/* // 仅供参考
...
ac_cs_config="'--host=arm-openwrt-linux' '--prefix=/.........../toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi' 'host_alias=arm-openwrt-linux'"
...
*/

4.自动部署的脚本

自用,仅供参考!看不懂脚本的人请不要使用!
自用,仅供参考!看不懂脚本的人请不要使用!
自用,仅供参考!看不懂脚本的人请不要使用!

操作步骤
1.将如下shell源码复制到编译环境,粘贴为一个.sh脚本,并添加执行权限。
2.指定一个文件夹名。./xxxxx --new [project name]

脚本源码如下:

#!/bin/sh

# Liam
# 20210524
# GPL

# 1.check env & cmd
# 2.create project & init src code
# 3.autoscan & M confure.scan
# 4.aclocal & autoconf
# 5.NEW Makefile.am & Build Makefile.in
# 6.build Makefile

function func_0_check_project_name(){
	# check 
	if [[ -z "$1" ]];then
		echo "Err : need [project name]"
		exit 1
	fi
}

function func_1_check_env(){
	CMD_AUTOSCAN=$(which autoscan)
	CMD_ACLOCAL=$(which aclocal)
	CMD_AUTOCONF=$(which autoconf)
	CMD_AUTOMAKE=$(which automake)
	if [[ -z "$CMD_AUTOSCAN" ]] || [[ -z "$CMD_ACLOCAL" ]] || [[ -z "$CMD_AUTOCONF" ]] || [[ -z "$CMD_AUTOMAKE" ]];then
		echo "=>env check : fail "
		echo "Tips : try 'sudo apt install automake'"
		exit 1
	else
		echo "=>env check : ok "
	fi
}

function func_2_new_pjt_init_code(){
	# check 
	if [[ -d "$1" ]] || [[ -f "$1" ]];then
		echo "=>init : fail"
		echo "Tips : change [project name] or try 'rm -r $1' first "
		exit 1
	fi
	# touch 
	mkdir $1
	mkdir $1/bin $1/include $1/src
	touch $1/include/common.h
	touch $1/src/main.c
	touch $1/src/func.c
	# init source code
	echo "#ifndef __COMMON_H__
#define __COMMON_H__
#define __SOFT_VERSION__ \"1.0.0\"
void show_version(void);
#endif
	" > $1/include/common.h
	echo "#include <stdio.h>
#include \"common.h\"
int main(){
	show_version();
	return 0;
}	
	" > $1/src/main.c
	echo "#include <stdio.h>
#include \"common.h\"
void show_version(void){
	printf(\"ver:%s\n\",__SOFT_VERSION__);
}	
	" > $1/src/func.c
	if [[ -f "$1/include/common.h" ]] || 
		[[ -f "$1/src/main.c" ]] || 
		[[ -f "$1/src/func.c" ]] ; then
		echo "=>init : ok"
	else
		echo "=>init : fail"
	fi
}

function func_3_autosacn_M_ac(){
	autoscan $1 || exit 1
	if [[ ! -f "$1/configure.scan" ]];then
		echo "=>autoscan : fail"
	fi
	mv $1/configure.scan $1/configure.ac
	sed -i "s#FULL-PACKAGE-NAME#$1#g"							$1/configure.ac
	sed -i 's#VERSION#1.0#g'									$1/configure.ac
	sed -i 's#BUG-REPORT-ADDRESS#liam@liam.com#g'				$1/configure.ac
	sed -i 's/AC_CONFIG_HEADERS/#AC_CONFIG_HEADERS/g'			$1/configure.ac
	sed -i "s#(\[config.h\])#(\[config.h\])\nAM_INIT_AUTOMAKE#g" $1/configure.ac
	sed -i 's#AC_OUTPUT#AC_OUTPUT(Makefile src/Makefile)#g'		$1/configure.ac
	echo "=>autoscan : done"
}

function func_4_aclocal(){
	cd $1
	if [[ ! -f "configure.ac" ]];then
		echo "=>aclocal : fail"
		echo "Tips : no configure.ac"
		exit 1
	fi
	aclocal
	if [[ ! -f "aclocal.m4" ]];then
		echo "=>aclocal : fail"
		exit 1
	else
		echo "=>aclocal : ok"
	fi
	cd  - >> /dev/null
}

function func_4_autoconf(){
	cd $1
	if [[ ! -f "aclocal.m4" ]];then
		echo "=>aclocal.m4 : fail"
		echo "Tips : no aclocal.m4"
		exit 1
	fi
	autoconf
	if [[ ! -f "configure" ]];then
		echo "=>autoconf : fail"
		exit 1
	else
		echo "=>autoconf : ok"
	fi
	cd  - >> /dev/null
}

function func_5_automake(){
	cd $1
	# init Makefile.am
	echo "AUTOMAKE_OPTIONS=foreign
SUBDIRS=src
	" > Makefile.am
	echo "AM_CPPFLAGS=-I\$(top_srcdir)/include
bin_PROGRAMS=\$(top_srcdir)/bin/test
__top_srcdir__bin_test_SOURCES=main.c func.c
	" > src/Makefile.am
	# build Makefile.in
	if [[ ! -f "configure" ]] || [[ ! -f "configure.ac" ]] ;then
		echo "=>automake : fail"
		echo "Tips : no configure / configure.ac"
		exit 1
	fi
	if [[ ! -f "Makefile.am" ]] || [[ ! -f "src/Makefile.am" ]] ;then
		echo "=>automake : fail"
		echo "Tips : no ./*/Makefile.am"
		exit 1
	fi
	automake --add-missing
	if [[ ! -f "Makefile.in" ]] || [[ ! -f "src/Makefile.in" ]] ;then
		echo "=>automake : fail"
		exit 1
	else
		echo "=>automake : ok"
	fi
	cd  - >> /dev/null
}

function func_6_configure(){
	cd $1
	if [[ ! -f "configure" ]] || [[ ! -f "configure.ac" ]] ;then
		echo "=>automake : fail"
		echo "Tips : no configure / configure.ac"
		exit 1
	fi
	./configure
	# opwnert toolchain EG
	# ./configure --host=arm-openwrt-linux --prefix=/......./toolchain/qca/toolchain-arm_cortex-a7_gcc-5.2.0_musl-1.1.16_eabi
	if [[ ! -f "Makefile" ]] || [[ ! -f "Makefile" ]] ;then
		echo "=>configure : fail"
		exit 1
	else
		echo "=>configure : ok"
	fi
	cd  - >> /dev/null
}

function func_0_make_run(){
	cd $1
	if [[ ! -f "Makefile" ]] || [[ ! -f "src/Makefile" ]] ;then
		echo "=>test : fail"
		echo "Tips : no Makefile / src/Makefile"
		exit 1
	fi
	if [[ ! -f "include/common.h" ]] || [[ ! -f "src/main.c" ]] || [[ ! -f "src/func.c" ]] ;then
		echo "=>test : fail"
		echo "Tips : no socure code"
		exit 1
	fi
	make
	if [[ ! -f "bin/test" ]];then
		echo "=>test : fail"
		echo "Tips : no bin/test"
		exit 1
	fi
	./bin/test
	cd  - >> /dev/null
	echo "test : deno"
}

case $1 in
	--env)
		func_1_check_env
	;;
	--init)
		func_0_check_project_name $2 || exit 1
		func_2_new_pjt_init_code $2 #project name
	;;
	--autoscan)
		func_0_check_project_name $2 || exit 1
		func_3_autosacn_M_ac $2 #project name
	;;
	--aclocal)
		func_0_check_project_name $2 || exit 1
		func_4_aclocal $2 #project name
	;;
	--autoconf)
		func_0_check_project_name $2 || exit 1
		func_4_autoconf $2 #project name
	;;
	--automake)
		func_0_check_project_name $2 || exit 1
		func_5_automake $2 #project name
	;;
	--configure)
		func_0_check_project_name $2 || exit 1
		func_6_configure $2 #project name
	;;
	--test)
		func_0_check_project_name $2 || exit 1
		func_0_make_run $2 #project name
	;;
	--new)
		func_1_check_env			|| exit 1
		func_0_check_project_name $2|| exit 1
		func_2_new_pjt_init_code $2	|| exit 1
		func_3_autosacn_M_ac $2		|| exit 1 
		func_4_aclocal $2			|| exit 1
		func_4_autoconf $2			|| exit 1
		func_5_automake $2			|| exit 1
		func_6_configure $2			|| exit 1
		echo "DOEN , new project named : $2 "
	;;
	--help)
		echo "useage :"
		echo "./xxxxx --new [project name]"
	;;
	*)
		echo "useage :"
		echo "./xxxxx --new [project name]"
	;;
esac

附件-自动部署的脚本

上述脚本的下载链接:https://download.csdn.net/download/yujianliam/19030133

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过得精彩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值