GNU Make简明教程

来源:互联网 发布:我欲封天时装进阶数据 编辑:程序博客网 时间:2024/06/14 22:31

GNU Make简明教程

  • GNU Make简明教程
    • 学写第一个makefile
    • Makefile进阶
      • 假目标或人工目标
      • 变量
      • 自动变量
      • 虚拟路径
      • 模式规则
    • 一个makefile样例

学写第一个makefile

使用make可以从源文件自动构建可执行程序。
让我们以一个简单的例子来学习make。
编辑下面文件

// hello.c#include <stdio.h>int main() {    printf("Hello, world!\n");    return 0;}

创建名为 “makefile” 的文件,注意没有任何的拓展名。
其中包含建立可执行文件的规则,并保存在源文件的同一个目录中。命令如下:

touch makeflie

注意,makefile文件中使用Tab缩进命令(而不是空格)。makefile文件内容如下:

all: hellohello: hello.o    gcc -o hello.exe hello.ohello.o: hello.c    gcc -c hello.cclean:    rm hello.o hello.exe

运行“make”如下:

> make输出gcc -c hello.c     gcc -o hello.exe hello.o

运行没有参数的make,将会从all处开始。
一个makefile是一组规则的集合组成。
一个规则由3部分组成:一个目标,一个先决条件列表和一个命令,如下:

target: pre-req-1 pre-req-2 ...    command

目标和条件之间用冒号分隔(:)。
在命令前面使用的是Tab缩进命令(而不是空格)。
它开始通过先决条件查找对应文件。

> make输出make: Nothing to be done for `all'.

注意

  • 如果命令没有使用Tab缩进命令, 将会得到错误信息 “makefile:4: * missing separator. Stop.”

  • 如果在当前目录下没有makefile,你得到一个错误信息
    “make: * No targets specified and no makefile found. Stop.”

  • makefile可以命名为”makefile”, “Makefile” 或者 “GNUMakefile”, 注意没有无文件扩展名。

Makefile进阶

假目标(或人工目标)

一个目标,如果它并不代表一个文件,则称为假目标。例如,在上面的例子中的clean,只是一个命令的标签。如果目标是一个文件,它将检查其所需的预条件。标准的假目标有:all, clean, install。

变量

使用变量才能处理复杂的问题,GNU Make 的变量将会简化makefile的编写。
一个变量开始于一个$,并被封闭在括号内( (…) or {…})。
单字符变量不需要括号。
例如,

$(CC), $(CC_FLAGS), $@, $^.

自动变量

自动变量通过规则匹配后被设置。这包括:

$@:目标文件名。$*:目标文件名没有文件扩展名。$<:第一个先决条件文件名。$^:所有先决条件的文件名,用空格分隔,丢弃重复。$+:类似于$,但包括重复。$?:所有比目标较新的先决条件的名称,用空格隔开。

例如,我们可以把早期的Makefile改写为:

all: hello.exe# $@ matches the target; $< matches the first dependenthello.exe: hello.o    gcc -o $@ $<hello.o: hello.c    gcc -c $<clean:    rm hello.o hello.exe

虚拟路径

你可以使用VPATH(大写)到指定的目录中搜索相关的依赖项和标文件。例如:

# Search for dependencies and targets from "src" and "include" directories# The directories are separated by spaceVPATH = src include

使用vpath(小写)指定更加精确的文件类型及其搜索路径。

# Search for .c files in "src" directory; .h files in "include" directory# The pattern matching character '%' matches filename without the extensionvpath %.c srcvpath %.h include

模式规则

模式规则,它使用模式匹配的字符“%”作为文件名,如果没有明确的规则可以应用于创建一个目标。例如,

#适用于创建.o目标文件#“%”匹配文件名。# $< 是第一个先决条件# $(COMPILE.c) 由编译器名称和编译器选项组成# $(OUTPUT_OPTIONS) 是-o $@# $@:生成文件名。%.o: %.c    $(COMPILE.c) $(OUTPUT_OPTION) $<#用于从.o object file创建可执行的(无扩展名)# $^ 匹配所有先决条件(无重复)。%: %.o$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

一个makefile样例

此示例Makefile是来自Eclipse的”C/C++ Development Guide -Makefile”。

# A sample Makefile# This Makefile demonstrates and explains # Make Macros, Macro Expansions,# Rules, Targets, Dependencies, Commands, Goals# Artificial Targets, Pattern Rule, Dependency Rule.# Comments start with a # and go to the end of the line.# Here is a simple Make Macro.LINK_TARGET = test_me.exe# Here is a Make Macro that uses the backslash to extend to multiple lines.OBJS =  \Test1.o \Test2.o \ Main.o# Here is a Make Macro defined by two Macro Expansions.# A Macro Expansion may be treated as a textual replacement of the Make Macro.# Macro Expansions are introduced with $ and enclosed in (parentheses).REBUILDABLES = $(OBJS) $(LINK_TARGET)# Here is a simple Rule (used for "cleaning" your build environment).# It has a Target named "clean" (left of the colon ":" on the first line),# no Dependencies (right of the colon),# and two Commands (indented by tabs on the lines that follow).# The space before the colon is not required but added here for clarity.clean :   rm -f $(REBUILDABLES)  echo Clean done# There are two standard Targets your Makefile should probably have:# "all" and "clean", because they are often command-line Goals.# Also, these are both typically Artificial Targets, because they don't typically# correspond to real files named "all" or "clean".  # The rule for "all" is used to incrementally build your system.# It does this by expressing a dependency on the results of that system,# which in turn have their own rules and dependencies.all : $(LINK_TARGET)  echo All done# There is no required order to the list of rules as they appear in the Makefile.# Make will build its own dependency tree and only execute each rule only once# its dependencies' rules have been executed successfully.# Here is a Rule that uses some built-in Make Macros in its command:# $@ expands to the rule's target, in this case "test_me.exe".# $^ expands to the rule's dependencies, in this case the three files# main.o, test1.o, and  test2.o.$(LINK_TARGET) : $(OBJS)  g++ -g -o $@ $^# Here is a Pattern Rule, often used for compile-line.# It says how to create a file with a .o suffix, given a file with a .cpp suffix.# The rule's command uses some built-in Make Macros:# $@ for the pattern-matched target# $< for the pattern-matched dependency%.o : %.cpp  g++ -g -o $@ -c $<# These are Dependency Rules, which are rules without any command.# Dependency Rules indicate that if any file to the right of the colon changes,# the target to the left of the colon should be considered out-of-date.# The commands for making an out-of-date target up-to-date may be found elsewhere# (in this case, by the Pattern Rule above).# Dependency Rules are often used to capture header file dependencies.Main.o : Main.h Test1.h Test2.hTest1.o : Test1.h Test2.hTest2.o : Test2.h# Alternatively to manually capturing dependencies, several automated# dependency generators exist.  Here is one possibility (commented out)...# %.dep : %.cpp#   g++ -M $(FLAGS) $< > $@# include $(OBJS:.o=.dep)
0 0