`
lobin
  • 浏览: 382307 次
  • 性别: 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[陈皓]

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

    跟我一起写 Makefile_(PDF 重制版).rar

    什么是 makefile?或许很多 Windows 的程序员都不知道这个东西,因为那些 Windows 的集成开发 环境(integrated development environment,IDE)都为你做了这个工作,但我觉得要作一个好的和专业 的程序员,makefile...

    跟我一起写 Makefile &#40;PDF 重制版&#41;

    什么是 makefile?或许很多 Winodws 的程序员都不知道这个东西,因为那些 Windows 的集成开 发环境(integrated development environment,IDE)都为你做了这个工作,但我觉得要作一个好的 和专业的程序员,makefile...

    Makefile笔记.zip

    什么是 makefile?或许很多 Windows 的程序员都不知道这个东西,因为那些 Windows 的集成开 发环境(integrated development environment,IDE)都为你做了这个工作,但我觉得要作一个好的 和专业的程序员,makefile...

    Makefile教程-经典

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但...

    makefile的写法makefile的写法

    我们首先看一个简单的makefile: CC = g++ OBJS = main.o base.o derive.o EXEC = test $(EXEC): $(OBJS) $(CC) -o $@ $^ main.o: main.cpp base.h derive.h $(CC) -c $ base.o: base.cpp base.h $(CC) -c...

    Makefile手册中文版

    Makefile手册中文版,非常详尽的makefile官方文档。

    make和Makefile详解 一起写Makefile

    在linux中, GNU make 工具在当前工作目录中按照GNUmakefile、makefile、Makefile的顺序搜索 makefile文件。  -i 忽略命令执行返回的出错信息。  -s 沉默模式,在执行之前不输出相应的命令行信息。  -r 禁止使用...

    一个通用Makefile的编写

    我们在Linux环境下开发程序,少不了要自己编写Makefile,一个稍微大一些的工程下面都会包含很多.c的源文件。如果我们用gcc去一个一个编译每一个源文件的话,效率会低很多,但是如果我们可以写一个Makefile,那么只...

    Makefile进阶 Makefile进阶

    Makefile进阶 Makefile进阶 Makefile进阶 Makefile进阶 Makefile进阶 Makefile进阶 Makefile进阶

    makefile基础知识.pdf

    makefile入门讲义,IC必会

    CC++ 通用 Makefile

    本文提供了一个用于对 C/C++ 程序进行编译和连接以产生可执行程序的通用 Makefile。 在使用 Makefile 之前,只需对它进行一些简单的设置即可;而且一经设置,即使以后对源程序文件有所增减一般也不再需要改动 ...

    makefile教程.zip

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但...

    MakeFile教程.pdf

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但...

    Linux的makefile语法规则

    详细易懂的Linux makefile教程 一、概述 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这...

    Makefile 的编写指导

    什么是makefile?或许很多Windows 的程序员都不知道这个东西,因为那些Windows 的IDE 都为你做了这个工作,但我觉得 要作一个好的和professional 的程序员,makefile 还是要懂。这就好像现在有这么多的HTML 的编辑器...

    跟我一起写makefile.rar

    特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。 因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、...

    gnu_makefile文档pdf html

    2 Makefile文件介绍 2.1 规则的格式 2.2一个简单的Makefile文件 2.3make处理Makefile文件的过程 2.4使用变量简化Makefile文件 2.5让make推断命令 2.6另一种风格的Makefile文件 2.7在目录中删除文件的规则 3 ...

    韦东山通用Makefile文件

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

    跟我一起写makefile

    什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但...

Global site tag (gtag.js) - Google Analytics