移植GNU Make到riscv64架构

为了可以使在嵌入式平台编译使用make工具,本文介绍GNU Make工具移植到riscv64架构平台的完整流程

1、GNU Make简介

  首先要了解的是,Make是一种工具,是用于从代码源文件生成可执行文件和其他非源文件。Make是根据makefile中制定的规则而执行一系列命令,将源文件构建为目标文件,makefile也指定了目标文件的依赖关系列表。Make不限于任何特定语言。对于程序中的每个非源文件,makefile指定用于计算它的shell命令。这些shell命令可以运行编译器以生成目标文件,链接器以生成可执行文件, ar以更新库,或运行TeXMakeinfo来格式化文档。Make不限于构建包装。还可以使用Make来控制软件包的安装或卸载,为其生成标签表,或者我们经常做的其他任何事情,会使得我们工作和学习起来更加方便。在编写程序是,应为其编写一个makefile,以便可以使用Make来生成和安装程序。

2、下载Make源码的三种方式

目前主要有三种方式下载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

原文地址:https://www.cnblogs.com/ImagineMiracle-wxn/p/GNU-Make_Transplant.html