【现象】
在uboot中,将makefile写好:
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
COBJS := as3536.o asdebug.o ccu.o ssp.o ssp_nor.o enc28j60.o i2c_driver_polling.o as353x_nand.o shuffle.o mpmc_driver.o
SOBJS := lowlevel_init.o
#BCH_COBJS := bch/bch_gf.obj bch/bch_lut.obj bch/bch_enc.obj bch/bch_dec.obj
BCH_COBJS := bch/bch_gf.o bch/bch_lut.o bch/bch_enc.o bch/bch_dec.o
#BCH_COBJS := bch/libbch.a
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
BCH_OBJS :=$(addprefix $(obj),$(BCH_COBJS))
$(LIB): $(obj).depend $(OBJS) $(SOBJS) $(BCH_COBJS)
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS) $(BCH_COBJS)
然后去make Uboot,是可以正常编译通过的。
此处,希望将上面由源码生成的四个bch的.o文件,打包成单独的一个.o文件,比较叫做bch.obj(叫做bch.o的话,make clean就会把他clean掉了),
然后手动去
arm-linux-uclibc-ar crv bch/libbch.a bch/bch_gf.o bch/bch_lut.o bch/bch_enc.o bch/bch_dec.o
是可以正常生成对应的bch/libbch.a的。然后将makefile改成:
#BCH_COBJS := bch/bch_gf.obj bch/bch_lut.obj bch/bch_enc.obj bch/bch_dec.obj
#BCH_COBJS := bch/bch_gf.o bch/bch_lut.o bch/bch_enc.o bch/bch_dec.o
BCH_COBJS := bch/libbch.a
再make 的话,就会出错:
arm-linux-uclibc-objdump: libbch.a : File format not recognized
即使改名成bch.obj也没用:
arm-linux-uclibc-objdump: bch.obj : File format not recognized
【解决过程】
1.尝试到网上找关于如何将多个.o打包成一个.o的资料,未找到可以用的。
只找到一点有用的相关知识:
http://www.movingmesh.org/forum/index.php?goto=74&t=msg#msg_74
“编译:把高级语言书写的代码转换为机器可识 别的机器指令。编译高级语言后生成的指令虽 然可被机器识别,但是还不能被执行。编译时 ,编译器检查高级语言的语法、函数与变量的 声明是否正确。只有所有的语法正确、相关变 量定义正确编译器就可以编译出中间目标文件 。通常,一个高级语言的源文件都可对应一个 目标文件。目标文件在 Linux 中默认后缀为 “.o”(如 “foo.c” 的目标文件为 “foo.o”)。
为了和规则的目标文件相区别。本文将编译高 级语言后生成的目标文件成为 .o 文件。
链接:将多 .o 文件,或者 .o 文件和库文件链接成为可被操作系统执行的可 执行程序( Linux 环境下,可执行文件的格式为 “ELF” 格式)。链接器不检查函数所在的源文件,只 检查所有 .o 文件中的定义的符号。将 .o 文件中使用的函数和其它 .o 或者库文件中的相关符号进行合并,对所有文 件中的符号进行重新安排(重定位),并链接 系统相关文件(程序启动文件等)最终生成可 执行程序。链接过程使用 GNU 的 “ld” 工具。
静态库:又称为文档文件(Archive File)。它是多个 .o 文件的集合。Linux 中静态库文件的后缀为 “.a”。静态库中的各个成员(.o 文件)没有特殊的存在格式,仅仅是一个 .o 文件的集合。使用 “ar” 工具维护和管理静态库。
共享库:也是多个 .o 文件的集合,但是这些 .o 文件时有编译器按照一种特殊的方式生成(Lin ux 中,共享库文件格式通常为 “ELF” 格式。共享库已经具备了可执行条件)。模块 中各个成员的地址(变量引用和函数调用)都 是相对地址。使用此共享库的程序在运行时, 共享库被动态加载到内存并和主程序在内存中 进行连接。多个可执行程序可共享库文件的代 码段(多个程序可以共享的使用库中的某一个 模块,共享代码,不共享数据)。另外共享库 的成员对象可被执行(由 libdl.so 提供支持)。
参考 info ld 了解更加详细的关于 ld 的说明和用法。 ”
2.尝试了objcopy,以为可以实现此功能,但是实际好像也不行。
3.尝试一次编译多个文件,还无法编译:
arm-linux-uclibc-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DTEXT_BASE=0x00000000 -I/home/crifan/uboot_as3536/u-boot-2009.03/include -fno-builtin -ffreestanding -nostdinc -isystem /home/eric/buildroot/buildroot-2009.08/build_arm/staging_dir/usr/bin/../lib/gcc/arm-linux-uclibc/4.2.4/include -pipe -DCONFIG_ARM -D__ARM__ -march=armv5te -mabi=apcs-gnu -mno-thumb-interwork -Wall -Wstrict-prototypes -fno-stack-protector -c -o bch/bch_4_8_c.obj bch/bch_dec.c bch/bch_enc.o bch/bch_gf.c bch/bch_lut.c
arm-linux-uclibc-gcc: cannot specify -o with -c or -S with multiple files
$gcc –help
Usage: gcc [options] file…
。。。
-combine Pass multiple source files to compiler at once
。。。
-B <directory> Add <directory> to the compiler’s search paths
-b <machine> Run gcc for target <machine>, if installed
-V <version> Run gcc version number <version>, if installed
-v Display the programs invoked by the compiler
-### Like -v but options quoted and commands not executed
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o <file> Place the output into <file>
。。。
For bug reporting instructions, please see:
<URL:http://bugs.opensuse.org>.
加了-combine也还是不行:
arm-linux-uclibc-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DTEXT_BASE=0x00000000 -I/home/crifan/uboot_as3536/u-boot-2009.03/include -fno-builtin -ffreestanding -nostdinc -isystem /home/eric/buildroot/buildroot-2009.08/build_arm/staging_dir/usr/bin/../lib/gcc/arm-linux-uclibc/4.2.4/include -pipe -DCONFIG_ARM -D__ARM__ -march=armv5te -mabi=apcs-gnu -mno-thumb-interwork -Wall -Wstrict-prototypes -fno-stack-protector -c -o bch/bch_4_8_c.obj bch/bch_dec.c bch/bch_enc.o bch/bch_gf.c bch/bch_lut.c -combine
arm-linux-uclibc-gcc: bch/bch_enc.o: linker input file unused because linking not done
仔细一看才发现,原来是自己不小心写错了,将bch_enc.c写成bch_enc.o了,囧。。。
最后终于编译成功了:
arm-linux-uclibc-gcc -g -Os -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DTEXT_BASE=0x00000000 -I/home/crifan/uboot_as3536/u-boot-2009.03/include -fno-builtin -ffreestanding -nostdinc -isystem /home/eric/buildroot/buildroot-2009.08/build_arm/staging_dir/usr/bin/../lib/gcc/arm-linux-uclibc/4.2.4/include -pipe -DCONFIG_ARM -D__ARM__ -march=armv5te -mabi=apcs-gnu -mno-thumb-interwork -Wall -Wstrict-prototypes -fno-stack-protector -o bch/bch_4_8_c.obj -c bch/bch_dec.c bch/bch_enc.c bch/bch_gf.c bch/bch_lut.c -combine
查看一下生成的目标文件的信息:
[crifan@linux-41lh as3536]$ls bch/bch_4_8_c.obj
bch/bch_4_8_c.obj
[crifan@linux-41lh as3536]$file bch/bch_4_8_c.obj
bch/bch_4_8_c.obj: ELF 32-bit LSB relocatable, ARM, version 1, not stripped
[crifan@linux-41lh as3536]$arm-linux-uclibc-objdump -f bch/bch_4_8_c.obj
bch/bch_4_8_c.obj: file format elf32-littlearm
architecture: arm, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
【总结】
在有源码的前提下,如果之前是每个文件单独编译出来生成对应的多个.o文件的,
而想要实现将这些.o文件打包成单个的.o文件,好像是不可以的,
但是可以这样实现:
通过重新一次性编译多个源文件,而生成单个.o文件。
具体用法一般为:
gcc -combine -o out_obj_file_name -c XX.c XXX.c XXXX.c XXXX.c
注:对于此处用gcc编译,还要加上-combine参数才可以支持同时编译多个文件
-combine Pass multiple source files to compiler at once
否则会提示:cannot specify -o with -c or -S with multiple files
最后感慨一句,连最基本的gcc编译多个文件生成单个.o文件的知识都忘了,真是越来越退步了。。。
转载请注明:在路上 » 【已解决】arm-linux-uclibc-objdump: libbch.a : File format not recognized