`

我使用过的Linux命令之make - 强大的编译工具

阅读更多

我使用过的Linux命令之make - 强大的编译工具

本文链接:http://codingstandards.iteye.com/blog/969924   (转载请注明出处)

 

用途说明

make命令是一个常用的编译命令,尤其是在开发C/C++程序时,它通过Makefile文件中描述的源程序之间的依赖关系来自动进行编译。Makefile文件是按照规定的格式编写的,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。在首次执行make时,会将所有相关的文件都进行编译,而在以后make时,通常是进行增量编译,即只对修改过的源代码进行编译。许多Tarball格式的开源软件,在解压之后,一般先执行./configure,然后执行make,再执行make install进行安装。在进行Java编译时,我们常用的是ant,这个ant工具的发明乃是由于James被makefile的特殊格式弄烦了,采用XML格式来描述任务之间的关系,但是ant工具借鉴了make工具的做法这是肯定的。

man make 写道
The purpose of the make utility is to determine automatically which pieces of a large program need to be recom-
piled, and issue the commands to recompile them. The manual describes the GNU implementation of make, which
was written by Richard Stallman and Roland McGrath, and is currently maintained by Paul Smith. Our examples
show C programs, since they are most common, but you can use make with any programming language whose compiler
can be run with a shell command. In fact, make is not limited to programs. You can use it to describe any
task where some files must be updated automatically from others whenever the others change.

To prepare to use make, you must write a file called the makefile that describes the relationships among files
in your program, and the states the commands for updating each file. In a program, typically the executable
file is updated from object files, which are in turn made by compiling source files.

Once a suitable makefile exists, each time you change some source files, this simple shell command:

make

suffices to perform all necessary recompilations. The make program uses the makefile data base and the last-
modification times of the files to decide which of the files need to be updated. For each of those files, it
issues the commands recorded in the data base.

make executes commands in the makefile to update one or more target names, where name is typically a program.
If no -f option is present, make will look for the makefiles GNUmakefile, makefile, and Makefile, in that
order.

Normally you should call your makefile either makefile or Makefile. (We recommend Makefile because it appears
prominently near the beginning of a directory listing, right near other important files such as README.) The
first name checked, GNUmakefile, is not recommended for most makefiles. You should use this name if you have a
makefile that is specific to GNU make, and will not be understood by other versions of make. If makefile is
‘-’, the standard input is read.

make updates a target if it depends on prerequisite files that have been modified since the target was last
modified, or if the target does not exist.

使用make进行编译的关键点就是掌握makefile的编写规则,make的手册页中说道,makefile文件可以是GNUmakefile, makefile或者Makefile,但是推荐使用Makefile,因为在列出某个目录的文件时,使用Makefile作为文件名时将被排在前面。makefile文件也像C/C++代码一样支持include方式,即把一些基本的依赖规则写在一个公共的文件中,然后其他makefile文件包含此文件。我所使用的公共makefile文件名为common.mk,是多年以前从一个高人那儿拷贝而来的,现在贡献给大家。里面有些晦涩难懂的makefile指令,但是对于使用者来说可以不必关注。思路就是将makefile所在目录的源程序找出来,然后按照依赖关系进行编译。

common.mk 写道
#This is the common part for makefile

SOURCE := $(wildcard *.c) $(wildcard *.cc) $(wildcard *.cpp)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SOURCE))))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
CPPFLAGS += -MD

.PHONY : everything objs clean veryclean vc rebuild ct rl

everything : $(TARGETS)

objs : $(OBJS)

clean :
@$(RM) *.o
@$(RM) *.d

veryclean: clean
@$(RM) $(TARGETS)
@$(RM) cscope.out
@$(RM) core*

vc: veryclean

ct:
@$(RM) $(TARGETS)

rl: ct everything

rebuild: veryclean everything

ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
@$(RM) $(patsubst %.d,%.o,$@)
endif

-include $(DEPS)

怎么来使用这个common.mk来帮助我们编写makefile文件呢,首先我们来看一下编译成静态库的情况。见下面文件,其中的libhyfcd.a就是目标静态库文件的名称,INCS定义了依赖的包含文件路径。

makefile 写道
TARGETS = $(BIN1)

BIN1 = libhyfcd.a
BIN1_OBJS = $(OBJS)
BIN1_LIBS =
BIN1_LFLAGS =
INCS = -I.. -I../../hycu2 -I/usr/include/mysql

#CC := g++
CC := gcc
CXX := gcc
CFLAGS := -g $(INCS) -Wall -D_REENTRANT -D__DECLSPEC_SUPPORTED -DOPENSSL_NO_KRB5 #-DNDEBUG
CXXFLAGS := $(CFLAGS)

include common.mk

# $(BIN1) : $(BIN1_OBJS)
# $(CC) -g -o $@ $(BIN1_LFLAGS) $^ $(addprefix -l,$(BIN1_LIBS))

$(BIN1): $(BIN1_OBJS)
ar rcs $@ $^

再来看一下编译成可执行文件的情况。见下面文件,其中msgc就是目标执行文件,BIN1_LIBS是依赖的库。

写道
TARGETS = $(BIN1)

BIN1 = msgc
BIN1_OBJS = $(OBJS)
BIN1_LIBS = curses pthread
BIN1_LFLAGS = #-L../hyfc/lib
INCS = #-I../hyfc

CC := g++
CFLAGS := -g $(INCS) -Wall
#CFLAGS := -g $(INCS) -Wall -DLOG_CHECK
#CFLAGS := -g $(INCS) -Wall #-DNDEBUG
CXXFLAGS := $(CFLAGS)

include /usr/include/hyfc/common.mk

$(BIN1) : $(BIN1_OBJS)
$(CC) -g -o $@ $(BIN1_LFLAGS) $^ $(addprefix -l,$(BIN1_LIBS))

 

补充(2011.08.07):列位看官,如果你关注的是Makefile的语法结构,那么不妨看参考资料【5】《GNU make中文手册》。

 

常用参数

格式:make

使用默认的makefile文件进行编译,按照GNUmakefile, makefile和Makefile的顺序进行查找。编译目标all。

 

格式:make -f makefile.debug

使用指定的makefile进行编译,此处就是makefile.debug。编译目标all。

 

格式:make install

编译目标install。通常用于安装软件。

 

格式:make clean

编译目标clean。通常用于清除目标文件.o。

 

格式:make veryclean

编译目标clean。通常用于清除目标文件.o以及执行文件等,意思是干净的清除掉除makefile和源程序之外的文件。

 

 

格式:make rl

编译目标rl。rl是relink的缩写,即重新链接,常用于某个依赖的库文件发生变化时强制重新链接生成执行文件。

 

使用示例

示例一 编译安装mysql++2.3.2的过程

[root@jfht setup]# ls mysql++-2.3.2.tar.gz
mysql++-2.3.2.tar.gz
[root@jfht setup]# tar zxf mysql++-2.3.2.tar.gz
[root@jfht setup]# cd mysql++-2.3.2
[root@jfht mysql++-2.3.2]# ./configure --prefix=/usr
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
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 ANSI C... none needed
checking for ranlib... ranlib
checking for a BSD-compatible install... /usr/bin/install -c
checking whether ln -s works... yes
checking whether make sets $(MAKE)... yes
checking for ar... ar
checking for strip... strip
checking for nm... nm
checking if make is GNU make... yes
checking for dependency tracking method... gcc
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ANSI C... (cached) none needed
checking how to run the C preprocessor... gcc -E
checking for egrep... 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 zlib.h usability... yes
checking zlib.h presence... yes
checking for zlib.h... yes
checking for gzread in -lz... yes
checking whether -lm is needed to use C math functions... no
checking whether -lsocket is needed... no
checking whether -lnsl is needed... no
checking for MySQL library directory... /usr/lib
checking for MySQL include directory... /usr/include/mysql
checking for mysql_store_result in -lmysqlclient... yes
checking for mysql_ssl_set in -lmysqlclient... yes
checking for localtime_r()... yes
checking for main in -lintl... no
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for STL slist extension... <ext/slist>, namespace __gnu_cxx
configure: creating ./config.status
config.status: creating Makefile
config.status: creating mysql++.spec
config.status: creating lib/Doxyfile
config.status: creating lib/mysql++.h
config.status: creating config.h
[root@jfht mysql++-2.3.2]# make && make install

此处省略较多输出。

/usr/bin/install -c -d /usr/lib
/usr/bin/install -c -m 644 libmysqlpp.so /usr/lib
/usr/bin/install -c libmysqlpp.so.2.3.2 /usr/lib
(cd /usr/lib ; rm -f libmysqlpp.so libmysqlpp.so.2; ln -s libmysqlpp.so.2.3.2 libmysqlpp.so.2; ln -s libmysqlpp.so.2 libmysqlpp.so)
/usr/bin/install -c -d /usr/include/mysql++
(cd . ; /usr/bin/install -c -m 644  lib/*.h /usr/include/mysql++)
[root@jfht mysql++-2.3.2]#

 

示例二 使用common.mk进行编译的例子

[root@jfht src]# make
make: Nothing to be done for `everything'.
[root@jfht src]# make clean
[root@jfht src]# make
g++ -g  -Wall  -MD  -c -o compiler.o compiler.cpp
g++ -g  -Wall  -MD  -c -o file_updater.o file_updater.cpp
g++ -g  -Wall  -MD  -c -o file_util.o file_util.cpp
g++ -g  -Wall  -MD  -c -o gen_async.o gen_async.cpp
g++ -g  -Wall  -MD  -c -o gen_c.o gen_c.cpp
g++ -g  -Wall  -MD  -c -o gen_cpp.o gen_cpp.cpp
g++ -g  -Wall  -MD  -c -o gen_fmdo2.o gen_fmdo2.cpp
g++ -g  -Wall  -MD  -c -o gen_fmdo.o gen_fmdo.cpp
g++ -g  -Wall  -MD  -c -o gen_hyfc.o gen_hyfc.cpp
g++ -g  -Wall  -MD  -c -o gen_hyfcw.o gen_hyfcw.cpp
g++ -g  -Wall  -MD  -c -o gen_java.o gen_java.cpp
g++ -g  -Wall  -MD  -c -o gen_jdom.o gen_jdom.cpp
g++ -g  -Wall  -MD  -c -o gen_jt.o gen_jt.cpp
g++ -g  -Wall  -MD  -c -o gen_jxh.o gen_jxh.cpp
g++ -g  -Wall  -MD  -c -o gen_pas.o gen_pas.cpp
g++ -g  -Wall  -MD  -c -o gen_php.o gen_php.cpp
g++ -g  -Wall  -MD  -c -o gen_struts.o gen_struts.cpp
g++ -g  -Wall  -MD  -c -o gen_tag.o gen_tag.cpp
g++ -g  -Wall  -MD  -c -o gen_udpsw.o gen_udpsw.cpp
g++ -g  -Wall  -MD  -c -o gen_wsdl.o gen_wsdl.cpp
g++ -g  -Wall  -MD  -c -o gen_xml.o gen_xml.cpp
g++ -g  -Wall  -MD  -c -o msgc.o msgc.cpp
g++ -g  -Wall  -MD  -c -o string_util.o string_util.cpp
g++ -g -o msgc  compiler.o file_updater.o file_util.o gen_async.o gen_c.o gen_cpp.o gen_fmdo2.o gen_fmdo.o gen_hyfc.o gen_hyfcw.o gen_java.o gen_jdom.o gen_jt.o gen_jxh.o gen_pas.o gen_php.o gen_struts.o gen_tag.o gen_udpsw.o gen_wsdl.o gen_xml.o msgc.o string_util.o -lcurses -lpthread
cp -af msgc /usr/bin
cp -af msgc msgc.`uname -r`
[root@jfht src]# make rl
g++ -g -o msgc  compiler.o file_updater.o file_util.o gen_async.o gen_c.o gen_cpp.o gen_fmdo2.o gen_fmdo.o gen_hyfc.o gen_hyfcw.o gen_java.o gen_jdom.o gen_jt.o gen_jxh.o gen_pas.o gen_php.o gen_struts.o gen_tag.o gen_udpsw.o gen_wsdl.o gen_xml.o msgc.o string_util.o -lcurses -lpthread
cp -af msgc /usr/bin
cp -af msgc msgc.`uname -r`
[root@jfht src]#

 

问题思考

1. 很多自由软件中使用的Makefile是由autoconf和automake来生成的,怎么使用法?

2. Makefile中一些常见的指令的含义如何?

 

相关资料

【1】LinuxSky Linux平台Makefile文件的编写基础篇
http://www.linuxsky.org/doc/dev/200709/117.html
【2】学习在线 Linux/Unix环境下的make命令详解
http://www.3648.com/article/sort01/sort021/sort086/info-2667.html
【3】鸟哥的Linux私房菜 第二十二章、軟體安裝:原始碼與 Tarball
http://linux.vbird.org/linux_basic/0520source_code_and_tarball.php#make
【4】新浪学园 Linux下Makefile的automake生成全攻略
http://tech.sina.com.cn/s/2004-10-19/1115443045.shtml

【5】GNU make中文手册

http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/index.html#content

 

 

返回 我使用过的Linux命令系列总目录

 

0
0
分享到:
评论

相关推荐

    aarch64-himix210-linux 交叉编译工具包

    交叉编译工具链包括了编译器(如GCC)、链接器、汇编器等,它们协同工作,将源代码转换为能够在目标平台上运行的二进制文件。在这个工具包中,"aarch64-himix210-linux"这部分标识了工具链是针对aarch64架构的HiMix...

    HP-Socket编译-Linux

    本主题将详细介绍如何在Linux系统上编译和安装HP-Socket,以及与之相关的几个关键依赖库的安装过程。 首先,我们需要了解Linux socket编程的基本概念。Socket是进程间通信的一种方式,它允许两个或多个运行在相同或...

    arm-linux-gnueabihf交叉编译ffmpeg

    2. **arm-linux-gnueabihf**:这是针对ARMv7及更高版本处理器的交叉编译工具链,其中"arm"代表目标架构是ARM,"linux"表示遵循Linux ABI(应用程序二进制接口),"gnueabihf"则表示使用GNU C库并且支持浮点运算,"hf...

    linux wifi工具hostapd编译方法.doc

    Linux WiFi 工具 hostapd 编译方法详解 hostapd 是一个功能强大的 WiFi 工具,能够在 Linux 操作系统上构建无线接入点,支持 IEEE 802.11 协议和 IEEE 802.1X/WPA/WPA2/EAP/RADIUS 加密。为了编译 hostapd,需要...

    windows 安装make (gnu make)

    GNU Make是一个自动化构建工具,它能够读取名为“Makefile”的文件,根据文件中的规则来编译、链接源代码,帮助开发者高效地管理项目构建流程。下面我们将详细介绍如何在Windows环境下安装和使用GNU Make。 1. 获取...

    spice-gtk编译后程序

    4. **编译**:执行 `make` 命令开始编译源代码。 5. **安装**:使用 `sudo make install` 将编译好的程序和库安装到系统目录。 **使用和调试** 编译后的 `spice-gtk` 可能包含以下文件: - `libspice-client-gtk....

    make-4.3.tar.gz

    在Linux操作系统中,`make`是一款强大的自动化构建工具,它能够根据Makefile文件中的规则自动编译和链接程序,极大地提高了开发效率。`make-4.3`是`make`工具的一个版本,我们在此将深入探讨其工作原理、Makefile的...

    linux版jison-c-0.9.tar.zip

    Linux版的Jison-C-0.9是一款专为Unix-like操作系统设计的开源解析器生成工具,主要用于处理JSON(JavaScript Object Notation)数据格式。Jison是基于PHP的JSLint和JSMin的作者Nathan Torkington开发的一个项目,它...

    arm-linux-gcc-4.6.4-arm-x86-64交叉编译器安装包(含详细安装教程)

    - **安装**:使用`sudo make install`将编译好的工具链安装到系统路径中,通常为`/usr/local`。 - **环境变量设置**:更新`PATH`环境变量,使系统能在命令行中找到新安装的交叉编译器。 4. **使用交叉编译器**:...

    windows下面编译linux-0.11内核

    首先,**MinGW32** 是一套在Windows下运行的GNU开发工具集合,它提供了与GCC(GNU Compiler Collection)兼容的编译器和链接器,使得开发者能够在Windows环境下使用类似于Linux的命令行工具来编译C和C++代码。...

    用arm-linux-gcc交叉编译 openssl zlib curl

    # 修改Makefile中的编译工具 CC=/opt/FriendlyARM/toolschain/4.4.3/bin/arm-linux-gcc CFLAGS=-O3 -D_LARGEFILE64_SOURCE=1 SFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1 LDSHARED=/opt/FriendlyARM/toolschain/...

    GNU make-3.79.1.tar.gz

    GNU make 是一个强大的自动化构建工具,它在软件开发过程中扮演着至关重要的角色。这个压缩包“GNU make-3.79.1.tar.gz”包含了GNU make的3.79.1版本源代码,允许用户在自己的系统上编译和安装这款软件。 1. **GNU ...

    linux-0.11-devel-040809.rar

    本文将深入探讨一个基于Linux 0.11版本的开发环境构建过程,以及其中包含的关键组件和工具,如nasm汇编器和Bochs模拟器的使用。 首先,"linux-0.11-devel-040809.rar"这个文件名揭示了我们关注的核心内容:Linux ...

    make-4.3-without-guile-w32-bin-2.zip

    其中,`make` 是一个广泛使用的命令行工具,尤其在Unix/Linux环境中。然而,随着跨平台开发的需求增加,`make` 也在Windows系统中得到了应用。本文将详细介绍`make-4.3 without Guile w32-bin`在Windows环境下的构建...

    内网环境下Linux环境gcc gcc-c++编译器安装所需依赖

    在Linux上编译Nginx源代码时,首先需要确保系统已经安装了必要的编译工具,其中最主要的就是GCC和G++。 在Linux环境中,通常使用包管理器来安装依赖。在Red Hat系列的Linux发行版(如CentOS、Fedora)中,我们可以...

    make-3.81.zip

    `make`是软件开发中的一个强大工具,尤其在Unix/Linux环境下广泛使用,用于自动化编译、链接等构建过程。`make-3.81.zip`是GNU `make`的一个版本,它是在gnuwin32官网上下载的,为Windows环境提供了兼容性。在这里,...

    linux libosip2-3.5.0 libeXosip2-3.5.0 源码及编译动态库

    3. **编译**:运行`make`命令,编译源码生成目标文件和库文件。 4. **安装**:使用`sudo make install`将编译好的库文件安装到系统的标准库路径,通常是/usr/local/lib。 5. **配置依赖**:确保所有依赖项已安装,...

    EasyDarwin-linux-8.1.0-1901141151.tar.gz.zip

    首先,确保你的系统已安装必要的编译工具,如GCC、Make等。然后,按照以下步骤进行编译: 1. 执行`make clean`清除之前可能存在的编译残留。 2. 使用`make`命令开始编译过程。如果一切顺利,编译完成后,会生成可...

    Linux5.10内核:linux-dovetail-v5.10.76-dovetail3.tar.gz

    在使用这个压缩包时,首先需要解压"linux-dovetail-v5.10.76-dovetail3",这通常可以通过tar命令完成。解压后,用户将得到完整的内核源码,包括Xenomai的集成。然后,开发者或系统管理员需要按照Xenomai的构建指南...

    linux 离线安装perl-IPC-Cmd

    在Linux环境中,Perl是一种强大的脚本编程语言,广泛用于系统管理、网络编程和文本处理等任务。`perl-IPC-Cmd`是Perl的一个模块,它提供了执行外部命令并捕获其输出的功能。离线安装Perl模块在没有互联网连接或者...

Global site tag (gtag.js) - Google Analytics