解读NDS程序的编译参数



niubo_
2009-05-16 10:18:57

[i=s] 本帖最后由 niubo_ 于 2009-5-16 23:51 编辑 [/i]

和雷叔讨论overlay的实现,一直没有进展,反倒找到编译器的手册,把编译参数研究了一下。
nds程序的编译过程相对PC程序麻烦些,不但中间文件比较多,还因为涉及到两个CPU,又增添了一些步骤。
首先把源码编译成目标文件.o,然后链接得到一个后缀.elf的文件,这玩意儿个头比较大,据说含有调试信息,然后用objcopy把没用的东西去掉,变成一个cpu可以执行的二进制文件.arm9或者.arm7。最后用ndstool把他们连同图标,标题,包含的外部文件打包成一个.nds文件,这样就可以放到烧录卡或在模拟器上运行了。
模板里提供的Makefile把很多命令都隐藏起来了,我们可以把命令前面的@去掉,就可以看到完整的编译输出了。
参数很长很长,我把它们断开,一个一个解读其作用。

[quote]编译:

实际这个编译过程包含了预处理和编译两步,预处理产生的文件是以.i做后缀的。
若不删除中间文件,会看到即使一个简单的Hello World经预处理后的篇幅也是相当壮观的。
arm-eabi-gcc

-MMD
控制在编译的过程中生成依赖文件,以写入到.d文件中
-MP
给除主文件外的所有源文件设置一个空依赖,可以解决某些因移除文件而又没更新Makefile产生的make错误
-MF
当用了上面的-MMD后,指定依赖文件输出到后面路径所示的位置
/m/make_test/build/main.d

-save-temps
保留编译过程中产生的中间文件
-g
生成调试信息
-Wall
开启所有waring
-O2
设置优化级别为2
-fomit-frame-pointer
优化,尽可能不产生栈框架(Frame)
-ffast-math
优化,加快运算,不过不保证正确性
-mthumb
产生Thumb编码
-mthumb-interwork
产生支持ARM和Thumb指令集一起使用的编码
-march=armv5te
指定目标码是何种ARM体系
-mtune=arm946e-s
调整产生的编码适合特定的ARM型号
-I/m/make_test/include
-I/d/devkitPro/libnds/include
以-I开头后跟路径的参数,指定#include 的搜索路径
-DARM9
预先定义ARM9这个宏
-c
控制编译器只编译到生成目标文件.o,不进行链接
/m/make_test/source/main.c
指定输入文件的路径
-o main.o
指定输出文件为后面的文件名

链接:

可以看到,链接这一步也是用gcc来完成的
arm-eabi-gcc

-specs=ds_arm9.specs
指定一个储存器配置表,或者说一个Linker script指令文件
-g
-mthumb
-mthumb-interwork
-march=armv5te
-mtune=arm946e-s
和编译时的参数相同
-Wl,-Map,make_test.map
给链接器传递参数,生成链接映射表文件
main.o
sh.o
输入文件
-L/d/devkitPro/libnds/lib
-L开头的参数指定后面外部库文件的路径
-lnds9
-lXXX,需要链接的库。库文件名应该是libnds9.a
-o
指定输出文件为后面的文件名
/m/make_test/make_test.elf

objcopy 减肥:

arm-eabi-objcopy -O binary /m/make_test/make_test.elf /m/make_test/make_test.arm9
这个比较简单,-O binary 以binary的格式把elf文件输出到arm9文件。

ndstools 打包:

ndstool -c /m/make_test/make_test.nds
-9 /m/make_test/make_test.arm9
-b /d/devkitPro/libnds/icon.bmp "make_test;[url]www.devkitpro.org[/url];[url]www.drunkencoders.com[/url]"

-9 + 路径 包含进一个arm9二进制文件。
另外也可以用-7 + 路径包含进一个arm7二进制文件,如果不指定的话ndstool会自动到libnds下寻找Default包含进来。
-b + 后面那一串 分别把图标,标题,副标题1和副标题2包含进来。
另外还有 -d + 路径 可以把一个文件夹也打包进来。使用EFSlib的时候会要用到这个参数。[/quote]

可以看出很多参数都是优化或者修饰性的,或者在编译的时候输出些副产物。
当然不同的Makefile模板提供的编译参数也不完全相同,不过读懂这些这样的话其实可以根据自己的需要定制一下了,比如加上不删除中间文件的参数,连生成的汇编码都保留下来了,嗯,以后学汇编的话倒是可以对照C源码来看看。