完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 城东 于 2016-12-6 22:33 编辑
关于makefile的内容请看前文:https://bbs.elecfans.com/jishu_1098380_1_1.html 上面说到运行脚本gen_misc.sh最后执行的make语句如下: make BOOT=$boot APP=$app SPI_SPEED=$spi_speed SPI_MODE=$spi_mode SPI_SIZE_MAP=$spi_size_map 其中参数的具体值如下: BOOT=new APP=1 SPI_SPEED=40 SPI_MODE=QIO SPI_SIZE_MAP=3 这里来具体的分析makefile,掠过前面的注释不谈,看到几个变量的定义: TARGET = eagle #FLAVOR = release FLAVOR = debug #EXTRA_CCFLAGS += -u 这里声明了两个变量TARGET和FLAVOR,前者作为一个标志,后者则代表当前代码是调试和是发行,接下来是: ifndef PDIR # { GEN_IMAGES= eagle.app.v6.out GEN_BINS= eagle.app.v6.bin SPECIAL_MKTARGETS=$(APP_MKTARGETS) SUBDIRS= user sample_lib driver endif # } PDIR 这里PDIR是用来设置父目录的 在sample_lib的Makefile中有设置,到目前为止是没有定义的,所以下面的内容会被执行,所以这里定义了GEN_IMAGES、GEN_BINS、SPECIAL_MKTARGETS和SUBDIRS,其中SPECIAL_MKTARGETS这个变量APP_MKTARGETS是给用户指定编译目标的 没有用到可以不设 这里继续看下面的内容: LDDIR = $(SDK_PATH)/ld CCFLAGS += -Os TARGET_LDFLAGS = -nostdlib -Wl,-EL --longcalls --text-section-literals 这里也是定义三个变量LDDIR、CCFLAGS和TARGET_LDFLAGS注意在第一个变量中-Os是一个额外的编译标志,告诉GCC以优化尺寸(参考http://www.it1352.com/347430.html), /Os(代码大小优先)通过指示编译器优选大小而非速度来最小化 EXE 和 DLL 的大小。编译器可以将许多 C 和 C++ 构造缩小为功能类似的机器码序列。这些差异有时在大小和速度之间提供了折中。/Os 和 /Ot 选项允许在二者之间指定一个首选项: /Ot(代码速度优先)通过指示编译器优选速度而非大小来最大化 EXE 和 DLL 的速度。(这是默认设置。)编译器可以将许多 C 和 C++ 构造缩小为功能类似的机器码序列。这些差异有时在大小和速度之间提供了折衷。“最大化速度”(/O2/O1、/O2(最小化大小、最大化速度)) 选项隐含 /Ot 选项。/O2 选项组合若干个选项以产生速度非常快的代码。 如果使用 /Os 或 /Ot,还必须指定 /Og/Og(全局优化)以优化代码。(参考https://msdn.microsoft.com/zh-cn/library/f9534wye(VS.80).aspx) 接下来的内容是: ifeq ($(FLAVOR),debug) TARGET_LDFLAGS += -g -O2 endif ifeq ($(FLAVOR),release) TARGET_LDFLAGS += -g -O0 endif FLAVOR在本makefile的前面定义,选择了该代码是调试模式还是发行模式,最后他们的差别是-O2与-O0这两者的差异在上面一段代码的解释中有说明,接下来的内容是定义变量COMPONENTS_eagle.app.v6,这是一个编译器目标标示,标示要生成什么样的结果: COMPONENTS_eagle.app.v6 = user/libuser.a sample_lib/libsample.a driver/libdriver.a 注意这里只是定义了要生成的库的结果,比如user/libuser.a 是根据D:OracleshareSDKet_appuser的Makefile来生成库libuser.a,sample_lib/libsample.a根据D:OracleshareSDKet_appsample_lib的makefile来生成库libsample.a,但是注意这里只是定义了这些要生成的库的集合叫做COMPONENTS_eagle.app.v6,但是这里并没有真正进行编译工作。下面的内容是: (备注:关于连接器的声明请看:http://blog.csdn.net/earbao/article/details/53153853) LINKFLAGS_eagle.app.v6 = -L$(SDK_PATH)/lib #定义链接库的搜索路径是~/Share/SDK/lib/ -Wl,--gc-sections #减少静态库不必要的调用 -Wl,<选项> 将逗号分隔的 <选项> 传递给链接器 -nostdlib /#不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。 -T$(LD_FILE) #-T 文件, --script 文件 读取链接脚本 -Wl,--no-check-sections #Do not check section addresses for overlaps 不检查重叠地址 -u call_user_start #-U<宏> 取消定义宏 整体来说就是取消call_user_start这个宏定义 -Wl,-static #为了确保使用的是静态库,则使用此选项。 优先使用静态库 -Wl,--start-group #库列表开始, 这些库最后会存在~shareSDKlib下 -lminic -lgcc -lhal -lphy -lpp -ljson -lpwm -lnet80211 -lwpa -lcrypto -lmain -lfreertos -llwip -lespconn -lsmartconfig -letilink -lfac -lairkiss $(DEP_LIBS_eagle.app.v6) #在下面的内容有定义DEPENDS_eagle.app.v6 -Wl,--end-group #和上面的这个和 -Wl,--start-group一起使用 这里定义了LINKFLAGS_eagle.app.v6这个连接标识,这个应该是和上面的COMPONENTS_eagle.app.v6一起使用,下面是标识符的定义: -L-->指定连接库的搜索路径 -l-->指定连接时期望连接的库的名字 -W FILE -->假定文件 FILE 已经被修改。(有时候LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R":) -nostdlib-->暂时不知道什么意思 -T$(LD_FILE)-->暂时不知道是什么意思 静态库和动态库是两种共享程序代码的方式,它们的区别是:静态库在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存(http://baike.baidu.com/link?url= ... PyisAZxTV2jvV-bpoeW) -Wl,--gc-sections的解释:有时我们会遇到这种情况,可执行程序需要链接一些静态库,但是静态库中的函数并没有全部使用,只用了其中的几个,但是系统默认会自动把整个静态库全部链接到可执行程序中,造成可执行程序的大小大大增加,浪费了flash空间和内存空间。gcc为我们提供的解决这个问题的方法。(http://www.cnblogs.com/pengdonglin137/archive/2013/12/12/3471857.html) -nostdlib的作用:不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器。这个选项常用于编译内核、bootloader等程序,它们不需要启动文件、标准库文件。(http://blog.csdn.net/clb1609158506/article/details/41381561) -Wl,-static 说明:参考:http://blog.sina.com.cn/s/blog_602f877001011t8y.html 关于-Wl,--end-group:参考:http://blog.sina.com.cn/s/blog_a9303fd90101cy5y.html 这里有一些规律性的东西如lminic,这里包含minic库,但是这个库并不是标准库,这里应该是D:OracleshareSDKlib下面的libminic.a,其他的也依旧类推 至于这个的具体意思,以后再慢慢分析,这里不再细看 接下来的内容是: DEPENDS_eagle.app.v6 = $(LD_FILE) $(LDDIR)/eagle.rom.addr.v6.ld 这里LD_FILE暂时不知道是什么意思,但是LDDIR = $(SDK_PATH)/ld是在之前定义的 接下来的内容是: CONFIGURATION_DEFINES = -DICACHE_FLASH DEFINES += $(UNIVERSAL_TARGET_DEFINES) $(CONFIGURATION_DEFINES) DDEFINES += $(UNIVERSAL_TARGET_DEFINES) $(CONFIGURATION_DEFINES) 这里定义了DEFINES和DDEFINES这两个变量标志这些的具体内容我暂且也不知道是什么,不过从字面意思可以知道上面的可以知道这个应该和flash缓存有关系 到了这里依旧没有进行任何的实质性的编译工作,接下来的内容就是编译了,如下: INCLUDES := $(INCLUDES) -I $(PDIR)include sinclude $(SDK_PATH)/Makefile .PHONY: FORCE FORCE: 到这里还是没有看到真正的编译,只是包含了首目录的makefile,说明真正的编译工作还是得看首目录的makefile 到了这里我们可以意识到,esp8266的编译工作是一个有结构的编译,这个编译流程和Linux内核的编译流程十分的相似! 但是这里要注意这里只是把首目录的makefile包含进来,,并没有跳转目录,我和疑惑为什么没有把首目录的makefile作为第一个makefile,而用分目录! |
|
相关推荐
1 个讨论
|
|
本帖最后由 城东 于 2016-11-27 22:13 编辑
掠过前面的注释不谈,看到几个变量的定义: TARGET = eagle #FLAVOR = release FLAVOR = debug #EXTRA_CCFLAGS += -u 这里声明了两个变量TARGET和FLAVOR,前者作为一个标志,后者则代表当前代码是调试和是发行,接下来是: ifndef PDIR # { GEN_IMAGES= eagle.app.v6.out GEN_BINS= eagle.app.v6.bin SPECIAL_MKTARGETS=$(APP_MKTARGETS) SUBDIRS= user sample_lib driver endif # } PDIR 这里PDIR到目前为止是没有定义的,所以下面的内容会被执行,所以这里定义了GEN_IMAGES、GEN_BINS、SPECIAL_MKTARGETS和SUBDIRS,其中SPECIAL_MKTARGETS这个变量目前并不知道其具体意义,暂时留着 这里继续看下面的内容: LDDIR = $(SDK_PATH)/ld CCFLAGS += -Os TARGET_LDFLAGS = -nostdlib -Wl,-EL --longcalls --text-section-literals 这里也是定义三个变量LDDIR、CCFLAGS和TARGET_LDFLAGS注意在第一个变量中-Os是一个额外的编译标志,告诉GCC以优化尺寸(参考http://www.it1352.com/347430.html), /Os(代码大小优先)通过指示编译器优选大小而非速度来最小化 EXE 和 DLL 的大小。编译器可以将许多 C 和 C++ 构造缩小为功能类似的机器码序列。这些差异有时在大小和速度之间提供了折中。/Os 和 /Ot 选项允许在二者之间指定一个首选项: /Ot(代码速度优先)通过指示编译器优选速度而非大小来最大化 EXE 和 DLL 的速度。(这是默认设置。)编译器可以将许多 C 和 C++ 构造缩小为功能类似的机器码序列。这些差异有时在大小和速度之间提供了折衷。“最大化速度”(/O2/O1、/O2(最小化大小、最大化速度)) 选项隐含 /Ot 选项。/O2 选项组合若干个选项以产生速度非常快的代码。 如果使用 /Os 或 /Ot,还必须指定 /Og/Og(全局优化)以优化代码。(参考https://msdn.microsoft.com/zh-cn/library/f9534wye(VS.80).aspx) 接下来的内容是: ifeq ($(FLAVOR),debug) TARGET_LDFLAGS += -g -O2 endif ifeq ($(FLAVOR),release) TARGET_LDFLAGS += -g -O0 endif FLAVOR在本makefile的前面定义,选择了该代码是调试模式还是发行模式,最后他们的差别是-O2与-O0这两者的差异在上面一段代码的解释中有说明,接下来的内容是定义变量COMPONENTS_eagle.app.v6,这是一个编译器目标标示,标示要生成什么样的结果: COMPONENTS_eagle.app.v6 = user/libuser.a sample_lib/libsample.a driver/libdriver.a 注意这里只是定义了要生成的库的结果,比如user/libuser.a 是根据D:OracleshareSDKet_appuser的Makefile来生成库libuser.a,sample_lib/libsample.a根据D:OracleshareSDKet_appsample_lib的makefile来生成库libsample.a,但是注意这里只是定义了这些要生成的库的集合叫做COMPONENTS_eagle.app.v6,但是这里并没有真正进行编译工作。下面的内容是: LINKFLAGS_eagle.app.v6 = -L$(SDK_PATH)/lib -Wl,--gc-sections -nostdlib -T$(LD_FILE) -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lminic -lgcc -lhal -lphy -lpp -ljson -lpwm -lnet80211 -lwpa -lcrypto -lmain -lfreertos -llwip -lespconn -lsmartconfig -letilink -lfac -lairkiss $(DEP_LIBS_eagle.app.v6) -Wl,--end-group 这里定义了LINKFLAGS_eagle.app.v6这个连接标识,这个应该是和上面的COMPONENTS_eagle.app.v6一起使用,下面是标识符的定义: -L-->指定连接库的搜索路径 -l-->指定连接时期望连接的库的名字 -W FILE -->假定文件 FILE 已经被修改。(有时候LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R":) -nostdlib-->暂时不知道什么意思 -T$(LD_FILE)-->暂时不知道是什么意思 这里有一些规律性的东西如lminic,这里包含minic库,但是这个库并不是标准库,这里应该是D:OracleshareSDKlib下面的libminic.a,其他的也依旧类推 至于这个的具体意思,以后再慢慢分析,这里不再细看 接下来的内容是: DEPENDS_eagle.app.v6 = $(LD_FILE) $(LDDIR)/eagle.rom.addr.v6.ld 这里LD_FILE暂时不知道是什么意思,但是LDDIR = $(SDK_PATH)/ld是在之前定义的 接下来的内容是: CONFIGURATION_DEFINES = -DICACHE_FLASH DEFINES += $(UNIVERSAL_TARGET_DEFINES) $(CONFIGURATION_DEFINES) DDEFINES += $(UNIVERSAL_TARGET_DEFINES) $(CONFIGURATION_DEFINES) 这些的具体内容我暂且也不知道是什么 到了这里依旧没有进行任何的实质性的编译工作,接下来的内容就是编译了,如下: INCLUDES := $(INCLUDES) -I $(PDIR)include sinclude $(SDK_PATH)/Makefile .PHONY: FORCE FORCE: 到这里还是没有看到真正的编译,只是包含了首目录的makefile,说明真正的编译工作还是得看首目录的makefile 到了这里我们可以意识到,esp8266的编译工作是一个有结构的编译,这个编译流程和Linux内核的编译流程十分的相似! 但是这里要注意这里只是把首目录的makefile包含进来,,并没有跳转目录,我和疑惑为什么没有把首目录的makefile作为第一个makefile,而用分目录! |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
[小e体验板] 【小体积大智慧】关于体验板的技术问题,看这一篇就够了
2854 浏览 4 评论
【小e1开发板试用体验】分析程序架构四~/Share/SDK/makefile分析
3611 浏览 1 评论
6700 浏览 19 评论
29046 浏览 59 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 06:17 , Processed in 0.685183 second(s), Total 71, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号