makefile 使用实例(二)

在智能一点,全部使用自动化变量

obj= main.o foo1.o foo2.o
main  : $(obj)
    gcc -o [email protected] $^

clean:
    rm -f *.o main1 main

@代表规则目标本例就是main,^代表规则所依赖文件本例是 main.o foo1.o 和foo2.o

makefile也可以编译多目标文件,我们本例拷贝一份 main.c 命名为 main1.c,

obj= main.o foo1.o foo2.o
obj1= main1.o foo1.o foo2.o
var = main main1
all: $(var)
main  : $(obj)
    gcc -o [email protected] $^
main1  : $(obj1)
    gcc -o [email protected] $^

clean:
    rm -f *.o main1 main

结果是:

 make
cc    -c -o main.o main.c
cc    -c -o foo1.o foo1.c
cc    -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
cc    -c -o main1.o main1.c
gcc -o main1 main1.o foo1.o foo2.o

发现生成了多目标 main 和main1 。

优化后的makefile:

obj= main.o foo1.o foo2.o
obj1= main1.o foo1.o foo2.o
all: $(obj1) main
main  : $(obj)
    gcc -o [email protected] $^
$(obj1):%.o:%.c

clean:
    rm -f *.o main1 main

下面显示一下 和<区别:

obj= main.o foo1.o foo2.o
all:main
main:  main.o foo1.o foo2.o
    gcc -o [email protected] $^
clean:
    rm -f *.o main1 main

编译过程是:

make
cc    -c -o main.o main.c
cc    -c -o foo1.o foo1.c
cc    -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o

可以正确编译文件,

我们修改makefile为:

make
gcc -o main main.o
main.o: In function `main‘:
main.c:(.text+0x1c): undefined reference to `foo1‘
main.c:(.text+0x21): undefined reference to `foo2‘
collect2: ld returned 1 exit status
make: *** [main] Error 1

发现只有一个文件 mian.o 少了foo1.o 和 foo2.o。

all

作为Makefile的顶层目标,一般此目标作为默认的终极目标。 即使 all前不加 .PHONY,也会默认作为终极目标

以前很迷惑 = := 和+= 区别

obj= main.o foo1.o foo2.o
all:main

A=PPTV
B=$(A)
A=DSP
C=$(B)
main:  main.o foo1.o foo2.o
    gcc -o [email protected] $^
    @echo $(C)
clean:
    rm -f *.o main1 main

结果是

 make
cc    -c -o main.o main.c
cc    -c -o foo1.o foo1.c
cc    -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
DSP

操竟然不是 PPTV,

obj= main.o foo1.o foo2.o
all:main

A:=PPTV
B:=$(A)
A:=DSP
C:=$(B)
main:  main.o foo1.o foo2.o
    gcc -o [email protected] $^
    @echo $(C)
clean:
    rm -f *.o main1 main

结果是:

cc    -c -o main.o main.c
cc    -c -o foo1.o foo1.c
cc    -c -o foo2.o foo2.c
gcc -o main main.o foo1.o foo2.o
PPTV

现在是我们想输出的PPTV了,

“=”

make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值

“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

要是下面你只输出什么me??

obj= main.o foo1.o foo2.o
all:main

A:=PPTV
B:=$(A)
A=DSP
C:=$(B)
main:  main.o foo1.o foo2.o
    gcc -o [email protected] $^
    @echo $(C)
clean:
    rm -f *.o main1 main

这个结果是PPTV

因为B:=$(A)是即使展开,此时B=A=PPTV

obj= main.o foo1.o foo2.o
all:main

A:=PPTV
B=$(A)
A=DSP
C:=$(B)
main:  main.o foo1.o foo2.o
    gcc -o [email protected] $^
    @echo $(C)
clean:
    rm -f *.o main1 main

这个结果是DSP

因为 B=$(A)值是A在makefile最后的值,本例中最后的值是A:=DSP

时间: 2024-10-12 14:47:29

makefile 使用实例(二)的相关文章

Makefile持续学习二

Makefile概述 一.Makefile里有什么? Makefile里主要包含5个东西:显式规则.隐晦规则.变量定义.文件指示和注释 1.显式规则:显式规则说明如恶化生成一个或多的目标文件,包含要生成的文件,文件的依赖文件,生成的命令 2.隐晦规则:由make自动推动功能完成 3.变量定义:变量一般都是字符串,类似C语言中的宏定义,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上 4.文件指示: 在一个Makefile中引用另一个Makefile 根据某些情指定Makefil

【Linux学习】Makefile学习(二)

FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 40975    Accepted Submission(s): 13563 Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats g

DWR入门实例(二)

DWR(Direct Web Remoting) DWR is a Java library that enables Java on the server and JavaScript in a browser to interact and call each other as simply as possible. Dwr能让在服务器端的java代码和浏览器客户端的javascript代码尽可能简单的相互调用. DWR is Easy Ajax for Java!  官网:http://d

Hibernate实例二

Hibernate实例二 一.测试openSession方法和getCurrentSession方法 hebernate中可以通过上述两种方法获取session对象以对数据库进行操作,下面的代码以及注解是对两种方法的辨析 SessionTest.java 1 import java.sql.Connection; 2 import java.sql.SQLException; 3 import java.util.Date; 4 5 import org.hibernate.Session; 6

Linux DNS的主从服务器配置实例(二)

在主DNS服务器运行正常的情况下,在另外的一台与之相同的服务器上配置从DNS服务器:操作如下: 我们这里创建DNS从服务器是实验,没有注册,,实际工作中需要注册才能正常使用,明白!!嘻嘻你懂得! 从服务器配置前提调试:(网络必须相同,小孩都知道的!)  1.统一时间  #ntpdate 172.16.0.1 -----指定时间服务器地址(瞬间跟新时间)  #corntab -e----------------------计划任务可以设置定期更新   */3 * * * * /sbin/ntpda

c#事件实例二

c#事件实例二 事件驱动程序与过程式程序最大的不同就在于,程序不再不停地检查输入设备,而是呆着不动,等待消息的到来,每个输入的消息会被排进队列,等待程序处理它.如果没有消息在等待, 则程序会把控制交回给操作系统,以运行其他程序. 操作系统只是简单地将消息传送给对象,由对象的事件驱动程序确定事件的处理方法.操作系统不必知道程序的内部工作机制,只是需要知道如何与对象进行对话,也就是如何传递消息. 先来看看事件编程有哪些好处. 1.使用事件,可以很方便地确定程序执行顺序. 2.当事件驱动程序等待事件时

C语言库函数大全及应用实例二

原文:C语言库函数大全及应用实例二                                              [编程资料]C语言库函数大全及应用实例二 函数名: bioskey 功 能: 直接使用BIOS服务的键盘接口 用 法: int bioskey(int cmd); 程序例: #i nclude #i nclude #i nclude #define RIGHT 0x01 #define LEFT 0x02 #define CTRL 0x04 #define ALT 0x0

Json转换利器Gson之实例二-Gson注解和GsonBuilder

有时候我们不需要把实体的所有属性都导出,只想把一部分属性导出为Json. 有时候我们的实体类会随着版本的升级而修改. 有时候我们想对输出的json默认排好格式. ... ... 请看下面的例子吧: 实体类: [java] view plaincopy import java.util.Date; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; public 

WPF中的多进程(Threading)处理实例(二)

原文:WPF中的多进程(Threading)处理实例(二) 1 //错误的处理 2 private void cmdBreakRules_Click(object sender, RoutedEventArgs e) 3 { 4 Thread thread = new Thread(UpdateTextWrong); 5 thread.Start(); 6 } 7 8 private void UpdateTextWrong() 9 { 10 txt.Text = "Here is some n