项目 | 版本 |
---|---|
OS | Ubuntu 24.04 |
GCC | 15.0.0 |
GDB | 16.0.50 |
Binutils | 2.42.50 |
Python | 3.12.3 |
Glibc | 2.39 |
Mingw-w64 | 10.0.0 |
PExports | 0.47 |
Iconv | 1.17 |
Gmp | 6.2.1 |
Mpfr | 4.1.0 |
Expat | 2.5.0 |
sudo apt install bison flex texinfo make automake autoconf libtool git gcc g++ gcc-multilib g++-multilib python3 tar xz-utils unzip libgmp-dev libmpfr-dev zlib1g-dev libexpat1-dev gawk bzip2
git clone https://github.com/gcc-mirror/gcc.git --depth=1 gcc
git clone https://github.com/bminor/binutils-gdb.git --depth=1 binutils
git clone https://github.com/mirror/mingw-w64.git --depth=1 mingw
git clone https://github.com/libexpat/libexpat.git --depth=1 expat
cd ~/expat/expat
./buildconf.sh
cd ~
git clone https://github.com/torvalds/linux.git --depth=1 linux
# glibc版本要与目标系统使用的版本对应
git clone https://github.com/bminor/glibc.git -b release/2.39/master --depth=1 glibc
git clone https://github.com/bocke/pexports.git --depth=1 pexports
cd ~/pexports
autoreconf -if
cd ~
# 编译Windows下带有Python支持的gdb需要嵌入式Python3环境
wget https://www.python.org/ftp/python/3.12.3/python-3.12.3-embed-amd64.zip -O python-embed.zip
unzip -o python-embed.zip python3*.dll python3*.zip *._pth -d python-embed -x python3.dll
rm python-embed.zip
# 下载Python源代码以提取include目录
wget https://www.python.org/ftp/python/3.12.3/Python-3.12.3.tar.xz -O Python.tar.xz
tar -xaf Python.tar.xz
rm Python.tar.xz
cd Python-3.12.3/Include
mkdir ~/python-embed/include
cp -r * ~/python-embed/include
cd ../PC
cp pyconfig.h ~/python-embed/include
cd ~
rm -rf Python-3.12.3
wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.17.tar.gz -O iconv.tar.gz
tar -axf iconv.tar.gz
rm iconv.tar.gz
mv libiconv-1.17/ iconv
cd ~/gcc
contrib/download_prerequisites
cp -rfL gmp mpfr ..
cd ~
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | x86_64-linux-gnu |
export PREFIX=~/x86_64-linux-gnu-native-gcc15
cd ~/gcc
mkdir build
cd build
../configure --disable-werror --enable-multilib --enable-languages=c,c++ --disable-bootstrap --enable-nls --prefix=$PREFIX
make -j 20
make install-strip -j 20
# 单独安装带调试符号的库文件
make install-target-libgcc install-target-libstdc++-v3 install-target-libatomic install-target-libquadmath install-target-libgomp -j 20
echo "export PATH=$PREFIX/bin:"'$PATH' >> ~/.bashrc
source ~/.bashrc
参阅gcc配置选项。
cd ~/binutils
mkdir build
cd build
export ORIGIN='$$ORIGIN'
../configure --prefix=$PREFIX --disable-werror --enable-nls --with-system-gdbinit=$PREFIX/share/.gdbinit LDFLAGS="-Wl,-rpath='$ORIGIN'/../lib64" --enable-gold
make -j 20
make install-strip -j 20
unset ORIGIN
--with-system-gdbinit=$PREFIX/share/.gdbinit
选项是用于设置默认的.gdbinit,而我们可以在默认的.gdbinit中配置好pretty-printer模块,
这样就可以实现开箱即用的pretty-printer。参见GDB系统设置。
export ORIGIN='$$ORIGIN'
和LDFLAGS="-Wl,-rpath='$ORIGIN'/../lib64"
选项是用于设置gdb的rpath。由于编译时使用的gcc版本比系统自带的更高,故链接的libstdc++版本也更高。
因而需要将rpath设置到编译出来的libstdc++所在的目录。
在GCC更新后将C语言的默认标准提升至C23,这导致bool
相关的定义语句存在问题,需要对/gcc/libgcc/unwind-arm-common.inc
中的语句进行修改:
// gcc/libgcc/unwind-arm-common.inc
/* Definitions for C++ runtime support routines. We make these weak
declarations to avoid pulling in libsupc++ unnecessarily. */
#if __STDC_VERSION__ < 202311L
typedef unsigned char bool;
#endif
由libstdc++.so.6.0.33-gdb.py
配置pretty-printer,完成后转至第7步:
# share/.gdbinit
python
import os
import gdb
import sys
# gdb启动时会将sys.path[0]设置为share/gdb/python
scriptPath = os.path.join(sys.path[0], "../../../lib64/libstdc++.so.6.0.33-gdb.py")
gdb.execute(f"source {scriptPath}")
end
由share/.gdbinit
直接配置pretty-printer,完成后直接跳转至第8步:
# share/.gdbinit
python
import os
import gdb
import sys
# gdb启动时会将sys.path[0]设置为share/gdb/python
share_dir = os.path.abspath(os.path.join(sys.path[0], "../../"))
# 在share目录下搜索gcc的python支持
python_dir = ""
for dir in os.listdir(share_dir):
current_dir = os.path.join(share_dir, dir, "python")
if dir[0:3] == "gcc" and os.path.isdir(current_dir):
python_dir = current_dir
break
if python_dir != "":
sys.path.insert(0, python_dir)
from libstdcxx.v6 import register_libstdcxx_printers
register_libstdcxx_printers(gdb.current_objfile())
else:
print("Cannot find gcc python support because share/gcc*/python directory does not exist.")
end
# lib64/libstdc++.so.6.0.33-gdb.py
import sys
import gdb
import os
current_dir = os.path.dirname(os.path.abspath(__file__))
# pretty-printer所需的python脚本位于share/gcc-15.0.0/python下
# 故使用哪个libstdc++.so.6.0.33-gdb.py都不影响结果,此处选择lib64下的
python_dir = os.path.normpath(os.path.join(current_dir, "../share/gcc-15.0.0/python"))
if not python_dir in sys.path:
sys.path.insert(0, python_dir)
# 注册pretty-printer
from libstdcxx.v6 import register_libstdcxx_printers
register_libstdcxx_printers(gdb.current_objfile())
同理,修改lib32/libstdc++.so.6.0.33-gdb.py
,尽管在默认配置中该文件不会被加载。
通过make install-target
命令可以安装未strip的运行库,但这样的运行库体积过大,不利于部署。因此需要剥离调试符号到独立的符号文件中。
在第4步中我们保留了以下库的调试符号:libgcc libstdc++ libatomic libquadmath libgomp
接下来逐个完成剥离操作:
# 生成独立的调试符号文件
objcopy --only-keep-debug $PREFIX/lib64/libgcc_s.so.1 $PREFIX/lib64/libgcc_s.so.1.debug
# 剥离动态库的调试符号
strip $PREFIX/lib64/libgcc_s.so.1
# 关联调试符号和动态库
objcopy --add-gnu-debuglink=$PREFIX/lib64/libgcc_s.so.1.debug $PREFIX/lib64/libgcc_s.so.1
# 重复上述操作直到处理完所有动态库
cd $PREFIX/bin
# 值得注意的是,此时编译出来的gcc不包含cc,这会导致编译build的目标时一些依赖cc的工具报错
ln -s gcc cc
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export MEMORY=$(cat /proc/meminfo | awk '/MemTotal/ {printf "%dGiB\n", int($2/1024/1024)}')
tar -cf x86_64-linux-gnu-native-gcc15.tar x86_64-linux-gnu-native-gcc15/
xz -ev9 -T 0 --memlimit=$MEMORY x86_64-linux-gnu-native-gcc15.tar
构建mingw交叉工具链
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | x86_64-w64-mingw32 |
export TARGET=x86_64-w64-mingw32
export HOST=x86_64-linux-gnu
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
cd binutils/build
rm -rf *
# Linux下不便于调试Windows,故不编译gdb
../configure --disable-werror --enable-nls --disable-gdb --prefix=$PREFIX --target=$TARGET
make -j 20
make install-strip -j 20
echo "export PATH=$PREFIX/bin:"'$PATH' >> ~/.bashrc
source ~/.bashrc
cd ~/mingw
mkdir build
cd build
# 这是交叉编译器,故目标平台的头文件需要装在$TARGET目录下
../configure --prefix=$PREFIX/$TARGET --with-default-msvcrt=ucrt --host=$TARGET --without-crt
make install
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-multilib --enable-languages=c,c++ --enable-nls --disable-sjlj-exceptions --enable-threads=win32 --prefix=$PREFIX --target=$TARGET
make all-gcc all-target-libgcc -j 20
make install-strip-gcc install-strip-target-libgcc -j 20
遇到如下情况:
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 dllcrt2.o: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lmingwthrd: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lmingw32: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lmingwex: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lmoldname: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lmsvcrt: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -ladvapi32: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lshell32: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -luser32: 没有那个文件或目录
/home/luo/x86_64-linux-gnu-host-x86_64-w64-mingw32-cross-gcc15/x86_64-w64-mingw32/bin/ld: 找不到 -lkernel32: 没有那个文件或目录
尝试禁用动态库编译出gcc和libgcc
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-multilib --enable-languages=c,c++ --enable-nls --disable-sjlj-exceptions --enable-threads=win32 --prefix=$PREFIX --target=$TARGET --disable-shared
make all-gcc all-target-libgcc -j 20
make install-strip-gcc install-strip-target-libgcc -j 20
cd ~/mingw/build
rm -rf *
../configure --prefix=$PREFIX/$TARGET --with-default-msvcrt=ucrt --host=$TARGET
make -j 24
make install-strip -j 24
# 构建交叉工具链时multilib在$TARGET/lib/32而不是$TARGET/lib32下
cd $PREFIX/$TARGET/lib
ln -s ../lib32 32
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-multilib --enable-languages=c,c++ --enable-nls --disable-sjlj-exceptions --enable-threads=win32 --prefix=$PREFIX --target=$TARGET
make -j 20
make install-strip -j 20
# 单独安装带调试符号的库文件
make install-target-libgcc install-target-libstdc++-v3 install-target-libatomic install-target-libquadmath -j 20
在第15步中我们保留了以下库的调试符号:libgcc libstdc++ libatomic libquadmath。但需要注意的是,x86_64下libgcc名为libgcc_s_seh-1.dll
,而i386下libgcc名为libgcc_s_dw2-1.dll
。
接下来逐个完成剥离操作:
# 生成独立的调试符号文件
$TARGET-objcopy --only-keep-debug $PREFIX/$TARGET/lib/libgcc_s_seh-1.dll $PREFIX/$TARGET/lib/libgcc_s_seh-1.dll.debug
# 剥离动态库的调试符号
$TARGET-strip $PREFIX/$TARGET/lib/libgcc_s_seh-1.dll
# 关联调试符号和动态库
$TARGET-objcopy --add-gnu-debuglink=$PREFIX/$TARGET/lib/libgcc_s_seh-1.dll.debug $PREFIX/$TARGET/lib/libgcc_s_seh-1.dll
# 重复上述操作直到处理完所有动态库
cd ~/pexports
mkdir build
cd build
../configure --prefix=$PREFIX
make -j 20
make install-strip -j 20
# 添加pexports前缀
mv $PREFIX/bin/pexports $PREFIX/bin/$TARGET-pexports
cd ~
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
构建mingw加拿大工具链
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w64-mingw32 | x86_64-w64-mingw32 |
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w64-mingw32
export TARGET=$HOST
export PREFIX=~/$HOST-native-gcc15
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-multilib --enable-languages=c,c++ --enable-nls --disable-sjlj-exceptions --enable-threads=win32 --prefix=$PREFIX --target=$TARGET --host=$HOST
make -j 20
make install-strip -j 20
此时我们执行如下命令:
cd $PREFIX/bin
file *.dll
会得到如下结果:
libatomic-1.dll: PE32 executable (DLL) (console) Intel 80386 (stripped to external PDB), for MS Windows, 10 sections
libquadmath-0.dll: PE32 executable (DLL) (console) Intel 80386 (stripped to external PDB), for MS Windows, 10 sections
libssp-0.dll: PE32 executable (DLL) (console) Intel 80386 (stripped to external PDB), for MS Windows, 10 sections
libstdc++-6.dll: PE32 executable (DLL) (console) Intel 80386 (stripped to external PDB), for MS Windows, 10 sections
由此可见,make install-strip
时安装的dll是x86而非x86_64的,这是由于开启multilib后,gcc的安装脚本会后安装multilib对应的dll,导致32位dll覆盖64位dll。
同时,我们会发现lib
和lib32
目录下没有这些dll,这是因为gcc的安装脚本默认将它们安装到了bin目录下。综上所述,dll的安装是完全错误的。
还可以发现,include
、lib
和lib32
目录下都没有libc和sdk文件。故我们需要手动从先前安装的交叉工具链中复制这些文件。
这样不但不需要再次编译mingw-w64,而且可以直接复制编译交叉工具链时生成的调试符号文件,不需要再次剥离调试符号。
rm *.dll
cd ~/$BUILD-host-$TARGET-target-gcc15/$TARGET
# ldscripts会在后续安装binutils时安装
cp -n lib/* $PREFIX/lib
cp -n lib32/* $PREFIX/lib32
cp -nr include/* $PREFIX/include
在接下来的5步中,我们将构建编译gdb所需的依赖项。具体说明请参见构建gdb的要求。
cd ~/python-embed
$TARGET-pexports python311.dll > libpython.def
$TARGET-dlltool -D python311.dll -d libpython.def -l libpython.a
cd ~/gmp
export GMP=~/gmp/install
mkdir build
cd build
# 禁用动态库,否则编译出来的gdb会依赖libgmp.dll
../configure --host=$HOST --prefix=$GMP --disable-shared
make -j 20
make install-strip -j 20
cd ~/expat/expat
export EXPAT=~/expat/install
mkdir build
cd build
# 此处也需要禁用动态库
../configure --prefix=$EXPAT --host=$HOST --disable-shared
make -j 20
make install-strip -j 20
cd ~/iconv
export ICONV=~/iconv/install
mkdir build
cd build
# 此处也需要禁用动态库
../configure --prefix=$ICONV --host=$HOST --disable-shared
make -j 20
make install-strip -j 20
cd ~/mpfr
export MPFR=~/mpfr/install
mkdir build
cd build
# 此处也需要禁用动态库
../configure --prefix=$MPFR --host=$HOST --with-gmp=$GMP --disable-shared
make -j 20
make install-strip -j 20
要编译带有python支持的gdb就必须在编译gdb时传入python安装信息,但在交叉环境中提供这些信息是困难的。因此我们需要手动将这些信息传递给configure
脚本。
具体说明请参见使用交叉编译器编译带有python支持的gdb。
编写一个python脚本以提供上述信息:
import sys
import os
from gcc_environment import environment
# sys.argv[0] shell脚本路径
# sys.argv[1] binutils/gdb/python-config.py路径
# sys.argv[2:] python脚本所需的参数
def get_config() -> None:
assert len(sys.argv) >= 3, "Too few args"
env = environment("")
python_dir = env.lib_dir_list["python-embed"]
result_list = {
"--includes": f"-I{os.path.join(python_dir, 'include')}",
"--ldflags": f"-L{python_dir} -lpython",
"--exec-prefix": f"-L{python_dir}",
}
option_list = sys.argv[2:]
for option in option_list:
if option in result_list:
print(result_list[option])
return
assert False, f'Invalid option list: {" ".join(option_list)}'
if __name__ == "__main__":
get_config()
编写一个shell脚本以转发参数给上述python脚本:
# 获取当前文件的绝对路径
current_file="$(readlink -f $0)"
# 提取当前文件夹
current_dir="$(dirname $current_file)"
# 将接受到的参数转发给python_config.py
python3 "$current_dir/python_config.py" $@
值得注意的是,gdb依赖于c++11提供的条件变量,而win32线程模型仅在Windows Vista和Windows Server 2008之后的系统上支持该功能,即要求_WIN32_WINNT>=0x0600,而默认情况下该条件是不满足的。
因此需要手动设置CXXFLAGS
来指定Windows版本。否则在编译gdbsupport时将会产生如下错误:
.../std_mutex.h:164:5: 错误: ‘__gthread_cond_t’ does not name a type; did you mean ‘__gthread_once_t’?
164 | __gthread_cond_t* native_handle() noexcept { return &_M_cond; }
| ^~~~~~~~~~~~~~~~
| __gthread_once_t
交叉编译带python支持的gdb的所有要求都已经满足了,下面开始编译binutils和gdb:
cd ~/binutils/build
rm -rf *
../configure --host=$HOST --target=$TARGET --prefix=$PREFIX --disable-werror --with-gmp=$GMP --with-mpfr=$MPFR --with-expat --with-libexpat-prefix=$EXPAT --with-libiconv-prefix=$ICONV --with-system-gdbinit=$PREFIX/share/.gdbinit --with-python=$HOME/toolchains/script/python_config.sh CXXFLAGS=-D_WIN32_WINNT=0x0600
make -j 20
make install-strip -j 20
我们在Window下也提供pexports实用工具,下面开始编译pexports:
cd ~/pexports/build
rm -rf *
../configure --prefix=$PREFIX --host=$HOST
make -j 20
make install-strip -j 20
cp ~/python-embed
cp python* $PREFIX/bin
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-native-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
在开启multilib后,lib
和lib32
目录下会各有一份dll,这也就是为什么不能将dll文件复制到bin
目录下。
因而在使用时需要将bin
,lib
和lib32
文件夹都添加到PATH环境变量。程序在加载dll时Windows会顺序搜索PATH中的目录,直到找到一个dll可以被加载。
因此同时将lib
和lib32
添加到PATH即可实现根据程序体系结构选择相应的dll。
如果将lib
和lib32
下的dll分别复制到System32
和SysWOW64
目录下,则只需要将bin
文件夹添加到PATH环境变量,但不推荐这么做。
值得注意的是,.debug文件需要和.dll文件处于同一级目录下,否则调试时需要手动加载符号文件。
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | arm-none-eabi |
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=arm-none-eabi
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
cd ~/binutils/build
rm -rf *
export ORIGIN='$$ORIGIN'
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --with-system-gdbinit=$PREFIX/share/.gdbinit LDFLAGS="-Wl,-rpath='$ORIGIN'/../lib64" --enable-gold
make -j 20
make install-strip -j 20
unset ORIGIN
echo "export PATH=$PREFIX/bin:"'$PATH' >> ~/.bashrc
source ~/.bashrc
这是一个不使用newlib的完全独立的工具链,故而需要禁用所有依赖宿主系统的库和特性。此时支持的库仅包含libstdc++和libgcc。由于此时禁用了动态库,故不需要再手动剥离调试符号。
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-threads --disable-hosted-libstdcxx --disable-libstdcxx-verbose --disable-shared --without-headers --disable-libvtv --disable-libsanitizer --disable-libssp --disable-libquadmath --disable-libgomp
make -j 20
make install-strip -j 20
make install-target-libstdc++-v3 install-target-libgcc -j 20
编译出的arm-none-eabi-gdb依赖libstdc++,故需要从gcc本地工具链中复制一份。同时独立工具链不会安装pretty-printer,故也需要复制一份。
cd ~/$BUILD-native-gcc15
cp lib64/libstdc++.so.6 $PREFIX/lib64
cp lib64/libgcc_s.so.1 $PREFIX/lib64
cp -r share/gcc-15.0.0 $PREFIX/share
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w64-mingw32 | arm-none-eabi |
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w64-mingw32
export TARGET=arm-none-eabi
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
请参阅前文构建出libpython.a, libgmp, libexpat, libiconv, libmpfr。
原理请参阅x86_64-w64-mingw32本地gdb构建。
cd ~/binutils/build
rm -rf *
../configure --host=$HOST --target=$TARGET --prefix=$PREFIX --disable-werror --with-gmp=$GMP --with-mpfr=$MPFR --with-expat --with-libexpat-prefix=$EXPAT --with-libiconv-prefix=$ICONV --with-system-gdbinit=$PREFIX/share/.gdbinit --with-python=$HOME/toolchains/script/python_config.sh --enable-gold CXXFLAGS=-D_WIN32_WINNT=0x0600
make -j 20
make install-strip -j 20
原理请参阅arm独立交叉工具链。
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-nls --host=$HOST --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-threads --disable-hosted-libstdcxx --disable-libstdcxx-verbose --disable-shared --without-headers --disable-libvtv --disable-libsanitizer --disable-libssp --disable-libquadmath --disable-libgomp
make -j 20
make install-strip -j 20
make install-target-libstdc++-v3 install-target-libgcc -j 20
从mingw交叉工具链中复制动态库:
cd ~/$BUILD-host-$HOST-target-gcc15/$HOST
cp lib/libstdc++-6.dll $PREFIX/bin
cp lib/libgcc_s_seh-1.dll $PREFIX/bin
从gcc本地工具链中复制pretty-printer:
cd ~/$BUILD-native-gcc15
cp -r share/gcc-15.0.0 $PREFIX/share
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | x86_64-elf |
具体请参阅构建arm独立交叉工具链。
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=x86_64-elf
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
cd ~/binutils/build
rm -rf *
export ORIGIN='$$ORIGIN'
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --with-system-gdbinit=$PREFIX/share/.gdbinit LDFLAGS="-Wl,-rpath='$ORIGIN'/../lib64" --enable-gold
make -j 20
make install-strip -j 20
unset ORIGIN
echo "export PATH=$PREFIX/bin:"'$PATH' >> ~/.bashrc
source ~/.bashrc
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --disable-multilib --enable-languages=c,c++ --disable-threads --disable-hosted-libstdcxx --disable-libstdcxx-verbose --disable-shared --without-headers --disable-libvtv --disable-libsanitizer --disable-libssp --disable-libquadmath --disable-libgomp
make -j 20
make install-strip -j 20
make install-target-libstdc++-v3 install-target-libgcc -j 20
cd ~/$BUILD-native-gcc15
cp lib64/libstdc++.so.6 $PREFIX/lib64
cp lib64/libgcc_s.so.1 $PREFIX/lib64
cp -r share/gcc-15.0.0 $PREFIX/share
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w64-mingw32 | x86_64-elf |
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w64-mingw32
export TARGET=x86_64-elf
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
请参阅前文构建出libpython.a, libgmp, libexpat, libiconv, libmpfr。
原理请参阅x86_64-w64-mingw32本地gdb构建。
cd ~/binutils/build
rm -rf *
../configure --host=$HOST --target=$TARGET --prefix=$PREFIX --disable-werror --with-gmp=$GMP --with-mpfr=$MPFR --with-expat --with-libexpat-prefix=$EXPAT --with-libiconv-prefix=$ICONV --with-system-gdbinit=$PREFIX/share/.gdbinit --with-python=$HOME/toolchains/script/python_config.sh --enable-gold CXXFLAGS=-D_WIN32_WINNT=0x0600
make -j 20
make install-strip -j 20
原理请参阅arm独立交叉工具链。
cd ~/gcc/build
rm -rf *
../configure --disable-werror --enable-nls --host=$HOST --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-threads --disable-hosted-libstdcxx --disable-libstdcxx-verbose --disable-shared --without-headers --disable-libvtv --disable-libsanitizer --disable-libssp --disable-libquadmath --disable-libgomp
make -j 20
make install-strip -j 20
make install-target-libstdc++-v3 install-target-libgcc -j 20
从mingw交叉工具链中复制动态库:
cd ~/$BUILD-host-$HOST-target-gcc15/$HOST
cp lib/libstdc++-6.dll $PREFIX/bin
cp lib/libgcc_s_seh-1.dll $PREFIX/bin
从gcc本地工具链中复制pretty-printer:
cd ~/$BUILD-native-gcc15
cp -r share/gcc-15.0.0 $PREFIX/share
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | x86_64-ubuntu2004-linux-gnu |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台。为了和本地工具链加以区分,此处修改交叉工具链的vender字段。在vender字段中亦可以添加目标系统的版本以示区分。 值得注意的是,此处目标系统为ubuntu 20.04,使用的libc为glibc 2.30。交叉工具链的glibc要与目标系统匹配。由于x32已经濒临淘汰,故此处不再编译x32的multilib。
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=x86_64-ubuntu2004-linux-gnu
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
cd ~/binutils/build
rm -rf *
export ORIGIN='$$ORIGIN'
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --disable-binutils --with-system-gdbinit=$PREFIX/share/.gdbinit LDFLAGS="-Wl,-rpath='$ORIGIN'/../lib64"
make -j 20
make install-strip -j 20
unset ORIGIN
值得注意的是,binutils的一部分会安装到$PREFIX/$TARGET
目录下,而此目录下的lib64存放的是目标平台的glibc,故不能设置rpath
。
cd ~/binutils/build
rm -rf *
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --disable-gdb --enable-gold
make -j 20
make install-strip -j 20
echo "export PATH=$PREFIX/bin:"'$PATH' >> ~/.bashrc
source ~/.bashrc
cd ~/linux
make ARCH=x86 INSTALL_HDR_PATH=$PREFIX/$TARGET headers_install
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-shared
make all-gcc -j 20
make install-strip-gcc -j 20
由于当前的工具链尚不完整,故需要手动设置libc_cv_forced_unwind=yes
,否则会出现:
configure: error: forced unwind support is required
glibc头文件安装命令如下:
cd ~/glibc
mkdir build
cd build
../configure --host=$TARGET --build=$BUILD --prefix=$PREFIX/$TARGET --disable-werror libc_cv_forced_unwind=yes
make install-headers
在安装完头文件后,还需要手动新建include/gnu/stubs.h
文件,若缺少该文件,则无法编译出libgcc。该文件会在安装完整glibc时被覆盖。
touch $PREFIX/$TARGET/include/gnu/stubs.h
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-shared
make all-target-libgcc -j 20
make install-strip-target-libgcc -j 20
值得注意的是,尽管glibc本身不会使用c++编译器,但构建脚本会使用c++编译器进行链接,故c++编译器也需要设置。
cd ~/glibc/build
rm -rf *
../configure --host=i686-linux-gnu --build=$BUILD --prefix=$PREFIX/$TARGET --disable-werror CC="$TARGET-gcc -m32" CXX="$TARGET-g++ -m32"
make -j 20
make install -j 20
cd $PREFIX/$TARGET/lib
$TARGET-strip gconv/*.so
$TARGET-strip audit/*.so
$TARGET-strip ../libexec/getconf/*
$TARGET-strip ../sbin/*
$TARGET-objcopy --only-keep-debug libc-2.30.so libc-2.30.so.debug
$TARGET-objcopy --add-gnu-debuglink=libc-2.30.so.debug libc-2.30.so
# 同理剥离出其他需要的符号文件
$TARGET-strip *.so
此时只有lib/libc.so
需要修改,该文件的内容如下:
// lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /home/luo/x86_64-linux-gnu-host-x86_64-ubuntu2004-linux-gnu-target-gcc15/x86_64-ubuntu2004-linux-gnu/lib/libc.so.6 /home/luo/x86_64-linux-gnu-host-x86_64-ubuntu2004-linux-gnu-target-gcc15/x86_64-ubuntu2004-linux-gnu/lib/libc_nonshared.a AS_NEEDED ( /home/luo/x86_64-linux-gnu-host-x86_64-ubuntu2004-linux-gnu-target-gcc15/x86_64-ubuntu2004-linux-gnu/lib/ld-linux.so.2 ) )
可以看到其中使用的是绝对地址,这会导致移动安装位置后,无法正确链接。故需要修改为使用相对路径:
// lib/libc.so
OUTPUT_FORMAT(elf32-i386)
GROUP (libc.so.6 libc_nonshared.a AS_NEEDED (ld-linux.so.2))
由于在此multilib环境下,交叉编译器编译时lib32目录下存放32位multilib而lib目录下存放64位multilib,故需要调整glibc的位置。而ldscript需要始终存放在lib目录下。
mv $PREFIX/$TARGET/lib $PREFIX/$TARGET/lib32
mkdir $PREFIX/$TARGET/lib
mv $PREFIX/$TARGET/lib32/ldscripts $PREFIX/$TARGET/lib
cd ~/glibc/build
rm -rf *
../configure --host=$TARGET --build=$BUILD --prefix=$PREFIX/$TARGET --disable-werror
make -j 20
make install -j 20
cd $PREFIX/$TARGET/lib
$TARGET-strip gconv/*.so
$TARGET-strip audit/*.so
$TARGET-strip ../libexec/getconf/*
$TARGET-strip ../sbin/*
$TARGET-objcopy --only-keep-debug libc-2.30.so libc-2.30.so.debug
$TARGET-objcopy --add-gnu-debuglink=libc-2.30.so.debug libc-2.30.so
# 同理剥离出其他需要的符号文件
$TARGET-strip *.so
同理修改libc.so
,libm.a
和libm.so
:
// libc.so
OUTPUT_FORMAT(elf64-x86-64)
GROUP (libc.so.6 libc_nonshared.a AS_NEEDED (ld-linux-x86-64.so.2))
// libm.a
OUTPUT_FORMAT(elf64-x86-64)
GROUP (libm-2.30.a libmvec.a)
// libm.so
OUTPUT_FORMAT(elf64-x86-64)
GROUP (libm.so.6 AS_NEEDED(libmvec_nonshared.a libmvec.so.1))
cd $PREFIX/$TARGET/lib
ln -s ../lib32 32
在gcc/libsanitizer/asan/asan_linux.cpp
中默认没有包含linux/limits.h
文件,这会导致编译的时候缺少PATH_MAX
宏,故将其修改为:
// gcc/libsanitizer/asan/asan_linux.cpp
# include <dlfcn.h>
# include <fcntl.h>
# include <limits.h>
# include <pthread.h>
# include <stdio.h>
# include <sys/mman.h>
# include <sys/resource.h>
# include <sys/syscall.h>
# include <sys/time.h>
# include <sys/types.h>
# include <unistd.h>
# include <unwind.h>
# include <linux/limits.h> // < 添加linux/limits.h头文件
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++
make -j 20
make install-strip -j 20
# 单独安装带调试符号的库文件
make install-target-libgcc install-target-libstdc++-v3 install-target-libatomic install-target-libquadmath install-target-libgomp -j 20
在第70步中我们保留了以下库的调试符号:libgcc libstdc++ libatomic libquadmath libgomp
接下来逐个完成剥离操作:
# 生成独立的调试符号文件
objcopy --only-keep-debug $PREFIX/lib64/libgcc_s.so.1 $PREFIX/lib64/libgcc_so.1.debug
# 剥离动态库的调试符号
strip $PREFIX/lib64/libgcc_s.so.1
# 关联调试符号和动态库
objcopy --add-gnu-debuglink=$PREFIX/lib64/libgcc_s.so.1.debug $PREFIX/lib64/libgcc_s.so.1
# 重复上述操作直到处理完所有动态库
lib32目录下是纯净的glibc文件,故以lib32为参照经行文件复制,建议使用python脚本完成:
import shutil
import os
home_dir = os.environ["HOME"]
lib_prefix = os.path.join(home_dir, "x86_64-linux-gnu-host-x86_64-ubuntu2004-linux-gnu-gcc15", "x86_64-ubuntu2004-linux-gnu")
lib_dir = os.path.join(env.lib_prefix, "lib")
lib32_dir = os.path.join(env.lib_prefix, "lib32")
lib64_dir = os.path.join(env.lib_prefix, "lib64")
for file in os.listdir(lib_dir):
lib_path = os.path.join(lib_dir, file)
lib32_path = os.path.join(lib32_dir, file)
lib64_path = os.path.join(lib64_dir, file)
if os.path.exists(lib32_path) or file == "ld-linux-x86-64.so.2":
shutil.move(lib_path, lib64_path)
lib32目录下是纯净的glibc文件,直接移动即可:
cd $PREFIX/$TARGET
mov lib32/* lib
从x86_64-linux-gnu本地工具链中复制动态库:
cd ~/$BUILD-host-$HOST-target-gcc15/$HOST
cp lib64/libstdc++.so.6 $PREFIX/lib64
cp lib64/libgcc_s.so.1 $PREFIX/lib64
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | loongarch64-linux-gnu |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=loongarch64-linux-gnu
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=loongarch
cd ~/binutils/build
rm -rf *
export ORIGIN='$$ORIGIN'
../configure --disable-werror --enable-nls --target=$TARGET --prefix=$PREFIX --disable-gdbserver--with-system-gdbinit=$PREFIX/share/.gdbinit LDFLAGS="-Wl,-rpath='$ORIGIN'/../lib64"
make -j 20
make install-strip -j 20
unset ORIGIN
echo "export PATH=$PREFIX/bin:"'$PATH' >> ~/.bashrc
source ~/.bashrc
cd ~/linux
make INSTALL_HDR_PATH=$PREFIX/$TARGET headers_install
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-shared
make all-gcc -j 20
make install-strip-gcc -j 20
cd ~/glibc
mkdir build
cd build
../configure --host=$TARGET --build=$BUILD --prefix=$PREFIX/$TARGET --disable-werror libc_cv_forced_unwind=yes
make install-headers
touch $PREFIX/$TARGET/include/gnu/stubs.h
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++ --disable-shared
make all-target-libgcc -j 20
make install-strip-target-gcc -j 20
cd ~/glibc/build
rm -rf *
../configure --host=$TARGET --build=$BUILD --prefix=$PREFIX/$TARGET --disable-werror
make -j 20
make install -j 20
需要修改lib/libc.so
为使用相对路径:
// lib/libc.so
OUTPUT_FORMAT(elf64-loongarch)
GROUP (libc.so.6 libc_nonshared.a AS_NEEDED(ld-linux-loongarch-lp64d.so.1))
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --enable-nls --target=$TARGET --prefix=$PREFIX --enable-multilib --enable-languages=c,c++
make -j 20
make install-strip -j 20
# 单独安装带调试符号的库文件
make install-target-libgcc install-target-libstdc++-v3 install-target-libatomic install-target-libquadmath install-target-libgomp -j 20
从x86_64-linux-gnu本地工具链中复制动态库:
cd ~/$BUILD-host-$HOST-target-gcc15/$HOST
cp lib64/libstdc++.so.6 $PREFIX/lib64
cp lib64/libgcc_s.so.1 $PREFIX/lib64
对limits.h文件末尾的修改如下:
// lib/gcc/loongarch64-linux-gnu/15.0.0/include/limits.h
#endif /* _LIMITS_H___ */
#undef MB_LEN_MAX
#define MB_LEN_MAX 16
cd ~/binutils/build
rm -rf *
../configure --prefix=$PREFIX --host=$TARGET --target=$TARGET --disable-werror --disable-binutils --disable-gdb --enable-gdbserver --enable-nls
make -j 20
# 其他工具的体系结构与host不同,覆盖host工具会导致错误,故只安装gdbserver
make install-strip-gdbserver -j 20
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w32-mingw64 | loongarch64-linux-gnu |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w32-mingw64
export TARGET=loongarch64-linux-gnu
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=loongarch
cd ~/binutils/build
rm -rf *
export ORIGIN='$$ORIGIN'
../configure --disable-werror --disable-nls --target=$TARGET --prefix=$PREFIX --disable-gdbserver --with-gmp=$GMP --with-mpfr=$MPFR --with-expat --with-libexpat-prefix=$EXPAT --with-libiconv-prefix=$ICONV --with-system-gdbinit=$PREFIX/share/.gdbinit --with-python=$HOME/toolchains/script/python_config.sh CXXFLAGS=-D_WIN32_WINNT=0x0600
make -j 20
make install-strip -j 20
cd ~/gcc/build
rm -rf *
../configure --disable-werror --disable-bootstrap --disable-nls --host=$HOST --target=$TARGET --prefix=$PREFIX --disbale-multilib --enable-languages=c,c++
make -j 20
make install-strip -j 20
此工具链所需的linux头文件、glibc等已经在构建交叉工具链时完成构建,只需复制即可。
export CROSS_PREFIX=~/$BUILD-host-$TARGET-target-gcc15
export SRC_PREFIX=$CROSS_PREFIX/$TARGET
export DST_PREFIX=$PREFIX/$TARGET
# 个别工具链还需要复制lib64,如果目录下有该文件夹则一并复制
# 换而言之,复制除bin外的所有文件夹
cp -rf $SRC_PREFIX/include $DST_PREFIX/include
cp -rf $SRC_PREFIX/lib $DST_PREFIX/lib
# 复制gdbserver
cp $CROSS_PREFIX/bin/gdbserver $PREFIX/bin/gdbserver
cd ~
cp ~/toolchains/script/.gdbinit $PREFIX/share
export PACKAGE=$HOST-host-$TARGET-target-gcc15
tar -cf $PACKAGE.tar $PACKAGE/
xz -ev9 -T 0 --memlimit=$MEMORY $PACKAGE.tar
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | arm-linux-gnueabi |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=arm-linux-gnueabi
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=arm
参考loongarch64-linux-gnu交叉工具链构建流程完成构建。
值得注意的是,需要修改lib/libc.so
为:
// lib/libc.so
OUTPUT_FORMAT(elf32-littlearm)
GROUP (libc.so.6 libc_nonshared.a AS_NEEDED (ld-linux.so.3))
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w32-mingw64 | arm-linux-gnueabi |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w32-mingw64
export TARGET=arm-linux-gnueabi
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=arm
参考arm-linux-gnueabi交叉工具链和 loongarch64-linux-gnu加拿大工具链构建流程完成构建。
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | arm-linux-gnueabihf |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=arm-linux-gnueabihf
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=arm
参考loongarch64-linux-gnu交叉工具链构建流程完成构建。
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w32-mingw64 | arm-linux-gnueabihf |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w32-mingw64
export TARGET=arm-linux-gnueabihf
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=arm
参考arm-linux-gnueabihf交叉工具链和 loongarch64-linux-gnu加拿大工具链构建流程完成构建。
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-linux-gnu | loongarch64-loongnix-linux-gnu |
这是为loongnix操作系统交叉编译所需要的工具链,值得注意的是,loongnix使用的是修改过的Linux 4.19和Glibc 2.28而非主线版本。 故而需要从loongnix源上下载Linux和Glibc的源代码。
项目 | URL |
---|---|
Linux | https://pkg.loongnix.cn/loongnix/pool/main/l/linux/linux_4.19.190.8.22.orig.tar.gz |
Glibc | https://pkg.loongnix.cn/loongnix/pool/main/g/glibc/glibc_2.28.orig.tar.gz |
export BUILD=x86_64-linux-gnu
export HOST=$BUILD
export TARGET=loongarch64-loongnix-linux-gnu
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=loongarch
参见loongarch64-linux-gnu工具链的构建流程。
与loongarch64-linux-gnu工具链不同,此版本的glibc在configure时需要额外增加--enable-obsolete-rpc
选项。
由于Glibc和Linux内核版本较老旧,此平台不支持libsanitizer
,故而需要增加--disable-libsanitizer
选项。
此版本的glibc的动态链接器名为ld.so.1
,故而链接器脚本需要做如下修改:
// lib/libc.so
OUTPUT_FORMAT(elf64-loongarch)
GROUP (libc.so.6 libc_nonshared.a AS_NEEDED (ld.so.1))
同时在使用工具链时需要增加链接选项-Wl,-dynamic-linker=/lib64/ld.so.1
以设置动态链接器路径。
build | host | target |
---|---|---|
x86_64-linux-gnu | x86_64-w32-mingw64 | loongarch64-loongnix-linux-gnu |
值得注意的是,libc版本、种类不同的工具链是不同的工具链,它们具有不同的target平台,此处目标系统使用的libc为glibc 2.39。交叉工具链的glibc要与目标系统匹配。
export BUILD=x86_64-linux-gnu
export HOST=x86_64-w32-mingw64
export TARGET=loongarch64-loongnix-linux-gnu
export PREFIX=~/$HOST-host-$TARGET-target-gcc15
# Linux头文件架构
export ARCH=arm
参考loongarch64-loongnix-linux-gnu交叉工具链和 loongarch64-linux-gnu加拿大工具链构建流程完成构建。
其他GCC工具链的编译流程大同小异,此处不再赘述,具体可参照对应的编译脚本。