Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义

本文介绍了Makefile的基础概念,包括其在项目构建过程中的作用,以及如何利用Makefile的特性简化编译流程。通过示例讲解了Makefile的编写方法,并演示了如何使用预定义变量和规则来进一步简化Makefile。

来自 http://my.oschina.net/u/1413984/blog/199029

Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是: 

$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。 

假设我们有下面这样的一个程序,源代码如下: 

/* main.c */ 

#include "mytool1.h" 

#include "mytool2.h" 

int main(int argc,char **argv) 

{ 

mytool1_print("hello"); 

mytool2_print("hello"); 

} 

/* mytool1.h */ 

#ifndef _MYTOOL_1_H 

#define _MYTOOL_1_H 

void mytool1_print(char *print_str); 

#endif 

/* mytool1.c */ 

#include "mytool1.h" 

void mytool1_print(char *print_str) 

{ 

printf("This is mytool1 print %s ",print_str); 

} 

/* mytool2.h */ 

#ifndef _MYTOOL_2_H 

#define _MYTOOL_2_H 

void mytool2_print(char *print_str); 

#endif 

/* mytool2.c */ 

#include "mytool2.h" 

void mytool2_print(char *print_str) 

{ 

printf("This is mytool2 print %s ",print_str); 

}


当然由于这个程序很短,我们可以这样来编译: 

gcc -c main.c 

gcc -c mytool1.c 

gcc -c mytool2.c 

gcc -o main main.o mytool1.o mytool2.o

 

 这样的话我们也可以产生main程序,而且也不是很麻烦。但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?也许你会说,这个很容易解决啊,我写一个 SHELL脚本,让它帮我去完成不就可以了。是的对于这个程序来说,是可以起到作用的。但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译? 

为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make。我们只要执行以下make,就可以把上面的问题解决掉。在我们执行make之前,我们要先编写一个非常重要的文件。--Makefile。对于上面的那个程序来说,可能的一个Makefile的文件是: 

# 这是上面那个程序的Makefile文件: 


main:main.o mytool1.o mytool2.o 

gcc -o main main.o mytool1.o mytool2.o 

main.o:main.c mytool1.h mytool2.h 

gcc -c main.c 

mytool1.o:mytool1.c mytool1.h 

gcc -c mytool1.c 

mytool2.o:mytool2.c mytool2.h 

gcc -c mytool2.c



有了这个Makefile文件,不论我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件它连理都不想去理的。 

下面我们学习Makefile是如何编写的。 

在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明。一般的格式是: 

target:components 

TAB rule 

第一行表示的是依赖关系。第二行是规则。 

比如说我们上面的那个Makefile文件的第二行。 

main:main.o mytool1.o mytool2.o 

表示我们的目标(target)main的依赖对象(components)是main.o mytool1.omytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令。就象我们的上面那个Makefile第三行所说的一样要执行 gcc-o main main.o mytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键 

Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是: 

$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。 

如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为: 

# 这是简化后的Makefile 

main:main.o mytool1.o mytool2.o 

gcc -o $@ $^ 

main.o:main.c mytool1.h mytool2.h 

gcc -c $< 

mytool1.o:mytool1.c mytool1.h 

gcc -c $< 

mytool2.o:mytool2.c mytool2.h 

gcc -c $< 

经过简化后,我们的Makefile是简单了一点,不过人们有时候还想简单一点。这里我们学习一个Makefile的缺省规则 

.c.o: 

gcc -c $< 

这个规则表示所有的 .o文件都是依赖与相应的.c文件的。例如mytool.o依赖于mytool.c这样Makefile还可以变为: 

# 这是再一次简化后的Makefile 

main:main.o mytool1.o mytool2.o 

gcc -o $@ $^ 

.c.o: 

gcc -c $< 

好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile的规则,可以查看相应的文档。

<think>好的,我现在需要解释用户关于GCC编译命令中-o $@ $^的用法的问题。首先,我要确认用户的问题点在哪里。用户可能是在看Makefile的时候遇到了这些符号,不太明白它们的含义和用法。我需要回忆一下Makefile中的自动变量,特别是$@$^分别代表什么。 根据之前的引用内容,比如引用[2]中提到,$@表示目标文件,$^表示所有的依赖文件。那在GCC命令中,-o后面接的是输出文件名,这里用了$@,也就是目标文件的名字。然后$^代表所有的依赖文件,这样编译器会把所有依赖的源文件一起编译链接成目标文件。 接下来,我需要举一个例子来说明。比如在Makefile中有这样一条规则: target: dep1.c dep2.c gcc -o $@ $^ 那么当执行make target时,$@会被替换成target,$^会被替换成dep1.c dep2.c,所以实际执行的命令是gcc -o target dep1.c dep2.c。这样就把两个源文件编译链接成可执行文件target。 用户可能还会疑惑这些符号的其他用途,比如$<代表第一个依赖文件,但在这个问题中主要关注$@$^。需要确保解释清晰,避免混淆。 另外,要注意用户提供的引用中有没有其他需要注意的地方。比如引用[1]中的示例Makefile,里面确实使用了$@$^来生成目标文件。引用[2]和[3]也解释了这些自动变量的含义,所以可以结合这些引用来加强回答的权威性。 最后,要确保回答符合用户的要求,使用中文,结构清晰,并且包含相关问题。可能用户后续还会想了解如何编写更复杂的Makefile,或者如何处理多个依赖等情况,所以相关问题需要围绕这些点展开。</think>关于GCC编译命令中`-o $@ $^`的用法及含义,这是Makefile中特有的自动变量语法,具体解释如下: ### 一、语法解析 1. **`$@`** 表示当前规则中的**目标文件名**。 *示例*:若规则为`main.o: main.c`,则`$@`会被替换为`main.o` 2. **`$^`** 表示当前规则中列出的**所有依赖文件**(自动去重)。 *示例*:若规则为`program: main.o utils.o`,则`$^`会被展开为`main.o utils.o` ### 二、组合用法示例 ```makefile program: main.o utils.o lib.o gcc -o $@ $^ ``` - **`-o $@`**:指定输出文件名为目标文件`program` - **`$^`**:将依赖的`main.o utils.o lib.o`全部链接 - **实际执行命令**:`gcc -o program main.o utils.o lib.o`[^2][^3] ### 三、对比其他自动变量 | 变量 | 含义 | 示例 | |------|-----------------------|--------------------| | `$<` | 第一个依赖文件 | `main.c` → `$<` | | `$?` | 比目标新的依赖文件 | 用于增量编译场景 | | `$*` | 匹配通配符的文件前缀 | `file.c` → `file` | ### 四、典型应用场景 1. **多文件编译**:将多个`.o`文件链接为可执行文件 ```makefile app: a.o b.o c.o gcc -o $@ $^ ``` 2. **动态生成目标名**:保持规则与目标名称解耦 ```makefile %.o: %.c gcc -c $< -o $@ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值