[英]linking succeeds with arm-none-eabi-g++ but not arm-none-eabi-gcc
我正在使用Launchpad Arm編譯器工具。 特別,
arm-none-eabi-g ++和arm-none-eabi-gcc來自:
(適用於ARM嵌入式處理器的GNU工具)5.2.1 20151202(發布)[ARM / embedded-5-branch revision 231848]
我有一個針對STM32F103處理器的簡單程序,除了證明我可以編寫硬件並從數學庫中調用函數之外沒有任何目的。 這就是全部:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "stm32f10x.h"
void hardwareTest(void){
// Turn on the clock for PortB
RCC->APB2ENR = RCC_APB2ENR_IOPBEN; // Turn on IO Port B
// Put PB0 into push pull 50 MHz mode
GPIOB->CRL = 0x03;
// Turn PB0 on
GPIOB->ODR = 1;
}
volatile int x; // force call to sqrt() later
int main(void) {
x = sqrt(100.0f);
x = sqrt(x);
hardwareTest();
return (x);
}
當我嘗試構建它時,我收到一個鏈接器錯誤,告訴我有一個未定義的sqrt引用。 構建是用arm-none-eabi-gcc完成的。 我偶然發現,如果使用arm-none-eabi-g ++完成構建,使用相同的命令行參數,則成功執行鏈接。
我寫了一個Makefile來演示差異:
PROJECT = minimal
SOURCES = src/startup_stm32f10x_hd.s \
src/system_stm32f10x.c \
src/main.c
OUTPUT = ./out
print-%:
@echo '$*=$($*)'
TOOLCHAIN = arm-none-eabi-
CXX = $(TOOLCHAIN)g++
CC = $(TOOLCHAIN)gcc
AR = $(TOOLCHAIN)ar
AS = $(TOOLCHAIN)gcc -c -x assembler-with-cpp
LD = $(TOOLCHAIN)gcc
OBJCOPY = $(TOOLCHAIN)objcopy
OBJDUMP = $(TOOLCHAIN)objdump
SIZE = $(TOOLCHAIN)size
RM = rm -f
CFLAGS = -O
CFLAGS += -nostartfiles
CXXFLAGS = -O
CXXFLAGS += -nostartfiles
ARCH = -mcpu=cortex-m3 -mthumb -DSTM32F10X_HD
LDFLAGS =
all: clean $(PROJECT).elf $(PROJECT).gcc $(PROJECT).bin
$(PROJECT).bin: $(PROJECT).elf
@echo ' ======== '
@echo ' Generating binaries'
$(OBJCOPY) -O binary $(OUTPUT)/$< $(OUTPUT)/$(PROJECT).bin
$(OBJCOPY) -O ihex $(OUTPUT)/$< $(OUTPUT)/$(PROJECT).hex
@echo ' ======== '
$(PROJECT).elf: $(SOURCES)
@echo ' ======== '
@echo ' Successful build uses g++'
@echo ' CXXFLAGS = $(CXXFLAGS)'
@echo ' LDFLAGS = $(LDFLAGS)'
@echo ' ARCH = $(ARCH)'
$(CXX) -o $(OUTPUT)/$@ $(ARCH) $(CXXFLAGS) $(LDFLAGS) -Wl,-Tld_script/stm32.ld,-lm $^
@echo ' ======== '
$(PROJECT).gcc: $(SOURCES)
@echo ' ======== '
@echo ' Broken build uses gcc'
@echo ' CFLAGS = $(CFLAGS)'
@echo ' LDFLAGS = $(LDFLAGS)'
@echo ' ARCH = $(ARCH)'
$(CC) -o $(OUTPUT)/$@ $(ARCH) $(CFLAGS) $(LDFLAGS) -Wl,-Tld_script/stm32.ld,-lm $^
@echo ' ======== '
$(PROJECT).gxx: $(SOURCES)
@echo ' ======== '
@echo ' build with g++'
$(CXX) -o $(OUTPUT)/$@ $(ARCH) $(CXXFLAGS) $(LDFLAGS) -Wl,-Tld_script/stm32.ld $^
@echo ' ======== '
# Program the binary to the board using the builtin serial bootloader
program:
stm32loader.py -p /dev/ttyUSB0 -ewv $(OUTPUT)/$(PROJECT).bin
# Remove the temporary files
clean:
@echo ' '
@echo ' Cleaning up: '
$(RM) $(OUTPUT)/* *.o *.elf *.bin *.hex *.gcc *.gxx *.g++
@echo ' ======== '
它給出了以下結果:
Cleaning up:
rm -f ./out/* *.o *.elf *.bin *.hex *.gcc *.gxx *.g++
========
========
Successful build uses g++
CXXFLAGS = -O -nostartfiles
LDFLAGS =
ARCH = -mcpu=cortex-m3 -mthumb -DSTM32F10X_HD
arm-none-eabi-g++ -o ./out/minimal.elf -mcpu=cortex-m3 -mthumb -DSTM32F10X_HD -O -nostartfiles -Wl,-Tld_script/stm32.ld,-lm src/startup_stm32f10x_hd.s src/system_stm32f10x.c src/main.c
========
========
Broken build uses gcc
CFLAGS = -O -nostartfiles
LDFLAGS =
ARCH = -mcpu=cortex-m3 -mthumb -DSTM32F10X_HD
arm-none-eabi-gcc -o ./out/minimal.gcc -mcpu=cortex-m3 -mthumb -DSTM32F10X_HD -O -nostartfiles -Wl,-Tld_script/stm32.ld,-lm src/startup_stm32f10x_hd.s src/system_stm32f10x.c src/main.c
/var/folders/t4/dv7b46055cjgknp4nndn1_zr0000gn/T//ccbl4swG.o: In function `main':
main.c:(.text+0x28): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
make: *** [minimal.gcc] Error 1
========
Generating binaries
arm-none-eabi-objcopy -O binary ./out/minimal.elf ./out/minimal.bin
arm-none-eabi-objcopy -O ihex ./out/minimal.elf ./out/minimal.hex
make: Target `all' not remade because of errors.
那么有誰能告訴我為什么兩個編譯器的行為不同? 我忽略了什么簡單的事情? 如果我想使用arm-none-eabi-gcc,我應該如何確保與libm和其他人的正確鏈接?
我看過Freddie Chopin的文件,但是它們太復雜了我無法解開。
C ++要求數學函數是基本運行時的一部分,而C允許它們在庫中。 GCC實現通過在C ++構建中自動鏈接libm
來實現這一點。
鏈接階段還有許多其他差異; 如果使用C鏈接器,C ++鏈接將始終失敗。
對於C鏈接,請使用C鏈接器並指定-lm
以使libm
可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.