`
lobin
  • 浏览: 425954 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多
写道
 

 

 

make

Makefile

Makefile包含规则(explicit rules, 显式规则以及implicit rules, 隐式规则),变量定义(variable definitions), 指令(directives), 以及注释(comments)五类东西。

 

一个Makefile可以不包含上面的任何东西,比如一个空的Makefile文件。或者只包含一些变量定义,指令,注释等,可以不包含规则。

 

执行make默认在当前目录下加载Makefile文件并解释执行第1个规则。

 

可以指定-f FILE, --file=FILE或者--makefile=FILE加载指定的Makefile文件。

写道
-f FILE, --file=FILE, --makefile=FILE
Read FILE as a makefile.

还可以指定-C DIRECTORY, --directory=DIRECTORY转到指定目录加载Makefile文件。

写道
-C DIRECTORY, --directory=DIRECTORY
Change to DIRECTORY before doing anything.

 

>make

/cygdrive/d/usr/bin/git/bin/echo: line 7: $'\r': command not found

在Cygwin控制台下执行就不会有这种问题:

>make

 

 

Rule

即规则,

 

 

写道
target: prerequisites
tab recipes

 

写道
target: prerequisite 1 2 3 ... prerequisite n
tab recipe 1
tab recipe 2
tab recipe 3
tab ...
tab recipe n

 

Target

即目标,

 

Phony

写道
A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.

 

Prerequisite

即前提条件

 

Recipe

即食谱,其实就是一组规则逻辑。

start:
	echo this is var 1

每个Recipe一行,每个Recipe以一个"tab"开头。

start:
	echo this is var 1
	echo this is var 2
	echo this is var 3

多个Recipe在一行,通过";"分割。

start:
	echo this is var 1;echo this is var 2;echo this is var 3

 

转义

转义符"\",转义符可以出现在Makefile中的任何地方。

 

比如输出"#"

因为"#"表示后面的是注释内容,解析的时候"#"及后面的注释内容将被忽略掉。所以要输出"#",需要对它进行转义:\#

@echo \#

 

start:
	@echo #
	@echo \#

	@echo # this is a comment
	@echo \# this is not a comment

 

 

start:
	echo this is \
	\
	var 1

	echo this is \
	\
	var 2\; echo this is \
	\
	\
	var 3

	echo this is \
	\
	var 4\; 
	echo this is \
	\
	\
	var 5

	echo this is \
	\
	var 6; \
	echo this is \
	\
	\
	var 7

 

Variable

即变量,

var = a

 

var1 = this is \
\
var 1

start:
	@echo $(var1)

 

var := a

 

变量也可以没定义直接使用

 

也可以在执行make的时候传入变量:

>make global_variable=abc

 

echo $(global_variable)

 

另外还有一些预定义的变量,如AS、CC、CXX、CFLAGS、CXXFLAGS等。参考“Variables Used by Implicit Rules”

写道
Here is a table of some of the more common variables used as names of programs in built-in rules:

AR

Archive-maintaining program; default ‘ar’.
AS

Program for compiling assembly files; default ‘as’.
CC

Program for compiling C programs; default ‘cc’.
CXX

Program for compiling C++ programs; default ‘g++’.
CPP

Program for running the C preprocessor, with results to standard output; default ‘$(CC) -E’.
FC

Program for compiling or preprocessing Fortran and Ratfor programs; default ‘f77’.
M2C

Program to use to compile Modula-2 source code; default ‘m2c’.
PC

Program for compiling Pascal programs; default ‘pc’.
CO

Program for extracting a file from RCS; default ‘co’.
GET

Program for extracting a file from SCCS; default ‘get’.
LEX

Program to use to turn Lex grammars into source code; default ‘lex’.
YACC

Program to use to turn Yacc grammars into source code; default ‘yacc’.
LINT

Program to use to run lint on source code; default ‘lint’.
MAKEINFO

Program to convert a Texinfo source file into an Info file; default ‘makeinfo’.
TEX

Program to make TeX DVI files from TeX source; default ‘tex’.
TEXI2DVI

Program to make TeX DVI files from Texinfo source; default ‘texi2dvi’.
WEAVE

Program to translate Web into TeX; default ‘weave’.
CWEAVE

Program to translate C Web into TeX; default ‘cweave’.
TANGLE

Program to translate Web into Pascal; default ‘tangle’.
CTANGLE

Program to translate C Web into C; default ‘ctangle’.
RM

Command to remove a file; default ‘rm -f’.

Here is a table of variables whose values are additional arguments for the programs above. The default values for all of these is the empty string, unless otherwise noted.

ARFLAGS

Flags to give the archive-maintaining program; default ‘rv’.
ASFLAGS

Extra flags to give to the assembler (when explicitly invoked on a ‘.s’ or ‘.S’ file).
CFLAGS

Extra flags to give to the C compiler.
CXXFLAGS

Extra flags to give to the C++ compiler.
COFLAGS

Extra flags to give to the RCS co program.
CPPFLAGS

Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).
FFLAGS

Extra flags to give to the Fortran compiler.
GFLAGS

Extra flags to give to the SCCS get program.
LDFLAGS

Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.
LDLIBS

Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.
LFLAGS

Extra flags to give to Lex.
YFLAGS

Extra flags to give to Yacc.
PFLAGS

Extra flags to give to the Pascal compiler.
RFLAGS

Extra flags to give to the Fortran compiler for Ratfor programs.
LINTFLAGS

Extra flags to give to lint.

 

 

shell

$(SHELL)

这是makefile中内置的一个变量,它指向makefile中使用shell是使用的哪个shell?可以输出看看:

echo $(SHELL)

/bin/sh

可以看出它指向/bin/sh

 

也可以自己指定shell解释器

#SHELL = /bin/sh

#SHELL = /usr/bin/sh

 

SHELL = /usr/bin/bash

 

Directive

即指令

 

include

写道
include filenames…

 

 

例子

include system.mk

 

define

define var1
this is \
\
var 1
endef

start:
	@echo $(var1)

 

 

override

 

conditional

条件判断

写道
conditional-directive
text-if-true
endif

if...else...endif

 

ifeq ($(var),c)

...

else

...

endif

写道
conditional-directive
text-if-true
else
text-if-false
endif

 

if...else if...else...endif

ifeq ($(var),a)

...

else ifeq ($(var),b)

...

else

...

endif

写道
conditional-directive-one
text-if-one-is-true
else conditional-directive-two
text-if-two-is-true
else
text-if-one-and-two-are-false
endif

 

conditional-directive

 

写道
ifeq (arg1, arg2)
ifeq 'arg1' 'arg2'
ifeq "arg1" "arg2"
ifeq "arg1" 'arg2'
ifeq 'arg1' "arg2"

 

写道
ifneq (arg1, arg2)
ifneq 'arg1' 'arg2'
ifneq "arg1" "arg2"
ifneq "arg1" 'arg2'
ifneq 'arg1' "arg2"

 

写道
ifdef variable-name

 

写道
ifndef variable-name

 

使用shell中的条件判断

 

if...then...fi

if [[ $(kernel_size_in_sector) -gt 64 ]]; then \

dd if=boot/setup of=Image seek=512 obs=1 ibs=512 count=$(setup_size_in_sector) conv=notrunc ; \

fi

 

if...else...fi

 

if [[ $(kernel_size_in_sector) -le 64 ]]; then \

dd if=system.exe of=Image seek=512 obs=1 ibs=512 count=$(kernel_size_in_sector) conv=notrunc ; \

else \

dd if=boot/setup of=Image seek=512 obs=1 ibs=512 count=$(setup_size_in_sector) conv=notrunc ; \

dd if=system.exe of=Image seek=$(kernel_disk_offset) obs=1 ibs=512 count=$(kernel_size_in_sector) conv=notrunc ; \

fi

 

comment

即注释

"#"用于注释一行,"#"后面的被认为是注释,在解析的时候将被忽略。

 

生成Makefile文件

Makefile可以手工编写,也可以通过configure自动生成。

 

$ autoscan 

执行之后生成configure.scan文件。

写道
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_CONFIG_SRCDIR([array.c])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset pow sqrt])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

 

需要根据需要进行一些修改。

写道
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AM_INIT_AUTOMAKE(libmath, 1.0)
AC_CONFIG_SRCDIR([array.c])
# AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CC

# Checks for libraries.
AC_PROG_RANLIB

# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h])

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset pow sqrt])

# AC_OUTPUT
AC_OUTPUT(Makefile)

 

$ mv configure.scan  configure.in

$ aclocal

$ autoconf

 

编写Makefile.am文件

写道
AUTOMAKE_OPTIONS = foreign
INCLUDEES = -I../log/include
# bin_PROGRAMS = libmath
# libmath_SOURCES = array.c map.c set.c similarity_chebyshev.c similarity_cos.c similarity_euclidean.c similarity_jaccard.c similarity_manhattan.c similarity_minkowski.c vt.c
# libmath_LDADD = -L. -lmath
lib_LIBRARIES = libmath.a
libmath_a_SOURCES = array.c map.c set.c similarity_chebyshev.c similarity_cos.c similarity_euclidean.c similarity_jaccard.c similarity_manhattan.c similarity_minkowski.c vt.c
export INCLUDES

 

$ automake --add-missing

执行后生成Makefile.in文件。

$ ./configure CFLAGS=-I/cygdrive/h/{...}/usr/log/include

checking for a BSD-compatible install... /usr/bin/install -c

checking whether build environment is sane... yes

checking for a thread-safe mkdir -p... /usr/bin/mkdir -p

checking for gawk... gawk

checking whether make sets $(MAKE)... yes

checking for gcc... gcc

checking whether the C compiler works... yes

checking for C compiler default output file name... a.exe

checking for suffix of executables... .exe

checking whether we are cross compiling... no

checking for suffix of object files... o

checking whether we are using the GNU C compiler... yes

checking whether gcc accepts -g... yes

checking for gcc option to accept ISO C89... none needed

checking for style of include used by make... GNU

checking dependency style of gcc... gcc3

checking for ranlib... ranlib

checking how to run the C preprocessor... gcc -E

checking for grep that handles long lines and -e... /usr/bin/grep

checking for egrep... /usr/bin/grep -E

checking for ANSI C header files... yes

checking for sys/types.h... yes

checking for sys/stat.h... yes

checking for stdlib.h... yes

checking for string.h... yes

checking for memory.h... yes

checking for strings.h... yes

checking for inttypes.h... yes

checking for stdint.h... yes

checking for unistd.h... yes

checking for stdlib.h... (cached) yes

checking for string.h... (cached) yes

checking for stdlib.h... (cached) yes

checking for GNU libc compatible malloc... yes

checking for stdlib.h... (cached) yes

checking for GNU libc compatible realloc... yes

checking for memset... yes

checking for pow... yes

checking for sqrt... yes

checking that generated files are newer than configure... done

configure: creating ./config.status

config.status: creating Makefile

config.status: executing depfiles commands

 

执行后生成Makefile文件。

 

后面就可以make了。

$ make

 

在Windows命令行下运行CYGWIN的make的时候,出现如下提示:

>make

rm -f *.bak

      0 [main] rm 1616 stdio_init: couldn't make stderr distinct from

stdout

rm -f *.o

      0 [main] rm 3228 stdio_init: couldn't make stderr distinct from

stdout

 

查看make版本如下:

>make --version

GNU Make 3.82.90

Built for i686-pc-cygwin

这种在CYGWIN或者linux下执行的时候不会有这个提示:

$ make

rm -f *.bak

 

rm -f *.o

 

运行如下命令进入CYGWIN的命令行输入:

>CYGWIN=tty

 

Administrator@ADA ~

$

 

再执行make就没有上面的提示了:

$ make

rm -f *.bak

rm -f *.o

 

 

C/C++程序的构建打包以及发布安装

在linux下编写C/C++程序,一定使用过make去编译构建源代码。

 

通过make编译构建C程序的完整例子

SRCS     = $(wildcard *.c)

SRCS-MAIN = $(filter-out %test.c, $(SRCS))
SRCS-TEST     = $(wildcard *test.c)

OBJS     = $(patsubst %.c, %.o, $(SRCS))
OBJS-MAIN     = $(patsubst %.c, %.o, $(SRCS-MAIN))
OBJS-TEST     = $(patsubst %.c, %.o, $(SRCS-TEST))

TESTS = $(patsubst %.c, %, $(SRCS-TEST))

build: compile test
	

$(TESTS): %: %.o 
	$(CC) $(OBJS-MAIN) $< -o $@

test: $(TESTS)
	@echo [test] build [$(OBJS-TEST)] to [$(TESTS)]


%.o: %.c
	$(CC) -c $< -o $@

compile: $(OBJS)
	@echo [main] $(OBJS-MAIN)
	@echo [test] $(OBJS-TEST)


clean:
	$(RM) *.bak
	$(RM) *.o
	$(RM) *.exe 

 

 

build

编写完C/C++程序后,通常通过

make

或者

make build

去构建,它会对源程序进行编译,然后链接构建,生成目标程序,如可执行目标程序,或者目标库,如果需要的话把构建好了的目标程序打包的话,还可以打包好。

 

如果程序是以源代码形式发布的话,直接将源程序打包。

 

install

make install

 

在Makefile文件中,可以像gcc那样在命令行下那样编译单个和多个文件。

还是这样编译多个文件:

$(CC) -c $(CFLAGS) $(wildcard *.c)

 

或者:

SRCS     = $(wildcard *.c)

OBJS1     = $(patsubst %.c, %.o, $(SRCS))

$(OBJS1) : %.o: %.c 

$(CC) -c $(CFLAGS) -o $@ $<

 

compile4: $(OBJS1)

这样也可以编译多个文件,但这样也是一个一个的进行编译。

 

或者:

SRCS     = $(wildcard *.c)

OBJS2  = $(SRCS:%.c=%.o)

$(OBJS2) : %.o: %.c 

$(CC) -c $(CFLAGS) -o $@ $<

compile5: $(OBJS2)

这样也可以编译多个文件,但和上面一样,也是一个一个的进行编译。

 

$(wildcard *.c)

 

$(patsubst %.c, %.o, $(wildcard *.c)

 

$^

表示所有依赖项

如:

compile: $(wildcard *.c) $(wildcard */*.c)

    $(CC) -c $^

这里的$^就表示$(wildcard *.c) $(wildcard */*.c)

 

$<

表示第一个依赖项

 

$@

表示目标

 

 

以下例子中,

SRCS     = $(wildcard *.c)

OBJS     = $(patsubst %.c, %.o, $(SRCS))

TARGETS  = $(SRCS:%.c=%)

all : $(TARGETS)

compile: $(OBJS)

$(TARGETS): %: %.o

$(CC) $(LDFLAGS) -o $@ $<

$(OBJS) : %.o: %.c 

$(CC) -c $(CFLAGS) -o $@ $<

第1个$@表示%对应的目标(也就是$(TARGETS)展开后的*.c源程序文件去掉后缀名)

第2个$@表示%.o对应的目标(也就是$(OBJS)展开后的*.c源程序文件将.c后缀换成.o)

第1个$<表示%.o对应的依赖项(也就是对应目标%加上.o后缀)

第2个$<表示%.c对应的依赖项(也就是对应目标%.o将.o后缀换成.c)

 

 

在一个项目中,如果有多个main函数(每个main函数都在一个独立的源程序文件中),在make构建时,每个main函数对应生成一个执行文件。

以下例子中,有3个main函数,分别在read_test.c demo.c server.c中,make构建后分别生成3个执行文件read_test demo server。

 

gcc $(filter-out read_test.o demo.o, $(wildcard *.o)) -o server

gcc $(filter-out server.o demo.o, $(wildcard *.o)) -o read_test

gcc $(filter-out server.o read_test.o, $(wildcard *.o)) -o demo

 

第1行生成server可执行文件,在link的时候,先将read_test.o demo.o排除掉。

第2行生成read_test可执行文件,在link的时候,先将server.o demo.o排除掉。

第3行生成demo可执行文件,在link的时候,先将server.o read_test.o排除掉。

 

 

1、http://www.gnu.org/software/make/manual/make.html

分享到:
评论

相关推荐

    makefile基础知识.pdf

    "makefile基础知识" Makefile 是一种自动化编译工具,常用于大型开发项目的管理和维护。它可以将复杂的开发项目分解成多个易于管理的模块,並高效地处理源文件之间的复杂关系。 Makefile 的主要功能是描述源程序...

    跟我一起学Makefile.pdf

    跟我一起学Makefile.pdf Makefile是嵌入式工程师开发必备的经典教程,以下是从文件中提取的相关知识点: 1. 关于程序的编译和链接:Makefile的主要作用是自动化编译和链接过程,使得开发者可以更方便地管理项目。 ...

    Makefile 多目录编译Demo

    在编程世界中,Makefile是一个极其重要的工具,它允许开发者自动化构建项目,特别是当项目包含多个目录和大量源代码文件时。"Makefile 多目录编译Demo"着重讲解了如何在复杂的项目结构中有效利用Makefile进行编译。...

    韦东山通用Makefile文件

    本程序的Makefile分为3类: 1. 顶层目录的Makefile 2. 顶层目录的Makefile.build 3. 各级子目录的Makefile 一、各级子目录的Makefile: 它最简单,形式如下: EXTRA_CFLAGS := CFLAGS_file.o := obj...

    跟我一起写makefile.pdf

    Makefile编译和链接基础知识 Makefile是 Unix 和 Unix-like 操作系统中一种工具,用于自动编译和链接程序。Makefile 文件中包含了一系列规则,指定了编译和链接的过程。下面将详细介绍 Makefile 的基本概念和使用...

    Makefile基础知识学习 很好 肯定能学会

    ### Makefile基础知识详解 #### 第一部分:概述 Makefile是一种用于描述如何构建程序或文档的脚本文件。它被广泛应用于软件开发过程中,用来管理项目的编译和链接过程。通过Makefile,开发者可以轻松地组织复杂的...

    跟我一起写Makefile.pdf

    《跟我一起写Makefile》是陈皓大佬撰写的一份PDF文档,主要讲解了如何编写和理解Makefile,以便于管理程序的编译和链接过程。Makefile是软件开发中的一个重要工具,它帮助自动化构建过程,使得编译和链接更加高效。 ...

    跟我一起写Makefile[陈皓]

    make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样...

    codeblocks工程转makefile

    然而,有些情况下,开发者可能希望脱离IDE,直接使用命令行工具如`make`来编译项目,这时就需要将CodeBlocks的工程文件转换为`makefile`。`makefile`是一个文本文件,它包含了构建项目的规则和指令,使得编译过程...

    Makefile手册_中文版.pdf

    Makefile是Linux系统下的一种构建工具,它定义了程序编译和链接的所有规则,使得开发人员能够通过一个简单的命令make来自动构建可执行程序。Makefile手册为读者提供了全面的Makefile使用指南,介绍其语法、编写规则...

    跟我一起学Makefile(PDF版)

    《跟我一起学Makefile》是由陈皓撰写,祝冬华整理的一本关于Makefile学习的PDF教程。Makefile是软件构建过程中的重要工具,尤其在C、C++等编程语言中,它能自动化编译、链接等步骤,提高开发效率。这本书主要针对想...

    Makefile自动构建方法

    ### Makefile自动构建方法 #### 一、概述 在Linux平台下,Makefile是一种非常重要的自动化构建工具,它能够帮助开发者高效地管理项目构建过程。本文档将详细介绍如何使用Makefile进行自动构建,并通过一个简单的...

    跟我一起学makefile.pd

    ### 跟我一起学Makefile #### 第一部分:概述 **Makefile**是一种用于自动化构建过程的脚本文件,在软件开发过程中极为常见。通过定义一系列规则和指令,Makefile可以自动化地完成编译、链接等任务,极大地提高了...

    linux内核kbuild Makefile详解

    2. **kbuild架构**:kbuild由一系列的Makefile组成,包括顶级的`Makefile`、`Rules.make`、`Kbuild`等,以及每个子目录中的`Kconfig`和`Makefile`。`Kconfig`用于配置内核选项,而`Makefile`则定义了如何构建目标。 ...

    跟我一起写Makefile

    ### 跟我一起写Makefile #### 第一部分:概述 Makefile 是一种用于自动化构建过程的脚本文件,主要用于 Linux 和 Unix 类操作系统中。它能够帮助开发者通过编写一系列指令来自动化编译、链接和安装等操作,极大地...

    Makefile写法及自动化工具

    Makefile是Unix/Linux环境下用于自动化构建、编译和链接程序的重要工具。它允许开发者通过定义一系列规则来指示编译过程,从而极大地简化了大型项目中管理多个源文件的复杂性。在【标题】"Makefile写法及自动化工具...

    Makefile 中文教程.pdf

    Makefile 中文教程.pdf Makefile 作为一个自动化编译工具,在软件开发过程中扮演着非常重要的角色。Makefile 的主要作用是根据源代码文件生成目标文件,实现自动化编译和链接的过程。 Makefile 的基本概念 ...

    Makefile文件例程于工程模板

    Makefile是Unix/Linux环境下自动化构建工具的核心,它用于编译、链接和其他构建过程,通过预定义的规则将源代码转化为可执行程序或库。在这个"Makefile文件例程于工程模板"压缩包中,提供了6个逐步进阶的Makefile...

Global site tag (gtag.js) - Google Analytics