Linux make --强大的编译工具

2023-11-05

用途说明

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

man make 写道

The purpose of themake utility is to determine automatically which pieces of a large program needto be recom-

piled, and issue thecommands to recompile them. The manual describes the GNU implementation ofmake, which

was written byRichard 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 languagewhose compiler

can be run with ashell command. In fact, make is not limited to programs. You can use it todescribe any

task where somefiles must be updated automatically from others whenever the others change.

 

To prepare to usemake, you must write a file called the makefile that describes therelationships among files

in your program, andthe states the commands for updating each file. In a program, typically theexecutable

file is updated fromobject files, which are in turn made by compiling source files.

 

Once a suitablemakefile exists, each time you change some source files, this simple shellcommand:

 

make

 

suffices to performall necessary recompilations. The make program uses the makefile data base andthe last-

modification timesof the files to decide which of the files need to be updated. For each of thosefiles, it

issues the commandsrecorded in the data base.

 

make executescommands in the makefile to update one or more target names, where name istypically a program.

If no -f option ispresent, make will look for the makefiles GNUmakefile, makefile, and Makefile,in that

order.

 

Normally you shouldcall your makefile either makefile or Makefile. (We recommend Makefile becauseit appears

prominently near thebeginning of a directory listing, right near other important files such asREADME.) The

first name checked,GNUmakefile, is not recommended for most makefiles. You should use this name ifyou have a

makefile that isspecific to GNU make, and will not be understood by other versions of make. Ifmakefile is

‘-’, the standardinput is read.

 

make updates atarget if it depends on prerequisite files that have been modified since thetarget was last

modified, or if thetarget 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 commonpart 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 : everythingobjs 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: verycleaneverything

 

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 = cursespthread

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】《GNUmake中文手册》。

 

常用参数

格式:make

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

 

格式:make -fmakefile.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@jfhtmysql++-2.3.2]# ./configure --prefix=/usr

checking buildsystem type... i686-pc-linux-gnu

checking host systemtype... i686-pc-linux-gnu

checking targetsystem type... i686-pc-linux-gnu

checking for gcc...gcc

checking for Ccompiler default output file name... a.out

checking whether theC compiler works... yes

checking whether weare cross compiling... no

checking for suffixof executables...

checking for suffixof object files... o

checking whether weare using the GNU C compiler... yes

checking whether gccaccepts -g... yes

checking for gccoption to accept ANSI C... none needed

checking forranlib... ranlib

checking for aBSD-compatible install... /usr/bin/install -c

checking whether ln-s works... yes

checking whethermake sets $(MAKE)... yes

checking for ar...ar

checking forstrip... strip

checking for nm...nm

checking if make isGNU make... yes

checking fordependency tracking method... gcc

checking for gcc...(cached) gcc

checking whether weare using the GNU C compiler... (cached) yes

checking whether gccaccepts -g... (cached) yes

checking for gccoption to accept ANSI C... (cached) none needed

checking how to runthe C preprocessor... gcc -E

checking foregrep... grep -E

checking for ANSI Cheader files... yes

checking forsys/types.h... yes

checking forsys/stat.h... yes

checking forstdlib.h... yes

checking forstring.h... yes

checking formemory.h... yes

checking forstrings.h... yes

checking forinttypes.h... yes

checking forstdint.h... yes

checking forunistd.h... yes

checking zlib.husability... yes

checking zlib.hpresence... yes

checking forzlib.h... yes

checking for gzreadin -lz... yes

checking whether -lmis needed to use C math functions... no

checking whether-lsocket is needed... no

checking whether-lnsl is needed... no

checking for MySQLlibrary directory... /usr/lib

checking for MySQLinclude directory... /usr/include/mysql

checking formysql_store_result in -lmysqlclient... yes

checking formysql_ssl_set in -lmysqlclient... yes

checking forlocaltime_r()... yes

checking for main in-lintl... no

checking for g++...g++

checking whether weare using the GNU C++ compiler... yes

checking whether g++accepts -g... yes

checking for STLslist 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@jfhtmysql++-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 -clibmysqlpp.so.2.3.2 /usr/lib

(cd /usr/lib ; rm -flibmysqlpp.so libmysqlpp.so.2; ln -s libmysqlpp.so.2.3.2 libmysqlpp.so.2; ln -slibmysqlpp.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@jfhtmysql++-2.3.2]#

 

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

[root@jfht src]# make

make: Nothing to bedone 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.ogen_fmdo.o gen_hyfc.o gen_hyfcw.o gen_java.o gen_jdom.o gen_jt.o gen_jxh.ogen_pas.o gen_php.o gen_struts.o gen_tag.o gen_udpsw.o gen_wsdl.o gen_xml.o msgc.ostring_util.o -lcurses -lpthread

cp -af msgc /usr/bin

cp -af msgcmsgc.`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.ogen_fmdo.o gen_hyfc.o gen_hyfcw.o gen_java.o gen_jdom.o gen_jt.o gen_jxh.ogen_pas.o gen_php.o gen_struts.o gen_tag.o gen_udpsw.o gen_wsdl.o gen_xml.o msgc.ostring_util.o -lcurses -lpthread

cp -af msgc /usr/bin

cp -af msgcmsgc.`uname -r`

[root@jfht src]#


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux make --强大的编译工具 的相关文章

随机推荐

  • 【汽车电子】浅谈汽车四大总线:LIN、CAN、FlexRay、MOST

    目录 1 前言 2 汽车四大总线 2 1 LIN总线 2 1 1 LIN总线概述 2 1 2 LIN总线工作原理 2 2 CAN总线 2 2 1 CAN总线概述 2 2 2 CAN总线工作原理 2 2 3 CAN总线的优点 2 3 Flex
  • 【前端

    图 先看一个例子 html div class container div class item 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
  • js逆向--有道翻译

    目录 1 前言 2 起因 3 经过 4 结果 1 前言 分类 js逆向 语言 python 2 起因 记录一下js逆向入门案例 3 经过 分析案例 有道翻译是通过ajax的post请求获得的响应结果 打开开发者工具获取post请求时需要提交
  • Ubuntu16.04上升级NVIDIA显卡驱动及安装CUDA10.0操作步骤

    Ubuntu 16 04上已装有CUDA 8 0 现在想再安装CUDA 10 0 由于已安装的显卡驱动版本396 54不支持CUDA 10 0 因此安装CUDA 10 0之前需要先升级显卡驱动到410及以上版本 可在https docs n
  • python输出日志到文件_python将print输出的信息保留到日志文件中

    具体代码如下所示 import sys import os import sys import io import datetime def create detail day return 年 月 日 daytime datetime d
  • 通过白噪声的频谱处理产生任意光谱斜率(f^a)噪声(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章讲解 1 概述 文献来源 摘要 本文研究了具有任意谱
  • 前端例程20220815:拟物风格复选按钮

    演示 原理 本文要实现的按钮大致示意如下 观察者从正上方观看 写代码时主要处理光照以及近大远小等现象 代码
  • 【css】将背景图片设置到元素的右上角

    p 科学熊 将背景图片设置到body元素的右上角 p 效果 background repeat no repeat 设置背景是否重复显示 no repeat为不重复 r
  • java POI解析获取word文件内容

    1 需要的pom文件依赖
  • 微信小程序一键授权之前勾选协议

    微信小程序授权获取手机号之前勾选我已阅读并同意协议 想要实现的效果 用户点击微信一键注册按钮 如果用户没有勾选协议 就提示请勾选用户协议 如果勾选了 就直接获取微信用户的手机号密文 开始想的是直接在getPhoneNumber 方法中加一个
  • python同时发大量请求_PythonWebServer如何同时处理多个请求

    对于初学Web开发 理解一个web server如何能同事处理多个请求很重要 当然更重要的是 理解你通过浏览器发送的请求web server是怎么处理的 然后怎么返回给浏览器 浏览器才能展示的 我到现在还记得大概在2010年左右 看了tom
  • 高德地图的缩放和位移监听

    最近项目采用高德地图 高德地图的文档 demo都很详细 想实现的功能基本上都有 在项目里有一个功能 是类似根据地图的中心经纬度实现数据请求 为了不无限的请求 所以要分别监听 地图的缩放 地图位移 这里就有一个方法 gadMap setOnC
  • matlab根据成绩划分等级_Excel数据分析必备技能:对数据按范围多条件划分等级的判定套路

    点击右上角 关注 每天免费获取干货教程 职场办公中经常要对数据进行整理和分析 其中等级归类划分是很常用的一种方法 在这个过程中用好Excel公式可以事半功倍 但是还是有很多人不了解在Excel中对数据按范围多条件划分等级的系统思路和方法 所
  • Cover Letter常用范式和模版

    摘自 https zhuanlan zhihu com p 26708261 http muchong com html 201401 6920446 html 1 什么是Cover letter Cover Letter 即投稿信 是论文
  • 深聊测开领域之:测试策略模型有哪些?

    测试模型的分类 1 引言 2 金字塔 2 1 金字塔模型 引入 2 2 金字塔弊端 2 3 金字塔图形 3 冰淇淋 3 1 冰淇淋模型 引入 3 2 冰淇淋模型 优缺点 3 2 1 缺点 3 2 2 优点 3 2 冰淇淋图形 4 冠军杯 4
  • 微信小程序面试题汇总

    HTML篇 CSS篇 JS篇 Vue篇 TypeScript篇 React篇 前端面试题汇总大全 含答案超详细 HTML JS CSS汇总篇 持续更新 前端面试题汇总大全二 含答案超详细 Vue TypeScript React Webpa
  • 环境变量知识点

    环境变量 环境变量 环境变量是用来定义系统运行环境的一些参数 比如说 每一个用户的家目录 echo HOME 还有我们在编写C C 代码的时候 在链接的时候 从来不知道我们的所链接的动态静态库在哪里 但是照样可以链接成功 生成可执行程序 原
  • 不使用采集卡,实现相机手机多机位直播

    背景 因为直播需求 现在想实现使用一台相机和一台手机完成直播的两个机位设定 搜了很多视频都是要购买采集卡 违背了性价比这一原则 搜索半天之后 根据当前的设备完成了任务 硬件材料 苹果手机一部 佳能单反 所需软件 1 OBS 主要是用来集成各
  • 刷脸让商家引入智慧经营实现数字化转型

    移动支付在生活中已经实现了全覆盖 从单一的支付到驱动智慧经营 在数据为王的时代 通过对移动支付数据的深度挖掘 整合成消费大数据 移动支付还在经营上改变商户的效率 从以前柜台结账到如今的自助结账 从人工推荐到大数据的精准推荐 彻底的改变了商户
  • Linux make --强大的编译工具

    用途说明 make命令是一个常用的编译命令 尤其是在开发C C 程序时 它通过Makefile文件中描述的源程序之间的依赖关系来自动进行编译 Makefile文件是按照规定的格式编写的 文件中需要说明如何编译各个源文件并连接生成可执行文件