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