龙芯3A5000下最新gcc 12.1交叉编译器获取与使用

    本来这篇文章是要写成自己如何一步步编译成功gcc12.1的,无论是在龙芯35000下编译还是在x86机器下构建交叉编译工具链,折腾到最后,gcc12.1倒是编译出来了,glibc不知道应该怎么搞,最后发现龙芯官方github里面有人编译好了gcc12.1 ,下载地址:

https://github.com/sunhaiyong1978/CLFS-for-LoongArch

https://github.com/loongson/build-tools    

可以直接从第一个下载链接里面去下载完整的交叉编译工具链,然后放到x86 linux下面使用,使用之前配置一下环境变量

vi ~/.bashrc

export PATH=/phx/cross-tools/bin:$PATH
export LD_LIBRARY_PATH=/phx/cross-tools/lib:$LD_LIBRARY_PATH
export CROSS_COMPILE=loongarch64-linux-

  然后编译:

loongarch64-unknown-linux-gnu-gcc -o test1 test.c -static

  复制test1 到龙芯机器里面可以正常运行。

然后再说一下自己编译的折腾过程记录:

sudo apt update
sudo apt install  texinfo autoconf automake libiberty-dev sed flex bison gzip gettext  libelf-dev libgomp1 make tar libgmp-dev libmpfr-dev libmpc-dev libisl-dev build-essential -y

我最后是在debian 11下面编译的,注意必须安装以上gcc编译依赖,特别是texinfo等,编译binutils的时候这都是必须要用的。

 下面是从github找的一个编译脚本(narke/gcc-cross-compiler: A script to cross-compile GCC toolchain for various target architectures. (github.com)),我修改了gcc 12.1的checksum等

#!/usr/bin/env python3
""" Cross-compiler toolchain build script

    Possible target platforms are:
     aarch64    ARM64
     amd64      AMD64 (x86-64, x64)
     arm32      ARM
     ia32       IA-32 (x86, i386)
     ia64       IA-64 (Itanium)
     mips32     MIPS little-endian 32b
     mips32eb   MIPS big-endian 32b
     mips64     MIPS little-endian 64b
     ppc32      32-bit PowerPC
     ppc64      64-bit PowerPC
     sparc32    SPARC V8
     sparc64    SPARC V9
     lm32       LatticeMico32

    The toolchain is installed into directory specified by the
    CROSS_PREFIX environment variable. If the variable is not
    defined, /usr/local/cross/ is used as default.

    If '--install no' is present, the toolchain still uses the
    CROSS_PREFIX as the target directory but the installation
    copies the files into PKG/ subdirectory without affecting
    the actual root file system. That is only useful if you do
    not want to run the script under the super user."""

# Copyright (c) 2016-2020 Konstantin Tcholokachvili
# All rights reserved.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Credits:
# This script is inspired by toolchain.sh made by Martin Decky for HelenOS
# project.

import os
import sys
import ftplib
import shutil
import pathlib
import tarfile
import hashlib
import tempfile
import argparse
import subprocess


# Toolchain versions
BINUTILS_VERSION = '2.38'
GCC_VERSION = '12.1.0'
GDB_VERSION = '12.1'

BASEDIR = os.getcwd()
BINUTILS_TARBALL = 'binutils-{}.tar.xz'.format(BINUTILS_VERSION)
GCC_TARBALL = 'gcc-{}.tar.xz'.format(GCC_VERSION)
GDB_TARBALL = 'gdb-{}.tar.xz'.format(GDB_VERSION)

INSTALL_DIR = BASEDIR + '/PKG'

BINUTILS_CHECKSUM = '6e39cad1bb414add02b5b1169c18fdc5'
GCC_CHECKSUM = 'ed45b55ee859ada4b25a1e76e0c4d966'
GDB_CHECKSUM = '759a1b8d2b4d403367dd0e14fa04643d'

GMP_MAIN = """
#define GCC_GMP_VERSION_NUM(a, b, c) \
        (((a) << 16L) | ((b) << 8) | (c))

#define GCC_GMP_VERSION \
        GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)

#if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4, 3, 2)
        choke me
#endif
"""

MPFR_MAIN = """
#if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)
        choke me
#endif
"""

MPC_MAIN = """
#if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)
        choke me
#endif
"""

ISL_MAIN = """
isl_ctx_get_max_operations (isl_ctx_alloc ());
"""

TARGETS = {
    'aarch64': 'aarch64-linux-gnu',
    'amd64': 'amd64-linux-gnu',
    'arm32': 'arm-linux-gnueabi',
    'ia32': 'i686-pc-linux-gnu',
    'ia64': 'ia64-pc-linux-gnu',
    'mips32': 'mipsel-linux-gnu',
    'mips32eb': 'mips-linux-gnu',
    'mips64': 'mips64el-linux-gnu',
    'ppc32': 'ppc-linux-gnu',
    'ppc64': 'ppc64-linux-gnu',
    'sparc32': 'sparc-leon3-linux-gnu',
    'sparc64': 'sparc64-linux-gnu',
    'lm32': 'lm32-elf',
    "loongarch64": "loongarch64-linux-gnu"
}


def check_header(dependency, header, body):
    """Check the presence of a header file needed to compile sources."""
    code = """
    #include %s

    int main()
    {
        %s
        return 0;
    }
    """ % (header, body)

    filename = tempfile.NamedTemporaryFile(suffix='.c')
    filename.write(code.encode())

    try:
        subprocess.check_call(['cc', '-c', '-o', '{}.o'.format(filename.name[:-2]),
                               '{}'.format(filename.name)])
        os.unlink('{}.o'.format(filename.name[:-2]))
    except subprocess.CalledProcessError:
        print('{0} of {1} not found'.format(header, dependency))
        sys.exit()


def check_headers():
    """Check that all required headers are present."""
    check_header('GMP', '<gmp.h>', GMP_MAIN)
    check_header('MPFR', '<mpfr.h>', MPFR_MAIN)
    check_header('MPC', '<mpc.h>', MPC_MAIN)
    check_header('isl', '<isl/ctx.h>', ISL_MAIN)


def show_dependencies():
    """Notice informing about dependencies for a successful compilation."""

    message = """IMPORTANT NOTICE:

    For a successful compilation and use of the cross-compiler
    toolchain you need at least the following dependencies.

    Please make sure that the dependencies are present in your
    system. Otherwise the compilation process might fail after
    a few seconds or minutes."

    - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell
    - gettext, zlib, Texinfo, libelf, libgomp
    - GNU Make, Coreutils, Sharutils, tar
    - GNU Multiple Precision Library (GMP)
    - MPFR
    - MPC
    - integer point manipulation library (isl)
    - native C and C++ compiler, assembler and linker
    - native C and C++ standard library with headers"""

    print(message)


def download(toolname, tarball):
    """Downlaod a source archive."""
    if toolname == 'gcc':
        path = '/gnu/gcc/gcc-{}/'.format(GCC_VERSION)
    else:
        path = '/gnu/{}/'.format(toolname)

    try:
        ftp = ftplib.FTP('ftp.gnu.org')
        ftp.login()
        ftp.cwd(path)
        with open('{}'.format(tarball), 'wb') as ftpfile:
            ftp.retrbinary('RETR {}'.format(tarball), ftpfile.write)
        ftp.quit()
    except ftplib.all_errors:
        print('Error: Downoad of {} failed'.format(tarball))
        sys.exit()


def check_integrity(archive, checksum):
    """Check the md5 checksum of a tarball."""
    with open(archive, 'rb') as tarball:
        if hashlib.md5(tarball.read()).hexdigest() != checksum:
            print('Error: Wrong checksum for {}'.format(archive))
            sys.exit()


def prepare():
    """Prepare the compilation: get the sources and check their integrity."""
    show_dependencies()

    tools = {
        'binutils':
        {
            'tarball': BINUTILS_TARBALL,
            'checksum': BINUTILS_CHECKSUM
        },
        'gcc':
        {
            'tarball': GCC_TARBALL,
            'checksum': GCC_CHECKSUM
        },
        'gdb':
        {
            'tarball': GDB_TARBALL,
            'checksum': GDB_CHECKSUM
        }
    }

    for toolname in tools:
        if not os.path.isfile(tools[toolname]['tarball']):
            download(toolname, tools[toolname]['tarball'])
            check_integrity(tools[toolname]['tarball'],
                            tools[toolname]['checksum'])


def set_target_from_platform(platform):
    """Sets the triplet *-linux-* as target."""
    return TARGETS[platform]


def cleanup_dir(path):
    """Remove a directory ecursively."""
    if os.path.isdir(path):
        shutil.rmtree(path)


def create_dir(path):
    """Create a directory within a given path."""
    if not os.path.isdir(path):
        print('>>> Creating directory: {}'.format(path))
        pathlib.Path(path).mkdir(parents=True, exist_ok=True)


def unpack_tarball(tarball):
    """Extract file from a tarball."""
    with tarfile.open(tarball) as tar:
        tar.extractall('.')


def cleanup_previous_build(install, prefix, work_directory, obj_directory):
    """Remove files from the previous build."""

    print('>>> Removing previous content')
    if install:
        cleanup_dir(prefix)
        create_dir(prefix)

    cleanup_dir(work_directory)
    create_dir(work_directory)
    create_dir(obj_directory)


def unpack_tarballs(work_directory):
    """Unpack tarballs containing source code."""

    print('>>> Unpacking tarballs')
    os.chdir(work_directory)

    unpack_tarball(BASEDIR + '/' + BINUTILS_TARBALL)
    unpack_tarball(BASEDIR + '/' + GCC_TARBALL)
    unpack_tarball(BASEDIR + '/' + GDB_TARBALL)


def build_binutils(install, nb_cores, binutils_directory, target, prefix):
    """Build binutils."""

    os.chdir(binutils_directory)

    try:
        subprocess.check_call(['./configure', '--target={}'.format(target),
                               '--prefix={}'.format(prefix),
                               '--program-prefix={}-'.format(target),
                               '--disable-nls', '--disable-werror'])
    except subprocess.CalledProcessError:
        print('Error: binutils headers checking failed')
        sys.exit()

    os.environ['CFLAGS'] = '-Wno-error'

    try:
        subprocess.check_call(['make', '-j', str(nb_cores), 'all'])
    except subprocess.CalledProcessError:
        print('Error: binutils compilation failed')
        sys.exit()

    if install:
        cmd = ['make', 'install']
    else:
        cmd = ['make', 'install', 'DESTDIR={}'.format(INSTALL_DIR)]

    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
        print('Error: binutils installation failed ')
        sys.exit()


def build_gcc(*args):
    """Build GCC."""

    install, nb_cores, obj_directory, prefix, gcc_directory, target = args

    os.chdir(obj_directory)

    try:
        subprocess.check_call(['{}/configure'.format(gcc_directory),
                               '--target={}'.format(target),
                               '--prefix={}'.format(prefix),
                               '--program-prefix={}-'.format(target),
                               '--with-gnu-as', '--with-gnu-ld', '--disable-nls','--with-gcc-major-version-only','--enable-threads',
                                '--enable-languages=c,c++',
                               '--disable-multilib', '--disable-libgcj','--enable-tls',
                               '--disable-shared', '--enable-lto',
                               '--disable-werror'])
    except subprocess.CalledProcessError:
        print('Error: gcc headers checking failed')
        sys.exit()

    try:
        subprocess.check_call(['make', '-j', str(nb_cores), 'all-gcc'])
    except subprocess.CalledProcessError:
        print('Error: gcc compilation failed')
        sys.exit()

    if install:
        cmd = ['make', 'install-gcc']
    else:
        cmd = ['make', 'install-gcc', 'DESTDIR={}'.format(INSTALL_DIR)]

    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
        print('Error: gcc installation failed')
        sys.exit()


def build_gdb(install, nb_cores, gdb_directory, target, prefix):
    """Build GDB."""

    os.chdir(gdb_directory)

    try:
        subprocess.check_call(['./configure',
                               '--target={}'.format(target),
                               '--prefix={}'.format(prefix),
                               '--program-prefix={}-'.format(target),
                               '--enable-werror=no'])
    except subprocess.CalledProcessError:
        print('Error: gdb headers checking failed')
        sys.exit()

    try:
        subprocess.check_call(['make', '-j', str(nb_cores), 'all'])
    except subprocess.CalledProcessError:
        print('Error: gdb compilation failed')
        sys.exit()

    if install:
        cmd = ['make', 'install']
    else:
        cmd = ['make', 'install', 'DESTDIR={}'.format(INSTALL_DIR)]

    try:
        subprocess.check_call(cmd)
    except subprocess.CalledProcessError:
        print('Error: gdb installatior failed')
        sys.exit()


def build_target(platform, install, nb_cores):
    """Cross-compile gcc toolchain for a given architecture."""

    work_directory = BASEDIR + '/' + platform
    binutils_directory = work_directory + '/binutils-' + BINUTILS_VERSION
    gcc_directory = work_directory + '/gcc-' + GCC_VERSION
    obj_directory = work_directory + '/gcc-obj'
    gdb_directory = work_directory + '/gdb-' + GDB_VERSION

    target = set_target_from_platform(platform)

    if os.environ.get('CROSS_PREFIX'):
        cross_prefix = os.environ['CROSS_PREFIX']
    else:
        cross_prefix = '/usr/local/cross/'

    prefix = cross_prefix + platform

    os.environ['PATH'] += ':{0}{1}/bin'.format(INSTALL_DIR, prefix)
    os.environ['PATH'] += ':{0}/bin'.format(prefix)

    cleanup_previous_build(install, prefix, work_directory, obj_directory)
    unpack_tarballs(work_directory)

    build_binutils(install, nb_cores, binutils_directory, target, prefix)
    build_gcc(install, nb_cores, obj_directory, prefix, gcc_directory, target)
    build_gdb(install, nb_cores, gdb_directory, target, prefix)

    os.chdir(BASEDIR)
    print('>>> Cleaning up')
    cleanup_dir(work_directory)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-a', '--arch',
                        help='Target architecture',
                        type=str,
                        choices=['aarch64', 'amd64', 'arm32', 'ia32', 'ia64',
                                 'mips32', 'mips32eb', 'mips64', 'ppc32',
                                 'ppc64', 'sparc32', 'sparc64', 'lm32','loongarch64'],
                        required=True)
    parser.add_argument('-i', '--install',
                        help='Install in /usr/local/cross or just '
                        'keep cross-compiled binaries into the build directory',
                        type=str,
                        choices=['yes', 'no'],
                        required=True)
    parser.add_argument('-c', '--cores',
                        help='Number of CPU cores',
                        type=int, required=False, default=1)

    arguments = parser.parse_args()

    target_platform = arguments.arch
    INSTALL = arguments.install == 'yes'
    nb_cpu_cores = arguments.cores - 1

    check_headers()
    prepare()
    build_target(target_platform, INSTALL, nb_cpu_cores)

    MSG = 'installed' if arguments.install == 'yes' else 'built'
    print('>>> Cross-compiler for {} is now {}.'.format(target_platform, MSG))

使用的时候

sudo ./toolchain.py --arch loongarch64 --install yes --cores 8

   这样在我的debian 11下面是可以交叉编译得到loongarch64-linux-gnu-gcc的,而且执行的话也能正常打印gcc版本,但是就是用来编译程序的时候提示Error: unrecognized option -#lp64d错误,而且网上还查不到是因为什么出错。

   另外想手动一步步编译的,注意下载最新版的config.guess和config.sub,这个是用于告诉编译器识别什么事loongarch64架构的,下载地址:

https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess

https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

peihexian

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值