xref: /DragonOS/tools/build_gcc_toolchain.sh (revision eb49bb993a39964f92494ec3effafed3fb9adfd8)
1#!/bin/bash
2
3if test -n "$ZSH_VERSION"; then
4  CURRENT_SHELL=zsh
5elif test -n "$BASH_VERSION"; then
6  CURRENT_SHELL=bash
7elif test -n "$KSH_VERSION"; then
8  CURRENT_SHELL=ksh
9elif test -n "$FCEDIT"; then
10  CURRENT_SHELL=ksh
11elif test -n "$PS3"; then
12  CURRENT_SHELL=unknown
13else
14  CURRENT_SHELL=sh
15fi
16
17source "$HOME/.$CURRENT_SHELL"rc
18
19# init something here
20current_path=$PATH
21current_pwd=$PWD
22
23# 不建议自行选择安装的位置, 如果要修改请自行修改 INSTALL_POS
24STRUCTURE="x86_64"  # 这里选择 x86_64 (64位),而不是选择 i686 架构(32位)
25INSTALL_POS="$HOME/opt/dragonos-gcc"
26PREFIX="$INSTALL_POS/gcc-$STRUCTURE-unknown-none"
27TARGET="${STRUCTURE}-elf"
28PATH="$PREFIX/bin:$PATH"
29TARGET_GCC="$STRUCTURE-elf-gcc"
30TARGET_LD="$STRUCTURE-elf-ld"
31TARGET_AS="$STRUCTURE-elf-as"
32
33# 获取选项
34KEEP_BINUTILS=0
35KEEP_GCC=0
36CHANGE_SOURCE=0
37FORCE=0
38SAVE_CACHE=0
39while true; do
40    if [ ! -n "$1" ]; then
41        break
42    fi
43    case "$1" in
44        "-save-cache")
45            SAVE_CACHE=1
46            ;;
47        "-rebuild")
48            echo "清除${INSTALL_POS}目录下的所有信息"
49            rm -rf "${INSTALL_POS}"
50            ;;
51        "-kb")
52            KEEP_BINUTILS=1
53            ;;
54        "-kg")
55            KEEP_GCC=1
56            ;;
57        "-cs")
58            CHANGE_SOURCE=1
59            ;;
60        "-f")
61            FORCE=1
62            ;;
63        "-help")
64            echo "脚本选项如下:"
65            echo "-save-cache: 保留最后的下载压缩包"
66            echo "-rebuild: 清除上一次安装的全部信息, 即删掉$INSTALL_POS目录下的所有内容, 然后重新构建gcc工具链."
67            echo "-kg(keep-gcc): 您确保${STRUCTURE}-gcc已被编译安装, 本次调用脚本不重复编译安装gcc. 如果没有安装,脚本仍然会自动安装."
68            echo "-kb(keep-binutils): 您确保binutils已被编译安装, 本次调用脚本不重复编译安装binutils. 如果没有安装,脚本仍然会自动安装."
69            echo "-cs(change source): 如果包含该选项, 使用清华源下载gcc和binutils. 否则默认官方源."
70            echo "-f(force): 如果包含该选项, 可以强制使用root权限安装在/root/目录下."
71            ;;
72        *)
73            echo "不认识参数$1"
74            ;;
75    esac
76    shift 1
77done
78
79# check: Don't install the gcc-toolchain in /root/*
80if [ "${HOME:0:5}" = "/root" ] && [ $FORCE -eq 0 ]; then
81    echo -e "\033[35m 不要把GCC交叉编译工具链安装在/root/目录下, 或者请不要使用sudo \033[0m"
82    echo -e "\033[35m gcc交叉编译工具链默认安装在: /home/<your_usr_name>/opt/dragonos-gcc/ \033[0m"
83    echo -e "\033[35m 如果想要在/root/目录下安装(或者您的操作系统只有root用户), 请使用指令: sudo bash build_gcc_toolchain.sh -f \033[0m"
84    exit 0
85else
86    # 安装开始[提示]
87    echo -e "\033[35m [开始安装] \033[0m"
88    echo -e "\033[33m gcc交叉编译工具链默认安装在: /home/<your_usr_name>/opt/dragonos-gcc/, 整个过程耗时: 5-30mins \033[0m"
89    sleep 0.3s
90fi
91
92# install prerequisited
93# 注意texinfo和binutils的版本是否匹配
94# 注意gmp/mpc/mpfr和gcc/g++的版本是否匹配
95echo "Start installing prerequisited packages"
96case `cat /etc/os-release | grep '^NAME=' | cut -d'"' -f2` in
97    "Debian"* | "Ubuntu"*)
98        sudo apt-get install -y \
99            g++ \
100            gcc \
101            make \
102            texinfo \
103            libgmp3-dev \
104            libmpc-dev \
105            libmpfr-dev \
106            flex \
107            wget
108        ;;
109    "Arch"*)
110        sudo pacman -S --needed --noconfirm \
111            gcc make flex wget texinfo libmpc gmp mpfr \
112            diffutils pkgconf which unzip
113        ;;
114    *)
115        ;;
116esac
117
118# build the workspace
119mkdir -p $HOME/opt
120mkdir -p $INSTALL_POS
121mkdir -p $PREFIX
122cd $INSTALL_POS
123
124
125# compile binutils
126BIN_UTILS="binutils-2.38"
127BIN_UTILS_TAR="${BIN_UTILS}.tar.gz"
128
129if [[ ! -n "$(find $PREFIX/bin/ -name ${TARGET_LD})" && ! -n "$(find $PREFIX/bin/ -name ${TARGET_AS})" ]] || [ ${KEEP_BINUTILS} -ne 1 ]; then
130    if [ ${KEEP_BINUTILS} -eq 1 ]; then
131        echo -e "\033[35m 没有检测到 ${TARGET_LD} 或 没有检测到 ${TARGET_AS}, -kb参数无效 \033[0m"
132        echo -e "\033[35m 开始安装binutils \033[0m"
133        sleep 1s
134    fi
135    if [ ! -d "$BIN_UTILS" ]; then
136        if [ ! -f "$BIN_UTILS_TAR" ]; then
137            echo -e "\033[33m [提醒] 如果使用的是国外源, 下载时间可能偏久. 如果需要使用清华源, 请以输入参数-cs, 即: bash build_gcc_toolchain.sh -cs  \033[0m "
138            if [ ${CHANGE_SOURCE} -eq 1 ]; then
139                # 国内源
140                wget "https://mirrors.ustc.edu.cn/gnu/binutils/${BIN_UTILS_TAR}" -P "$INSTALL_POS"
141            else
142                # 官方网站
143                wget https://ftp.gnu.org/gnu/binutils/${BIN_UTILS_TAR} -P "$INSTALL_POS"
144            fi
145        fi
146        tar zxvf "$BIN_UTILS_TAR"
147    fi
148    # 开始编译
149    mkdir build-binutils
150    cd build-binutils
151    ../${BIN_UTILS}/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
152    make -j $(nproc) || exit 1
153    make install || exit 1
154    cd ..
155fi
156
157# compile GCC
158GCC_FILE="gcc-11.3.0"
159GCC_FILE_TAR="${GCC_FILE}.tar.gz"
160if [ ! -n "$(find $PREFIX/bin/* -name $TARGET_GCC)" ] || [ ${KEEP_GCC} -ne 1 ]; then
161    if [ $KEEP_GCC -eq 1 ]; then
162        echo -e "\033[35m 没有检测到 $TARGET_GCC, -kg参数无效 \033[0m"
163        echo -e "\033[35m 开始安装gcc \033[0m"
164        sleep 1s
165    fi
166    if [ ! -d "$GCC_FILE" ]; then
167        if [ ! -f "$GCC_FILE_TAR" ]; then
168                echo -e "\033[33m [提醒] 如果使用的是国外源, 下载时间可能偏久. 如果需要使用清华源, 请以输入参数-cs, 即: bash build_gcc_toolchain.sh -cs  \033[0m "
169                if [ ${CHANGE_SOURCE} -eq 1 ]; then
170                    # 国内源
171                    wget "https://mirrors.ustc.edu.cn/gnu/gcc/${GCC_FILE}/${GCC_FILE_TAR}" -P "$INSTALL_POS"
172                else
173                    # 官方网站
174                    wget "http://ftp.gnu.org/gnu/gcc/${GCC_FILE}/${GCC_FILE_TAR}" -P "$INSTALL_POS"
175                fi
176        fi
177        tar zxvf "$GCC_FILE_TAR"
178    fi
179    # 开始编译安装
180    mkdir build-gcc
181    cd build-gcc
182    ../${GCC_FILE}/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
183    make MAKEINFO=true all-gcc -j $(nproc) || exit 1
184    make MAKEINFO=true all-target-libgcc -j $(nproc)  || exit 1
185    make MAKEINFO=true install-gcc -j $(nproc)  || exit 1
186    make MAKEINFO=true install-target-libgcc -j $(nproc)  || exit 1
187    cd ..
188fi
189
190
191# update PATH
192if [ -n "$(grep -F "export DragonOS_GCC" "$HOME/.$(basename $SHELL)rc")" ]; then
193	echo "[info] DragonOS_GCC has been in the "'$PATH'
194else
195	echo 'export DragonOS_GCC='"$PREFIX"'/bin' >> "$HOME/.$(basename $SHELL)rc"
196	echo 'export PATH="$DragonOS_GCC:$PATH"'	>> "$HOME/.$(basename $SHELL)rc"
197	echo "[info] Add DragonOS_GCC into PATH successfully."
198fi
199source "$HOME/.$CURRENT_SHELL"rc
200
201# final check
202if [ -n "$(find $PREFIX/bin/* -name $TARGET_GCC)" ] &&
203   [ -n "$(find $PREFIX/bin/* -name $TARGET_LD)" ] &&
204   [ -n "$(find $PREFIX/bin/* -name $TARGET_AS)" ]; then
205   if [ ${SAVE_CACHE} -eq 0 ]; then
206        # 删除临时文件
207        rm -rf "$BIN_UTILS"
208        rm -rf "$BIN_UTILS_TAR"
209        rm -rf "build-binutils"
210        rm -rf "$GCC_FILE"
211        rm -rf "$GCC_FILE_TAR"
212        rm -rf "build-gcc"
213    fi
214
215    echo -e "\033[42;37m [构建成功] Build Successfully.(请重新打开另一个Shell窗口或者重新打开你的IDE以获取新的环境变量) \033[0m"
216else
217    echo -e "\033[31m [错误] 未找到$STRUCTURE-elf-gcc, $STRUCTURE-elf-ld和$STRUCTURE-elf-as. \033[0m"
218    echo -e "\033[31m [构建失败] 请尝试重新运行build_gcc_toolchain.sh, 或者查看输出,找到错误的原因. \033[0m"
219fi
220
221cd "$current_pwd"
222