你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

Ubuntu下开发STM32---1.我叫Makefile  

[复制链接]
qianfan 发布时间:2015-10-24 18:43
本帖最后由 QianFan 于 2016-3-18 17:06 编辑
+ _) k* S+ ~. o- f. v; z, h0 `5 _- h% t# @3 I
    回忆我们在windows环境下使用IDE进行开发,只要一股脑的将多有的源文件添加到工程中,点一个按钮,IDE就会为我们生成可执行文件。但是期间发生了什么?我们无从得知。IDE让我们编程简单的同时,也让我们变得更加傻瓜。
0 J# e+ \4 Z/ s  f& A: c# d; Z# c' l& j; _9 `5 b. i8 m
    在linux下编程,最常用的莫过于gcc了。比如我们编译main.c生成main.exe(在linux下,叫做main.out)或许更好些。只需要在控制台下敲下:
$ c$ G5 t. b$ \7 [    qianfan@Ubuntu $ gcc -Wall main.c -o main.out
5 j8 P5 o& e* w     -Wall是允许提示所有的警告。更多参数解释请参考http://gcc.gnu.org/onlinedocs/gcc/Option-Index.html 。这仅仅是编译一个文件。如果是想编译多个文件呢?比如foo.c和main.c构成一个工程,我们可以这样:( `2 r: D: Q( T# j8 s: D2 W
    qianfan@Ubuntu $ gcc -Wall main.c foo.c -o main.out
7 T3 ^5 a7 J5 P  j+ k# B0 _5 `9 `; Y  E+ H/ }  G' J, z! M3 M
    可是问题来了。如果你的整个工程中有成百上千个源文件。如果其中任意一个文件发生了变化,在生成一个可执行文件的时候,不管其余的文件是不是已经变化了,都需要将每一个C文件重新编译,最后在一次链接。这无疑浪费了大量的时间。人们想到了一个方法,将每一个源文件单独编译,生成*.o文件。只要源文件没有发生变化,链接的时候就使用之前的*.o文件。这样就减去了编译的时间了。生成*.o文件很简单。只要在编译的时候加上-c就好了。
1 I# k, Z2 @: w6 `) g) g( Z
  • qianfan@Ubuntu $gcc -Wall -c main.c -o main.o
  • qianfan@Ubuntu $gcc -Wall -c foo.c -o foo.o
    ! {4 O- r- G) \
编译完两个文件之后,在统一进行链接:
7 Z& ]. {2 Z2 B% F; O4 j/ W# u* K
  • qianfan@Ubuntu $gcc main.o foo.o -o main.out# R$ z" R2 w* q* Y$ m. D* V4 K/ X: j
如果你的main.c更改过,foo.o没有更改。只要重新编译main.c并和未更改的foo.o进行链接就好了。' ?1 b0 D5 v; \' [$ z/ z' E3 x
  • qianfan@Ubuntu $gcc -Wall -c main.c -o main.o
  • qianfan@Ubuntu $gcc main.o foo.o -o main.out/ g; z/ S9 ?- m: v6 p6 X& X! K
" G& z& |# [1 _: R6 M/ i
    人总是比较懒的。不情愿在控制台中敲击一千次来编译一千个源文件,他们索性发明了一个叫Makefile的东西。Makefile是一个文件的名字,类似与我们使用IDE创建的工程。Makefile中包含了使用什么命令,参数编译程序,或者进行其他的处理。举一个简单的例子。比如在~/debug/foo下有一个文件叫做Makefile。里面的内容是这样的:([TAB]是你用键盘按一下TAB键。由于显示空格,所以我这里使用TAB来代替他).
8 S& U) ]8 j9 i3 l# @: f9 Qall:5 F! `) Y+ k9 {0 L/ a
[TAB] echo Hello
6 y. Z% V' q' E7 s+ k[TAB] echo world!
. g3 |2 }  S5 s  t5 ^7 _! U
使用Makefile很简单,只要在控制台进入Makefile的目录,输入make all命令回车即可。
2 m' g# S- o( r" j* `
  • qianfan@Ubuntu $cd ~/debug/foo
  • qianfan@Ubuntu ~/debug/foo $ make all
    3 q; Z" S! A3 q1 p! M5 D. ^6 ?

    & T' m( q/ o4 o* U5 W
在运行之后,屏幕会输出:
3 f. Q; q! k/ R5 D* j    echo Hello; @6 o) P8 h# y0 B* b( ~$ ^
    Hello
$ p: s$ @' U: [; N4 x4 }    echo world!+ s2 b  P7 o$ ^5 O  _
    world
!
$ i8 h2 W! {  k1 V# QMakefile总会将他的命令和结果一同输出。如果你不想看到实际执行的命令,你可以在每行命令的前面加上@符号。这样命令就不会输出了。" u& x$ i& S. {+ `6 E: B+ D
all:
+ F6 B: h1 X" [5 v; y[tab] @echo Hello, J: O, |) _( ~4 t  l4 i
[tab] @echo world!
# v* r% t6 u! K3 n( H" z' ]; x# \- Q+ ^" z; q5 E
    上面的all叫做工作目标,与all在同一行的叫做依赖条件(如果没有依赖条件可以为空)。all下面的以TAB开头的若干行叫做执行命令。一个Makefile中可以有多个工作目标。如果你想执行Makefile中的特定的工作目标,可以在make后面加上工作目标的名字。像make all这样。如果你的make后面没有工作目标的名字。那么make会默认执行他在Makefile中找到的第一个工作目标。上面的make all其实等同于make。
! Y7 V- T8 b* o% u! V
+ r) t7 {6 ]; ]5 W8 a, M$ q0 a" h/ m
  R# e9 r- m2 E" l: j
--------------[我是分割线]---------------- z% c( f5 E! C$ Q# L2 g% I: l3 |4 \
    来看一个实际的例子。在~/debug/foo下有foo.c和main.c两个文件。两个文件共同链接成一个可执行文件。来为他写一个Makefile。$ {) [' U) h5 B9 p: v% w; X
OBJS = foo.o main.o* g$ v1 ~" |0 a1 p0 Z
DEFS = -DUSE_STDPERIPH_DRIVER
1 Y; e1 Z  z2 F5 u7 ]+ C1 pCFLAGS = -Wall  -g ) {5 h6 A+ H- x
0 A2 X8 F" n9 ?
all: main.out/ ?7 p1 q) ?6 ~2 A' [- H
clean:
$ @5 k" S5 n" V: Z9 F  M$ M  e# F[tab] @rm -f $(OBJS) main.out2 ~" l; x5 J8 S
5 k! t: @. ]6 x: d5 Y, }8 c
main.out: $(OBJS)% s1 l% u/ p! R4 f3 y1 g) I
[tab]gcc $^ -o $@# T: P7 l0 A# z4 u8 }& h# r

3 l/ n9 N% D" \3 i" v" B0 R! \%.o:%.c
/ A- A8 O; x+ M; z! A[tab]gcc $(DEFS) $(CFLAGS) -c $< -o $@
/ J& N7 r) d3 d$ c5 o6 V6 k# `4 {3 U# d: b- h1 x
main.o foo.o : foo.h* v2 D$ d% `+ H+ n8 _9 F
在上面的例子中,
4 u2 r4 ^: a5 q* Y( ]4 E$ D
  • OBJS, DEFS, CFLAGS都是变量名。类似与C语言,区分大小写。不需要声明,直接使用就行。在使用的时候需要前面家$,并使用括号括起来。像这样$(DEFS) 。
  • 在gcc的参数中,以-Dxxx开头的是宏。比如gcc -DDebug ... 在编译的时候定义了宏Debug
  • 在gcc的参数中,以-Ixxx开头的是头文件路径。如果想将Makefile的路径作为头文件路径,可以使用gcc -I./ 。
  • $<代表依赖条件中的地一个条件。$@代表工作目标的名字。$^代表依赖条件中所有的条件。
  • main.o :foo.h告诉make,当foo.h头文件变的时候,把main.c重新编译一次。
  • %.o : %.c的写法叫做隐含规则。意思是.c文件编译生成.o文件的时候,使用下面的命令。  o9 z1 Q" {  y8 o. ]' T
4 }$ ^, o! Q* l2 R2 R
    在上面的例子中,条件是foo.c main.c Makefile这三个文件在同一个文件夹中。但是如果不在呢?这样Makefile就找不到main.c foo.c了。比如这样的情况:4 J& R! L- j% w' y; |6 R2 i
                         | inc                   { foo.h
% ]" \2 e; T5 B5 F4 L

6 @# n: Q) A+ b! ~4 J~/debug/foo/ |  Makefile  
& d8 v& r7 Z2 T# u6 q$ `8 {
, k5 ]( h! _) J* h/ k
                        |  src                   {foo.c main.c* {  k* P' j/ ^1 u
这样的情况下,为了能够让Makefile找到源文件和头文件,需要在Makefile中添加这么两行:( v3 ]. t8 T+ b0 E; d7 Z
vpath %.c ./src! X- A6 y) @! ~% G* o
vpath %.h ./inc) A6 y/ q8 q( |- {" {
当然,添加vpath %.h ./inc只是为了让make找到foo.h。为了让gcc找到foo.h,不要忘记添加头文件路径(使用-I./inc添加)。  v/ u( v+ e4 F- p
, \+ K8 E4 s8 H/ k& ?) |4 w/ \7 K2 `
4 i* o) o! O( N7 O$ n4 g8 _
    关于Makefile就简单的介绍这么多。更多的Makefile的知识请尽情Google。或者参考书籍(GNU make项目管理)。/ n8 j. r& v+ g/ d# f4 ]
    附件1:GNU make的中文手册。仅供参考。
" z4 @+ x4 C4 Q9 k    附件2:GNU make项目管理。$ C. Z( `$ R4 a9 i
    附件3:  跟我一起写Makefile
* I* b5 g0 J) r0 A2 v& J/ F
! T2 z0 S% E6 v1 u+ ~8 i6 O合集地址:https://www.stmcu.org.cn/module/forum/thread-603753-1-1.html

gun_make.pdf

下载

1.34 MB, 下载次数: 2318

gnu make中文手册

GNU Make项目管理(第三版).pdf.part2.rar

下载

2.04 MB, 下载次数: 343

GNU Make项目管理(第三版).pdf.part1.rar

下载

9 MB, 下载次数: 428

how to write Makefile.pdf

下载

384.18 KB, 下载次数: 332

跟我一起写Makefile

评分

参与人数 1 ST金币 +1 收起 理由
永不停息 + 1 赞一个!

查看全部评分

赞 1 收藏 11 评论32 发布时间:2015-10-24 18:43

举报

32个回答
qianfan 回答时间:2016-3-18 17:05:03
beary 发表于 2016-3-18 15:17
- [' [7 P5 B9 `, L! o顶一个~~!!* V( t& h+ A/ z& ]( |; O" F
不错  不过这个之前了解过了,- w' H  U. Q" s" J
正好想学一下ubuntu 编译 - 下载stm32程序,楼主会继续更新吗 ...
% W6 D/ ]2 x6 V1 \
https://www.stmcu.org.cn/module/forum/thread-603753-1-1.html
qianfan 回答时间:2015-10-24 21:05:24
creep 发表于 2015-10-24 20:50/ _$ U5 L, C* }) f% [2 L5 y
@QianFan ,等你更新完成后放不方便分享个PDF版本,想跟着完整学习下!
$ n! u9 W9 e& P! P& y
都是在论坛手打的,如果PDF版本的话只能复制-粘贴了。。。话说橙子哥可以手动复制,粘贴啊
qianfan 回答时间:2016-3-18 12:20:13
jkop1216 发表于 2016-3-16 15:52  y& @0 ]) ^3 z! ~! {
Makefile 开发stm32例子呢?说的都是用的gcc,一点用也没有

: I$ Q3 P# R. p/ R) C( Ghttps://www.stmcu.org.cn/module/forum/thread-603753-1-1.html
风子 回答时间:2015-10-24 19:26:48
拜读了,留个印记
qianfan 回答时间:2015-10-24 19:31:09
风子 发表于 2015-10-24 19:26: @: F4 k) l% V0 {
拜读了,留个印记

8 ]" J+ d5 A) m
你好我好大家好! 回答时间:2015-10-24 20:14:38
:):):):):):):):)
hooke 回答时间:2015-10-24 20:45:45
楼主好厉害 学习了
creep 回答时间:2015-10-24 20:50:23
@QianFan ,等你更新完成后放不方便分享个PDF版本,想跟着完整学习下!
二货520 回答时间:2015-10-25 10:05:00
学习  
yanhaijian 回答时间:2015-10-25 16:41:10
makefile是Linux比较重要的东西。
samsamhoo 回答时间:2015-10-25 18:47:02
版主真是专业。
aoxiangwode2008 回答时间:2015-10-25 21:40:34
学习了,收藏一下。
ataudio 回答时间:2015-10-26 10:03:36
向你学习。重新再把linux捡起来。
qianfan 回答时间:2015-10-26 10:29:37
ataudio 发表于 2015-10-26 10:035 f5 v6 z7 x6 l8 i2 n3 a
向你学习。重新再把linux捡起来。

1 P* s, m: ~' ~7 ]( x之前也在linux下开发过?
ataudio 回答时间:2015-10-26 10:32:07
做过一点软件开发。
zj20115659 回答时间:2015-11-9 08:36:46
楼主很厉害啊
123下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版