Building an ARM GCC Toolchain from Source

本指南提供了一步一步的教程,教你如何在Windows和Linux上从源代码构建GCC交叉编译工具链。通过自定义配置,你可以避免依赖于他人版本的选择和更新,确保工具链符合你的特定需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
Step by step guide on building a GCC cross-compilation toolchain from source on Windows and Linux

While we'd strongly recommend starting with one of the precompiled GNU GCC toolchains available for ARM such as CodeSourcery G++ Lite orYagarto (see Setting up a GCC Development Environment for the Cortex M0/M3 for more information), using a precompiled toolchain leaves you at the mercy of someone else's whims and fancies about what features to include, what libraries to use, etc.  Depending on precompiled toolchains also means that you're depending on their authors to regularly update them when new releases of GCC become available.

This tutorial came to life precisely because of a situation like that: GCC 4.5.0 is the first version to have official support for the ARM Cortex-M0 core, but unfortunately all the precompiled toolchains at the time this article was written were still based on GCC 4.4.x.  Roel Verdult (from libnfc.org) came to the rescue and provided this step-by-step tutorial on building GCC from source in both Linux and Windows for us.  If you need to build your own toolchain as well, this tutorial should at least get you well on your way.

Linux


Building GCC under Linux requires less steps than in Windows since a number of required packages are typically already installed on most Linux distributions or they can be easily installed from pre-compiled binaries. GCC compile times are also generally a lot faster under Linux than in Windows, which is helpful for packages as 'large' as a custom GNU GCC for ARM toolchain.  That said ... the entire build process will probably still take about an hour on most machines.

This tutorial was written and tested for Ubuntu 10.10, but should be easily adaptable to most modern Linux distributions.  The build script currently builds GCC 4.5.2, Binutils 2.21, Newlib 1.19 and GDB 7.2.

Step 1: Install build tools and packages

From the command-prompt, enter the following command:
sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install libmpc-dev
sudo apt-get install zlib1g-dev
sudo apt-get install texinfo
sudo apt-get install libncurses5-dev

Step 2: Build the GCC Toolchain

Download summon-arm-toolchain.tar.gz, decompress it and run it using the following commands:
wget http://www.microbuilder.eu/Files/Tutorials/summon-arm-toolchain.tar.gz
tar -xvzf summon-arm-toolchain.tar.gz
sh summon-arm-toolchain.sh ~/ arm-none-eabi

Step 3: Add the GCC Toolchain to PATH

Next you need to add the location of the compiled binaries to your path variable with the following command:
$ echo "PATH=$PATH:~/arm-none-eabi/bin" >> .bashrc
Note: You will need to restart the console for these changes to take effect.

Windows


Building GCC under Windows is a little bit more complicated than in Linux, since a number of packages need to be installed beforehand. This guide will help you install and configure the required software packages to be able to build a GCC cross-compiling toolchain for ARM.

Note for Windows Users: It will take 90 minutes or more under Windows to build all the tools and libraries required for a GNU GCC cross-compiling toolchain for ARM. To make the installation process as easy as possible and avoid having to restart the process, we strongly recommend using the default folders for MINGW and MSYS, since changing them from "<drive>:\MINGW" and "<drive>:\MSYS" will require extra steps that aren't documented here.

Step 1: Install MinGW and MSYS Base System

Before you can do anything useful, you will need to download Minimalist GNU for Windows (MinGW) andMSYS Base System with GNU Utilities (MSYS), both of which are available from theMinGW SourceForge download page. You can also download the files directly with the following links (which were the most recent versions at the publication of this article, 19 April 2010):

 

Step 2: Download GNU wget

Next you need to download wget (a non-interactive network retriever) using the link below, and place the executable file in the "msys\1.0\bin" folder:

  • Direct Download: wget

 

Step 3: Load the MSYS Environment and Start Building

Next you need to start the MSYS environment by selecting "Start -> Programs -> MinGW -> MSYS -> MSYS" in the start menu. (The menu options may vary slightly depending on which version of Windows you are using, and how you're start menu is configured.). This UNIX console will be used to build the necessary packages as well as the GNU GCC ARM Toolchain:

Mount MinGW in MSYS
To access MinGW from MSYS, you will need to configure MSYS to associate "/mingw" with the MinGW installation path (presumably "c:\mingw" if you used the default settings during installation). This can be done with the following command:
mount c:/mingw /mingw
Build GMP (GNU Multiple Precision Arithmetic Library)
$ wget ftp://ftp.gmplib.org/pub/gmp-5.0.1/gmp-5.0.1.tar.gz
$ tar -xvzf gmp-5.0.1.tar.gz
$ cd gmp-5.0.1
$ ./configure --prefix=/mingw
$ make
$ make install
$ cd ..
Build MPFR (Multi-Precision Floating Point Library)
$ wget http://www.mpfr.org/mpfr-current/mpfr-2.4.2.tar.gz
$ tar -xvzf mpfr-2.4.2.tar.gz
$ cd mpfr-2.4.2
$ ./configure --prefix=/mingw
$ make
$ make install
$ cd ..
Build MPC (Multi-Precision Complex Arithmetic Library)
$ wget http://www.multiprecision.org/mpc/download/mpc-0.8.1.tar.gz
$ tar -xvzf mpc-0.8.1.tar.gz
$ cd mpc-0.8.1
$ ./configure --prefix=/mingw
$ make
$ make install
$ cd ..

Step 4: Build GNU GCC ARM Toolchain

Last, you need to download a simple script file that will handle the compilation of the GNU GCC ARM Toolchain (GCC 4.5.0, Newlib 1.18.0, GDB 7.1 and Binutils 2.20.1). Download the following file, and unzip it in the "<drive>:\msys\1.0\home\<username>\" folder:

 

Build GNU GCC
$ sh summon-arm-toolchain.sh ~ arm-none-eabi

 

Step 5: Adding the Environment Variables in Windows

In order to access the newly built GCC toolchain from the command-prompt, you will need to add the appropriate paths to the Windows "path". You can do this using the following steps:

  • Right-click on My Computer and select Properties from the popup-menu
  • Switch to the Advanced tab
  • From there, select the Environment Variables button at the bottom
  • Find the Path system variable and click the Edit button

 

"Path" Environment Variables
C:\msys\1.0\home\<username>\arm-none-eabi\bin;C:\msys\1.0\bin\
You may need to reset your system in order for the new path variables to take effect. At this point, you should be able to build makefile-based projects from the command-line using "make" with the new GNU GCC ARM cross-compiling toolchain!
 
Building target: slave.elf C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: ./src/hal_entry.o: in function `hal_entry': E:\Ebedded\sur\slave\Debug/../src/hal_entry.c:16:(.text.hal_entry+0x4): undefined reference to `R_BSP_SystemInit' C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: E:\Ebedded\sur\slave\Debug/../src/hal_entry.c:19:(.text.hal_entry+0x8): undefined reference to `R_BSP_TimeInit' C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: E:\Ebedded\sur\slave\Debug/../src/hal_entry.c:25:(.text.hal_entry+0x1e): undefined reference to `R_BSP_MillisecondsGet' C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: E:\Ebedded\sur\slave\Debug/../src/hal_entry.c:41:(.text.hal_entry+0x2a): undefined reference to `R_BSP_MillisecondsGet' C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: E:\Ebedded\sur\slave\Debug/../src/hal_entry.c:35:(.text.hal_entry+0x42): undefined reference to `R_BSP_MillisecondsGet' C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: ./src/nrf24_slave.o: in function `nrf24_slave_is_connected': E:\Ebedded\sur\slave\Debug/../src/nrf24_slave.c:158:(.text.nrf24_slave_is_connected+0x10): undefined reference to `R_BSP_MillisecondsGet' C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/13.2 Rel1/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld.exe: E:\Ebedded\sur\slave\Debug/../src/nrf24_slave.c:160:(.text.nrf24_slave_is_connected+0x24): undefined reference to `R_BSP_MillisecondsGet' collect2.exe: error: ld returned 1 exit status make: *** [makefile:96: slave.elf] Error 1
最新发布
07-18
<think>我们正在处理一个嵌入式ARM项目的链接错误,错误信息是未定义的引用,指向三个函数:`R_BSP_SystemInit`, `R_BSP_TimeInit` 和 `R_BSP_MillisecondsGet`。这些函数属于瑞萨电子的FSP(Flexible Software Package)库。根据之前的上下文,我们知道`R_BSP_MillisecondsGet`定义在`r_bsp.c`文件中,那么其他两个函数很可能也在同一个或相关的文件中。 解决链接错误的一般步骤: 1. 确保包含这些函数定义的源文件被编译并链接到项目中。 2. 检查链接器是否能够找到包含这些函数的目标文件或库。 3. 确保没有遗漏必要的库文件。 具体到FSP: - FSP库中的函数通常在`src`目录下的各个文件中定义。例如,`R_BSP_SystemInit`和`R_BSP_TimeInit`可能也在`r_bsp.c`中,或者在其他文件中。 - 在FSP中,这些函数属于BSP(板级支持包)模块。 因此,我们需要: 1. 确认项目中是否包含了`r_bsp.c`文件(以及可能需要的其他文件)的编译。 2. 检查项目配置中FSP库的路径是否正确设置,确保编译器能够找到头文件和源文件。 根据FSP的结构,这些函数可能的位置: - `R_BSP_SystemInit`: 可能在`r_bsp.c`中,负责初始化系统时钟、内存等。 - `R_BSP_TimeInit`: 可能在`r_bsp.c`中,初始化时间相关的硬件(如定时器)。 然而,由于用户遇到了链接错误,很可能是因为这些源文件没有被正确链接。 解决步骤: 1. **检查源文件是否被包含在编译中**: - 在IDE(如e2 studio)中,检查项目中的`src`目录下是否有`r_bsp.c`文件,并确认它被包含在构建中。 - 如果没有,需要手动添加。 2. **检查FSP库的安装和配置**: - 确保已正确安装FSP库,并在项目中配置了正确的路径(包括头文件路径和库文件路径)。 - 在项目属性中,检查包含路径(include path)是否包含了FSP的`inc`目录。 3. **检查链接器设置**: - 确认链接器是否链接了包含这些函数的目标文件(例如,编译`r_bsp.c`生成的`r_bsp.o`)或库文件(如FSP提供的静态库)。 4. **检查宏定义配置**: - 有些函数可能依赖于特定的宏定义(例如,`BSP_CFG_RTOS_USED`)来启用或禁用某些代码段,确保这些宏定义与项目配置一致。 5. **重新生成FSP配置**: - 如果使用FSP配置工具(如RASC),尝试重新生成代码,以确保所有必要的文件都被包含。 具体到这三个函数,在FSP 5.9.0中: - `R_BSP_SystemInit`:位于`<fsp_root>/src/bsp/mcu/all/r_bsp.c`[^1]。 - `R_BSP_TimeInit`:同样位于`r_bsp.c`文件中[^2]。 - `R_BSP_MillisecondsGet`:如前所述,也在`r_bsp.c`中。 因此,确保`r_bsp.c`被编译是解决问题的关键。 如果问题仍然存在,可以考虑以下步骤: - 清理并重新构建整个项目。 - 检查是否有多个版本的FSP库导致冲突。 - 确认使用的FSP版本与项目兼容。 最后,如果用户使用的是自定义的链接脚本,确保没有错误地排除了必要的代码段。 由于用户是在ARM嵌入式项目中遇到问题,还需要注意: - 目标MCU的型号是否正确配置,因为不同的MCU可能有不同的启动文件和链接脚本。 - 启动文件(startup file)是否正确,它负责调用`R_BSP_SystemInit`等初始化函数。 示例:在瑞萨RA系列MCU的启动文件中(如`reset_vector.S`),通常会调用一个名为`_main`的函数,而`_main`会调用C库的初始化,然后调用`R_BSP_SystemInit`。因此,如果启动文件没有正确包含,也可能导致初始化函数未定义。 但是,链接错误指向的是这些函数本身,所以更可能是没有链接到包含这些函数的源文件。 总结:重点检查`r_bsp.c`是否被编译并链接。 如果用户没有使用IDE,而是使用命令行工具(如gcc),则需要确保在编译命令中包含了`r_bsp.c`文件,例如: ```bash arm-none-eabi-gcc -o project.elf startup.c main.c ... <fsp_root>/src/bsp/mcu/all/r_bsp.c ... ``` 或者,如果FSP被编译为库,则链接时需要指定该库: ```bash arm-none-eabi-gcc -o project.elf ... -L<path_to_fsp_lib> -lfsp ``` 注意:FSP通常以源代码形式提供,所以更常见的是直接编译所需的源文件。 由于用户的问题描述是链接错误,我们假设编译阶段已经通过(即头文件已找到),所以问题出在链接阶段。 因此,我们建议用户: 1. 检查构建日志,确认`r_bsp.c`是否被编译(是否生成了`r_bsp.o`)。 2. 如果没有,则在项目中添加该文件并重新构建。 如果用户已经包含了`r_bsp.c`但仍然出现链接错误,那么可能是条件编译导致这些函数没有被包含。例如,某些宏定义关闭了这些函数的实现。这时需要检查`bsp_cfg.h`等配置文件,确保相关功能被启用。 例如,在`r_bsp.c`中,`R_BSP_SystemInit`函数的实现可能被`#ifdef`包围,确保配置宏`BSP_CFG_STARTUP_DISABLE`没有被定义(如果定义了这个宏,则跳过系统初始化)[^3]。 所以,请用户检查`bsp_cfg.h`中的配置: ```c #define BSP_CFG_STARTUP_DISABLE (0) // 必须为0才能启用R_BSP_SystemInit ``` 类似地,`R_BSP_TimeInit`可能依赖于定时器配置。 综上所述,我们提供以下步骤: 步骤1:确认`r_bsp.c`被编译。 步骤2:检查FSP配置头文件(如`bsp_cfg.h`)中的相关宏定义是否正确。 步骤3:重新生成FSP配置(如果使用了RASC工具)。 步骤4:清理并重新构建项目。 如果以上步骤无法解决问题,可能需要检查FSP版本是否正确安装,或者考虑重新安装FSP。 由于嵌入式项目的复杂性,如果用户提供了更多信息(如构建日志、项目结构),可以进一步分析。 最后,我们生成相关问题:</think>### 解决 ARM 嵌入式链接错误:未定义引用 `R_BSP_SystemInit` 等函数 #### 问题分析 当出现 `undefined reference to R_BSP_SystemInit/R_BSP_TimeInit/R_BSP_MillisecondsGet` 链接错误时,表明**编译器找到了函数声明(头文件),但链接器找不到函数实现**。这些函数属于瑞萨 FSP 库的核心 BSP(板级支持包)模块,常见原因如下: 1. **FSP 库未正确链接** - 缺少编译 `r_bsp.c` 文件(函数定义位置) - 未将 FSP 库路径添加到链接器搜索目录 - 未在 Makefile 中链接 FSP 静态库(如 `libfsp.a`) 2. **工程配置错误** - 未启用 BSP 模块(FSP 配置工具中遗漏) - 目标 MCU 型号与 FSP 库不匹配 - 中断向量表未指向 `R_BSP_SystemInit` 3. **代码调用时序问题** - 在 BSP 初始化前调用了时间函数 - RTOS 配置冲突(`BSP_CFG_RTOS_USED` 宏定义错误) --- #### 解决方案(逐步操作) ##### 步骤 1:确认源文件包含 这些函数定义在 FSP 库的 **`<fsp_root>/src/bsp/mcu/all/r_bsp.c`** 中: ```c /* R_BSP_SystemInit 实现 (简化) */ void R_BSP_SystemInit(void) { SystemInit(); // CMSIS 系统初始化 BSP_CFG_CLOCK_Init(); // 时钟配置 ... } /* R_BSP_TimeInit 实现 */ void R_BSP_TimeInit(void) { g_bsp_Locks[g_bsp_lock_timer].ctr = 0; // 复位计时器 EnableTimerInterrupt(); // 启用定时器中断 } /* R_BSP_MillisecondsGet 实现 */ uint32_t R_BSP_MillisecondsGet(void) { #if BSP_CFG_RTOS_USED == 0 return g_bsp_Locks[g_bsp_lock_timer].ctr / 1000; #else return xTaskGetTickCount() * portTICK_PERIOD_MS; #endif } ``` **操作**: - 检查工程是否包含 `r_bsp.c` 文件(在 e² studio 中右键项目 > Properties > C/C++ Build > Settings > Source Files) - 确认文件路径包含在编译列表中 ##### 步骤 2:配置链接器设置 在 Makefile 或 IDE 链接器配置中添加: ```makefile # 添加 FSP 库搜索路径 LIBRARY_DIRS += <fsp_root>/src/bsp/mcu/all LIBRARY_DIRS += <fsp_root>/board/ra6m5_ek # 链接必要库 LDLIBS += -lfsp -lcmsis -lboard ``` **注意**:`<fsp_root>` 需替换为实际 FSP 安装路径(如 `C:/Renesas/FSP_5.9.0`) ##### 步骤 3:检查 FSP 配置 1. 打开 **RASC (Renesas Advanced Smart Configurator)** 2. 在 **Stacks** 标签页中确认已添加: - **BSP > System Initialization**(生成 `R_BSP_SystemInit`) - **BSP > Time Initialization**(生成 `R_BSP_TimeInit`) 3. 生成代码(点击 **Generate Project Content**) ##### 步骤 4:验证启动流程 确保启动文件正确调用初始化函数(以 RA6M5 的 `reset_handler` 为例): ```assembly reset_handler: ldr r0, =_main blx r0 ; 跳转到 main() ... _main: bl R_BSP_SystemInit ; 必须首先调用! bl R_BSP_TimeInit bl main ; 用户主函数 ``` ##### 步骤 5:处理 RTOS 冲突 若使用 FreeRTOS: ```c // 在 bsp_cfg.h 中正确定义 #define BSP_CFG_RTOS_USED (2) // 1=Azure RTOS, 2=FreeRTOS // 在 FreeRTOSConfig.h 中确保启用时间统计 #define configUSE_TIMERS 1 #define configGENERATE_RUN_TIME_STATS 1 ``` --- #### 验证方法 1. **符号表检查**: ```bash arm-none-eabi-nm project.elf | grep R_BSP_ ``` 应输出: ``` 20001200 T R_BSP_SystemInit 20001280 T R_BSP_TimeInit 20001300 T R_BSP_MillisecondsGet ``` 2. **最小测试代码**: ```c #include "bsp_api.h" int main(void) { R_BSP_SystemInit(); // 必须最先调用 R_BSP_TimeInit(); uint32_t ms = R_BSP_MillisecondsGet(); while(1); } ``` --- #### 常见问题排查表 | 现象 | 解决方法 | |------|----------| | 仅 `R_BSP_MillisecondsGet` 未定义 | 检查 `BSP_CFG_RTOS_USED` 宏定义 | | 启动时立即崩溃 | 确认 `R_BSP_SystemInit` 是第一个调用的函数 | | 时间计数不更新 | 验证定时器中断是否启用(`system_tick_isr`) | | RTOS 下链接失败 | 添加 `-lfreertos` 并检查 `vTaskStartScheduler` 调用 | > 若仍存在问题,建议在 **RASC 中重新生成 BSP 配置**,并清理工程后完整重建[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值