macOS下交叉编译AArch64程序时链接阶段失败求助
交叉编译链接失败:ld无法识别目标文件类型
问题背景
在macOS上使用Clang搭配arm-linux-gnueabihf-binutils和LLVM工具交叉编译Hello World程序时,编译阶段可正常完成,但链接阶段报错,提示ld无法识别'/Users/rich/workspace/rpi/cross-test/build/main.o'的文件类型,尝试添加链接器参数后仍无效果。
链接失败输出
gcc build/main.o -o crosstest -L../sysroot/lib -L../sysroot/usr/local/lib -fuse-ld=ld -lc -lm ld: unknown file type in '/Users/rich/workspace/rpi/cross-test/build/main.o' clang: error: linker command failed with exit code 1 (use -v to see invocation) gmake: *** [Makefile:88: crosstest] Error 1
Makefile内容
####################################### # target: proto ####################################### TARGET = crosstest ####################################### # binaries ####################################### GCC_PATH = gcc PREFIX = CC = $(PREFIX)gcc CXX = $(PREFIX)g++ AS = $(PREFIX)gcc -x assembler-with-cpp CP = $(PREFIX)objcopy SZ = $(PREFIX)size HEX = $(CP) -O ihex BIN = $(CP) -O binary -S ####################################### # paths ####################################### BUILD_DIR = build SYSROOT = ../sysroot ####################################### # options ####################################### OPT = C_DEFS = CFLAGS = ifeq ($(DEBUG), 1) OPT += -Og -g3 C_DEFS += -DDEBUG $(info building for debug) endif ifeq ($(VERBOSE), 1) OPT += -v $(info verbose compile) endif ####################################### # compiler flags ####################################### CFLAGS += $(OPT) $(C_DEFS) -Wall -Wextra -Wpedantic -std=c11 --sysroot=$(SYSROOT) -v --target=aarch64-unknown-linux-gnueabihf -pipe -mlittle-endian -munaligned-access -march=armv8-a LDFLAGS = -L$(SYSROOT)/lib -L$(SYSROOT)/usr/local/lib -fuse-ld=ld LDLIBS = -lc -lm ###################################### # source ###################################### C_SOURCES = \ $(wildcard *.c) \ C_INCLUDES = \ -I. \ # -I../sysroot/usr/include \ # -I../sysroot/usr/local/include \ C_DEFS += \ # Create the build directory if it doesn't exist $(BUILD_DIR): mkdir -p $(BUILD_DIR) # Create the necessary subdirectories in the build directory $(BUILD_DIR)/%.o: %.c mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(C_INCLUDES) -c $< -o $@ # Compile the C source files into object files in the build directory $(BUILD_DIR)/%.o: %.c | $(BUILD_DIR) $(CC) -c $(CFLAGS) $(C_INCLUDES) -c $< -o $@ # List of object files C_OBJECTS = $(C_SOURCES:%.c=$(BUILD_DIR)/%.o) CPP_OBJECTS = $(CPP_SOURCES:%.cpp=$(BUILD_DIR)/%.o) OBJECTS = $(C_OBJECTS) ###################################### # build ###################################### all: $(TARGET) $(TARGET): $(OBJECTS) $(CC) $(OBJECTS) -o $@ $(LDFLAGS) $(LDLIBS) clean: rm -rf $(TARGET) $(BUILD_DIR)/*.o
编译器verbose输出
mkdir -p build/ gcc -c -Wall -Wextra -Wpedantic -std=c11 --sysroot=../sysroot -v --target=aarch64-unknown-linux-gnueabihf -pipe -mlittle-endian -munaligned-access -march=armv8-a -I. -c main.c -o build/main.o Apple clang version 16.0.0 (clang-1600.0.26.6) Target: aarch64-unknown-linux-gnueabihf Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple aarch64-unknown-linux-gnueabihf -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=non-leaf -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu generic -target-feature +neon -target-feature +v8a -target-abi aapcs -debugger-tuning=gdb -target-linker-version 1115.7.3 -v -fcoverage-compilation-dir=/Users/rich/workspace/rpi/cross-test -resource-dir /Library/Developer/CommandLineTools/usr/lib/clang/16 -I . -isysroot ../sysroot -internal-isystem /Library/Developer/CommandLineTools/usr/lib/clang/16/include -internal-isystem ../sysroot/usr/local/include -internal-externc-isystem ../sysroot/usr/include/aarch64-linux-gnu -internal-externc-isystem ../sysroot/include -internal-externc-isystem ../sysroot/usr/include -Wall -Wextra -Wpedantic -std=c11 -fdebug-compilation-dir=/Users/rich/workspace/rpi/cross-test -ferror-limit 19 -mdarwin-stkchk-strong-link -fno-signed-char -fgnuc-version=4.2.1 -fcolor-diagnostics -clang-vendor-feature=+disableAtImportPrivateFrameworkInImplementationError -target-feature -fmv -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o build/main.o -x c main.c clang -cc1 version 16.0.0 (clang-1600.0.26.6) default target arm64-apple-darwin24.2.0 ignoring nonexistent directory "../sysroot/include" #include "..." search starts here: #include <...> search starts here: . /Library/Developer/CommandLineTools/usr/lib/clang/16/include ../sysroot/usr/local/include ../sysroot/usr/include/aarch64-linux-gnu ../sysroot/usr/include End of search list. main.c:4:9: warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes] 4 | int main() { | ^ | void 1 warning generated. gcc build/main.o -o crosstest -L../sysroot/lib -L../sysroot/usr/local/lib -fuse-ld=ld -lc -lm ld: unknown file type in '/Users/rich/workspace/rpi/cross-test/build/main.o' clang: error: linker command failed with exit code 1 (use -v to see invocation) gmake: *** [Makefile:88: crosstest] Error 1
解决方案
核心问题
当前使用的是macOS系统自带的ld(Mach-O格式链接器),它无法识别AArch64 Linux平台的ELF格式目标文件,导致链接失败。
修复步骤
- 指定交叉编译工具链前缀:在Makefile中设置
PREFIX为你的交叉编译工具链前缀(例如aarch64-linux-gnu-),确保调用对应平台的链接器而非系统自带工具:PREFIX = aarch64-linux-gnu- CC = $(PREFIX)gcc CXX = $(PREFIX)g++ AS = $(PREFIX)gcc -x assembler-with-cpp CP = $(PREFIX)objcopy SZ = $(PREFIX)size - 移除强制指定系统
ld的参数:交叉工具链会自动匹配对应平台的链接器,无需手动指定fuse-ld=ld,修改LDFLAGS:LDFLAGS = -L$(SYSROOT)/lib -L$(SYSROOT)/usr/local/lib - 验证工具链可用性:确保
aarch64-linux-gnu-系列工具已安装并添加到环境变量PATH中,可通过aarch64-linux-gnu-ld --version确认工具正常。
验证修复
重新执行make命令,此时会使用交叉链接器处理ELF目标文件,可正常生成AArch64 Linux平台的可执行文件。
内容的提问来源于stack exchange,提问作者Richard Klosinski
相关产品推荐
相关产品推荐

