03.编译 & makefile

一、系统与编译器,及编译过程:(https://wenku.baidu.com/view/000a79ff04a1b0717fd5dded.html

    预处理:gcc -E -o hello.i hello.c    (生成预处理文件.i)

    编译:  gcc -S -o hello.s hello.i      (生成汇编文件.s。-o选项可省略)

    汇编:  gcc -c -o hello.o hello.s     (生成对象文件.o。预处理+编译+汇编。-o选项可省略)


    1、(Linux下的链接 - 生成可执行文件)

    链接:  gcc -o hello hello. o         (生成可执行文件。预处理+编译+汇编+链接。-o命名,可省略。-static链接静态库。ldd查看可执行文件的动态链接库。)


    2、(SOC下的链接 - 生成bin文件)

    使用链接脚本并生成elf格式文件:arm-linux-ld -T xxx.lds a.o b.o c.o -o xxx.elf (elf文件含有地址信息)

    将elf文件转换成二进制bin文件:arm-linux-objcopy -O binary -S xxx.elf xxx.bin(bin文件不含地址信息)

     (反汇编文件,用于调试:arm-linux-objdump -D xxx.elf > xxx.dis)



二、makefile:

    1、执行make命令后,系统在当前目录找到名为makefile的文件并执行。不带( -f )参数时,默认从首个没有通配符的目标进行构造。make命令会读取整个makefile进去分析。make命令之后可带参数。用来传递参数,或直接修改makefile里面的参数值。makefile只能有一个终极目标。如果要生成多个目标,可以添加假想目表all并执行命令:make all,表示从此开始执行。all依赖于需要生成的目标,但没有规则。

    2、核心规则: 当"目标文件"不存在或某个依赖文件比目标文件新,则: 执行"命令"。目标和命令的参数用空格分割。若改动头文件,则编译引用此头文件的所有文件。规则如下:

            target: 依赖1 依赖2 ... ...

            [TAB]命令

    3、其他规则:

            makefile中执行的shell命令,一行创建一个进程来执行。

            可以通过接续符" ; "将多个命令组合成一个。组合的命令依次在同一个进程中被执行。

            set -e指定发生错误后立即退出执行。

    4、语法:

            " / ":换行符。使代码易读

            " % ":通配符。与*类似,可以使用$(wildcard *)来代替。

            " $@ ":目标。

            " $< ":第1个依赖文件。

            " $^ ":所有依赖文件。

            " $? ":构造所需文件列表中更新过的文件。

            " $(objects) ":变量。用" = "为变量objects赋值。

            " .PHONY ":假想目标。其修饰的目标,只有规则没有依赖。没有依赖的文件,makefile会忽视其规则。clean之后是没有依赖的。如果在makefile文件相同路径下有名为clean的文件,会因无法判断目标与依赖的时间关系,导致无法执行下面规则。.PHONY : clean

            " export ":导出变量,路径等。同一级的另外一个makefile,无法得到export声明的内容。

            " A:=xxx ":即时变量。A的值在定义时即刻确定。

            " A=xxx ":延时变量。A的值在使用时确定。延时变量的值为整个makefile最后赋的值。

            " A?=xxx ":延时变量。首次定义起效。如果前面已定义则忽略。

            " A+=xxx ":附加。它是即时变量还是延时变量取决于前面的定义。

            " echo ":显示输出,输出:命令+结果。

            " @echo ":隐式输出,输出:结果。

            " include xxx ":将其他文件内容原封不动的搬入当前文件,类似C语言。

    5、关键词:

            " VPATH = path1 : path2 : ... ":make在当前目录找不到依赖文件和目标文件的情况下,到所指定的目录中去找寻文件。

            " vpath <pattern> <directories> ":为符合模式<pattern>的文件指定搜索目录<directories>。

            " vpath <pattern> ":清除符合模式<pattern>的文件的搜索目录。

            " vpath ":清除所有已被设置好了的文件搜索目录。

    6、函数:

            " $(foreach var, list,text) ":var中存放list每个值。text内必须包含“var”字段。并把每个var字段用text声明的格式替换。

            " $(filter pattern...,text) ":从text中取出,符合patten格式的值。

            " $(filter-out pattern...,text) ":从text中取出,不符合patten格式的值。

            " $(wildcard file) ":从当前目录中,寻找与file格式或名字匹配的文件。

            " $(basename file) ":取得文件的名字file(即去掉后缀)。

            " $(notdir dir) ":把展开的文件dir去掉路径信息。

            " $(patsubst pattern, replacement, $(list)) ":依次从列表list中取值与pattern对比。格式符合则用replacement替换。

            " $(addprefix fixstring,string1 string2 ...) ":fixstring 是要添加的前缀,逗号后是一个或多个要添加前缀的子字符串。



三、简化makefile与自动生成依赖关系:

    1. 大多C/C++ 编译器都支持“ -M ”等选项,自动寻找源文件中包含的头文件,生成一个依赖关系。即告诉预处理器输出适合make的规则,来描述目标文件的依赖关系。

    2. 参数:

            " -M ":生成文件依赖关系,包含标准库的头文件。规则显示在标准输出,需要重定向。-M会默认打开 -E 选项,作用是使得编译器在预处理结束时就停止编译。

            " -MM ":生成文件依赖关系,不包含标准库的头文件。

            " -MG ":要求把缺失的头文件按存在对待,并且假定他们和源程序文件在同一目录下。必须和" -M "一起使用。

            " -MF file ":与" -M "或" -MM "一同使用,则把依赖关系写入名为" file "的文件中。若与" -MD "或" -MMD ",“-MF” 将覆盖写入。

            " -MD ":等于" -M -MF File ",但默认关闭" -E "选项。输出文件名基于" -o "选项,并添加 .d 后缀。若没有" -o ",则使用输入的文件名。

            " -MMD ":类似于" -MD ".不包含标准库的头文件。

            " -MP ":生成的依赖文件里面,依赖规则中的所有.h依赖项都会在该文件中生成一个伪目标,其不依赖任何其他依赖项。该伪规则避免了删除对应的头文件但没有更新“Makefile” 来匹配新的依赖关系,导致make出错的结果。

            " -MT ":在生成的依赖文件中,指定依赖规则中的目标。


    如下面的例子:

        %.d : %.c

                @set -e; \

                gcc -MM $@ > $@.$$$$; \

                sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \

                rm -f $@.$$$$


        -include seq.d


    分析:

        1. @set -e:@关键字告诉make不输出该行命令;set -e表示当后面命令的返回值非0时立即退出。

        2. gcc -MM $< > $@.$$$$:根据源文件生成依赖关系,并保存到临时文件中。" $< "为第一个依赖文件。" $$$$ "为字符串" $$ "。makefile中" $ "为特殊字符(即使在单引号中)。需要用" $$ "来转义,来得到" $ "。" $$ "是shell的特殊变量,它的值为当前进程号。为保证创建文件的唯一性(包括临时变量),一般使用进程号做后缀。

        3. sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@:将目标文件加入依赖关系目录列表中,并保存到目标文件。" $* "为第一个依赖文件去掉后缀的名称。



GNU make: http://www.gnu.org/software/make/manual/make.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 来自陈浩的一片老文,但绝对营养。 示例工程:3 个头文件*.h,和 8 个 C 文件*.c。 初 编译过程,源文件...
    周筱鲁阅读 4,690评论 0 17
  • makefile关系到整个工程的编译规则,一个工程中的源文件不计其数,按其类型、功能、模块分别放在若干的目录当中,...
    Joe_HUST阅读 1,876评论 0 3
  • @(linux 编程)[开发技能, 工具使用] What is GNU Make Make 是控制工程中通过源码生...
    orientlu阅读 11,325评论 0 26
  • makefile 介绍 make命令执行时,需要一个 makefile 文件,以告诉make命令如何去编译和链接程...
    Stan_Z阅读 1,620评论 2 15
  • 第一章:编译和安装SCons第二章:简单编译第三章:编译相关的一些事情第四章:编译和链接库文件第五章:节点对象第六...
    仙灵儿阅读 11,760评论 0 3