移植GNU Make到riscv64架構
阿新 • • 發佈:2021-01-08
為了可以使在嵌入式平臺編譯使用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