-
Makefile: 函数 https://www.iteye.com/blog/lobin-2517113
make
Makefile
Makefile包含规则(explicit rules, 显式规则以及implicit rules, 隐式规则),变量定义(variable definitions), 指令(directives), 以及注释(comments)五类东西。
一个Makefile可以不包含上面的任何东西,比如一个空的Makefile文件。或者只包含一些变量定义,指令,注释等,可以不包含规则。
执行make默认在当前目录下加载Makefile文件并解释执行第1个规则。
可以指定-f FILE, --file=FILE或者--makefile=FILE加载指定的Makefile文件。
Read FILE as a makefile.
还可以指定-C DIRECTORY, --directory=DIRECTORY转到指定目录加载Makefile文件。
Change to DIRECTORY before doing anything.
>make
/cygdrive/d/usr/bin/git/bin/echo: line 7: $'\r': command not found
在Cygwin控制台下执行就不会有这种问题:
>make
Rule
即规则,
tab recipes
tab recipe 1
tab recipe 2
tab recipe 3
tab ...
tab recipe n
Target
即目标,
Phony
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”
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 system.mk
define
define var1 this is \ \ var 1 endef start: @echo $(var1)
override
conditional
条件判断
text-if-true
endif
if...else...endif
ifeq ($(var),c)
...
else
...
endif
text-if-true
else
text-if-false
endif
if...else if...else...endif
ifeq ($(var),a)
...
else ifeq ($(var),b)
...
else
...
endif
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"
ifneq 'arg1' 'arg2'
ifneq "arg1" "arg2"
ifneq "arg1" 'arg2'
ifneq 'arg1' "arg2"
使用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文件。
# 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
需要根据需要进行一些修改。
# 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文件
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基础知识" Makefile 是一种自动化编译工具,常用于大型开发项目的管理和维护。它可以将复杂的开发项目分解成多个易于管理的模块,並高效地处理源文件之间的复杂关系。 Makefile 的主要功能是描述源程序...
跟我一起学Makefile.pdf Makefile是嵌入式工程师开发必备的经典教程,以下是从文件中提取的相关知识点: 1. 关于程序的编译和链接:Makefile的主要作用是自动化编译和链接过程,使得开发者可以更方便地管理项目。 ...
在编程世界中,Makefile是一个极其重要的工具,它允许开发者自动化构建项目,特别是当项目包含多个目录和大量源代码文件时。"Makefile 多目录编译Demo"着重讲解了如何在复杂的项目结构中有效利用Makefile进行编译。...
本程序的Makefile分为3类: 1. 顶层目录的Makefile 2. 顶层目录的Makefile.build 3. 各级子目录的Makefile 一、各级子目录的Makefile: 它最简单,形式如下: EXTRA_CFLAGS := CFLAGS_file.o := obj...
Makefile编译和链接基础知识 Makefile是 Unix 和 Unix-like 操作系统中一种工具,用于自动编译和链接程序。Makefile 文件中包含了一系列规则,指定了编译和链接的过程。下面将详细介绍 Makefile 的基本概念和使用...
### Makefile基础知识详解 #### 第一部分:概述 Makefile是一种用于描述如何构建程序或文档的脚本文件。它被广泛应用于软件开发过程中,用来管理项目的编译和链接过程。通过Makefile,开发者可以轻松地组织复杂的...
《跟我一起写Makefile》是陈皓大佬撰写的一份PDF文档,主要讲解了如何编写和理解Makefile,以便于管理程序的编译和链接过程。Makefile是软件开发中的一个重要工具,它帮助自动化构建过程,使得编译和链接更加高效。 ...
make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样...
然而,有些情况下,开发者可能希望脱离IDE,直接使用命令行工具如`make`来编译项目,这时就需要将CodeBlocks的工程文件转换为`makefile`。`makefile`是一个文本文件,它包含了构建项目的规则和指令,使得编译过程...
Makefile是Linux系统下的一种构建工具,它定义了程序编译和链接的所有规则,使得开发人员能够通过一个简单的命令make来自动构建可执行程序。Makefile手册为读者提供了全面的Makefile使用指南,介绍其语法、编写规则...
在了解Makefile之前,我们首先要明白什么是makefile。Makefile是一种用于程序编译的脚本文件,它描述了整个程序编译和链接的过程,包括哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译等编译规则。在...
《跟我一起学Makefile》是由陈皓撰写,祝冬华整理的一本关于Makefile学习的PDF教程。Makefile是软件构建过程中的重要工具,尤其在C、C++等编程语言中,它能自动化编译、链接等步骤,提高开发效率。这本书主要针对想...
### Makefile自动构建方法 #### 一、概述 在Linux平台下,Makefile是一种非常重要的自动化构建工具,它能够帮助开发者高效地管理项目构建过程。本文档将详细介绍如何使用Makefile进行自动构建,并通过一个简单的...
### 跟我一起学Makefile #### 第一部分:概述 **Makefile**是一种用于自动化构建过程的脚本文件,在软件开发过程中极为常见。通过定义一系列规则和指令,Makefile可以自动化地完成编译、链接等任务,极大地提高了...
### 跟我一起写Makefile #### 第一部分:概述 Makefile 是一种用于自动化构建过程的脚本文件,主要用于 Linux 和 Unix 类操作系统中。它能够帮助开发者通过编写一系列指令来自动化编译、链接和安装等操作,极大地...
Makefile是Unix/Linux环境下用于自动化构建、编译和链接程序的重要工具。它允许开发者通过定义一系列规则来指示编译过程,从而极大地简化了大型项目中管理多个源文件的复杂性。在【标题】"Makefile写法及自动化工具...
Makefile 中文教程.pdf Makefile 作为一个自动化编译工具,在软件开发过程中扮演着非常重要的角色。Makefile 的主要作用是根据源代码文件生成目标文件,实现自动化编译和链接的过程。 Makefile 的基本概念 ...
Makefile 基础教程 Makefile 是一种特殊格式的文件,用于自动构建和管理项目。在 Unix、Linux 及其版本上运行的程序构建工具,帮助简化可能需要各种模块的构建程序可执行文件。Makefile 中定义的规则和依赖关系指导...