移植GNU Make到riscv64架构
为了可以使在嵌入式平台编译使用make工具,本文介绍GNU Make工具移植到riscv64架构平台的完整流程
1、GNU Make简介
首先要了解的是,Make
是一种工具,是用于从代码源文件生成可执行文件和其他非源文件。Make
是根据makefile
中制定的规则而执行一系列命令,将源文件构建为目标文件,makefile
也指定了目标文件的依赖关系列表。Make
不限于任何特定语言。对于程序中的每个非源文件,makefile
指定用于计算它的shell命令。这些shell
命令可以运行编译器以生成目标文件,链接器以生成可执行文件, ar
以更新库,或运行TeX
或Makeinfo
来格式化文档。Make
不限于构建包装。还可以使用Make
来控制软件包的安装或卸载,为其生成标签表,或者我们经常做的其他任何事情,会使得我们工作和学习起来更加方便。在编写程序是,应为其编写一个makefile
,以便可以使用Make
来生成和安装程序。
2、下载Make源码的三种方式
目前主要有三种方式下载Make源码:
- <1> GNU ftp服务器(通过HTTP) : http://ftp.gnu.org/gnu/make/
- <2> GNU ftp服务器(通过FTP) : ftp://ftp.gnu.org/gnu/make/
- <3> GNU mirrors(推荐使用镜像) : http://mirror.team-cymru.com/gnu/make/
2.1、通过GNU mirrors下载Make
[注]:既然官方提倡通过镜像下载,本文就介绍已该途径下载Make代码
打开GNU mirrors
网址,可以看到如下罗列的各种版本的Make
源码包,直接下载最新版本make-4.3.tar.gz
(笔者访问时间为2021/01/08)。
3、编译生成Make二进制文件
3.1、打开源码压缩包
解压并打开Make
源码包并创建Make
安装目录:
imaginemiracle@:make_install$ ls
make-4.3.tar.gz
imaginemiracle@:make_install$ tar -zxvf make-4.3.tar.gz
imaginemiracle@:make_install$ ls
make-4.3 make-4.3.tar.gz
imaginemiracle@:make_install$ mkdir install_4.3 //创建Make安装目录
imaginemiracle@:make_install$ ls
install_4.3
3.2、配置并编译安装Make
通过configure
配置make
工程:
imaginemiracle@:make_install$ cd make-4.3/
imaginemiracle@:make-4.3$ ls
ABOUT-NLS build-aux build_w32.bat COPYING Makefile.am NEWS README.customs README.W32 vms_export_symbol_test.com
aclocal.m4 build.cfg.in ChangeLog doc makefile.com po README.DOS SCOPTIONS
AUTHORS builddos.bat configure lib Makefile.in README README.OS2 src
Basic.mk build.sh configure.ac m4 mk README.Amiga README.VMS tests
##[注]:这里的prefix参数,是配置make的安装目录,必须写成绝对路径
imaginemiracle@:make-4.3$ ./configure --prefix=/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/install_4.3 --build=x86_64-unknown-linux-gnu --host=riscv64-unknown-linux-gnu
################################省略部分输出####################################
#############看到一下输出且没有报错,则表示configure成功生成接下来make命令所需文件##############
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating build.cfg
config.status: creating lib/Makefile
config.status: creating po/Makefile.in
config.status: creating doc/Makefile
config.status: creating tests/config-flags.pm
config.status: creating src/config.h
config.status: executing depfiles commands
config.status: executing po-directories commands
config.status: creating po/POTFILES
config.status: creating po/Makefile
执行make;make install
(编译并安装):
imaginemiracle@:make-4.3$ make;make install
imaginemiracle@:make-4.3$ ls ../install_4.3/
bin include share
imaginemiracle@:make-4.3$ ls ../install_4.3/bin/
make
imaginemiracle@:make-4.3$ file ../install_4.3/bin/make
../install_4.3/bin/make: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 3.0.0, with debug_info, not stripped
可以看到已经成功生成riscv64
架构的make
可执行文件,将其放在riscv64
架构平台下即可使用。
到此,Make工具的移植过程介绍完毕!!!
4、编译Make可能会遇到的问题以及解决方案
笔者之前在编译make4.1
版本时遇到以下错误:
<1>问题 make-4.1/config/missing: line 81: makeinfo: command not found
<1>解决方案
sudo apt-get install texinfo
<2>问题 make-4.1/glob/glob.c:1342: undefined reference to `__alloca'
gcc -DLOCALEDIR=\"/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/install/share/locale\" -DLIBDIR=\"/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/install/lib\" -DINCLUDEDIR=\"/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/install/include\" -DHAVE_CONFIG_H -I. -I./glob -g -O2 -MT remote-stub.o -MD -MP -MF .deps/remote-stub.Tpo -c -o remote-stub.o remote-stub.c
mv -f .deps/remote-stub.Tpo .deps/remote-stub.Po
gcc -g -O2 -Wl,--export-dynamic -o make ar.o arscan.o commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o guile.o implicit.o job.o load.o loadapi.o main.o misc.o output.o read.o remake.o rule.o signame.o strcache.o variable.o version.o vpath.o hash.o remote-stub.o glob/libglob.a -ldl
/usr/bin/ld: glob/libglob.a(glob.o): in function `glob_in_dir':
/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1/glob/glob.c:1367: undefined reference to `__alloca'
/usr/bin/ld: /home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1/glob/glob.c:1342: undefined reference to `__alloca'
/usr/bin/ld: /home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1/glob/glob.c:1256: undefined reference to `__alloca'
/usr/bin/ld: /home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1/glob/glob.c:1283: undefined reference to `__alloca'
/usr/bin/ld: glob/libglob.a(glob.o): in function `glob':
/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1/glob/glob.c:581: undefined reference to `__alloca'
/usr/bin/ld: glob/libglob.a(glob.o):/home/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1/glob/glob.c:732: more undefined references to `__alloca' follow
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:621: make] Error 1
make[2]: Leaving directory '/media/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1'
make[1]: *** [Makefile:762: all-recursive] Error 1
make[1]: Leaving directory '/media/imaginemiracle/Disk_D/Linux_Workspace/riscv-project/Initramfs_Create/busybox/make_install/make-4.1'
make: *** [Makefile:514: all] Error 2
<2>解决方案
# define realloc my_realloc
# endif /* __SASC */
#endif /* __GNU_LIBRARY__ || __DJGPP__ */
//============================Alter by me===========================
//#if !defined __alloca && !defined __GNU_LIBRARY__
#if !defined __alloca && defined __GNU_LIBRARY__
//=============================End Alter============================
# ifdef __GNUC__
# undef alloca
# define alloca(n) __builtin_alloca (n)
# else /* Not GCC. */
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else /* Not HAVE_ALLOCA_H. */
# ifndef _AIX
# ifdef WINDOWS32
# include <malloc.h>
# else
extern char *alloca ();
# endif /* WINDOWS32 */
# endif /* Not _AIX. */
# endif /* sparc or HAVE_ALLOCA_H. */
# endif /* GCC. */
# define __alloca alloca
#endif
5、致谢
[参考链接]: http://gnu-make.2324884.n4.nabble.com/undefined-reference-to-alloca-td18308.html