热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

linux下Makefile文件的编写

linux下Makefile文件的编写--Linux通用技术-Linux技术与应用信息,下面是详情阅读。
开始使用Linux编程时,一个很讨厌的问题就是如何写Makefile文件,由于在Linux下
不像在Windows下那么熟悉,有那么多好的软件(也许是对Linux孤陋寡闻了)。虽然
象Kylix和Anjuta这样的集成编译环境,但是Kylix太大太慢,用它编写console程序
不亚于高射炮打蚊子——大材小用,而Anjuta又太不稳定,况且字体有那么难看。不
说了,还是言归正传,看看Makefile该如何编写。



1. 简单的GCC语法:

如果你只有一个文件(或者只有几个文件),那么就可以不写Makefile文件(当然有
Makefile更加方便),用gcc直接编译就行了。在这里我们只介绍几个我经常用的几
个参数,第一是 “-o”,它后面的参数表示要输出的目标文件,再一个是 “-c”,
表示仅编译(Compile),不连接(Make),如果没有”-c”参数,那么就表示连接
,如下面的几个命令:

gcc ?c test.c,表示只编译test.c文件,成功时输出目标文件test.o

gcc ?c test.c ?o test.o ,与上一条命令完全相同

gcc ?o test test.o,将test.o连接成可执行的二进制文件test

gcc ?o test test.c,将test.c编译并连接成可执行的二进制文件test

gcc test.c ?o test,与上一条命令相同

gcc ?c test1.c,只编译test1.c,成功时输出目标文件test1.o

gcc ?c test2.c,只编译test2.c,成功时输出目标文件test2.o

gcc ?o test test1.o test2.o,将test1.o和test2.o连接为可执行的二进制文件test


gcc ?c test test1.c test2.c,将test1.o和test2.o编译并连接为可执行的二进制
文件test

注:如果你想编译cpp文件,那么请用g++,否则会有类似如下莫名其妙的错误:

cc3r3i2U.o(.eh_frame+0x12): undefined reference to `__gxx_personality_v0’
......

还有一个参数是”-l”参数,与之紧紧相连的是表示连接时所要的链接库,比如多线
程,如果你使用了pthread_create函数,那么你就应该在编译语句的最后加上”-lpthread
”,”-l”表示连接,”pthread”表示要连接的库,注意他们在这里要连在一起写
,还有比如你使用了光标库curses,那么呢就应该在后面加上”-lcurses”,比如下
面的写法:

gcc ?o test test1.o test2.o ?lpthread ?lcurses

当然gcc的参数我感觉有几百个,不过我们平时在x86机器上用的就这么些,况且这里
也不是GCC教程,所以,就此打住。



2. Makefile基本语法

我这里没有Makefile的详细设计书,只是凭着看别人的Makefile文件和一些网上的参
考资料,作一些简单的介绍(我自己理解的,不对的地方还请各位老大们指出,鄙人
将不甚感激)

2.1 目标:

大家在看别人使用Makefile文件时肯定经常见到有的人常用make all, make install
, make clean等命令,同样只有一个Makefile文件,那么all、install、clean参数
是如何控制Makefile文件的运行呢(这句话有问题,但我不知道该怎么说,大家能看
懂我的意思,就放我一马吧)?在这里,如果向上面的命令如果能够正确运行的话,
那么在Makefile文件里一定有这样的几行,他们的开始一定是

all: ×××××××

×××××××××××

install: ××××××

×××××××××××

clean: ×××××××××

×××××××××××

当然也不尽然,因为all,install,clean我们可以用其他的变量来代替,但是着了
我们就简单起见,就下定论了,各位别怪。

在上面提到的all,install,clean等就是我们所说的目标。make all命令,就告诉
make我们将执行all所指定的目标。为了便于理解Make程序的流程,我们给大家看一
个与gcc毫无关系的Makefile文件:

# #表示Makefile文件中的注释,下面是Makefile文件的具体内容

all:

@echo you have typed command “make all”

clean:

@echo you have typed command “make clean”

install:

@ehco you have typed command “make $@”

#Makefile文件结束

注意在这里,all:、clean:、install:行要顶格些,而所有的@echo前要加tab键来跳
格缩进。下面是运行结果:

[root@xxx test]#cat Makefile

# #表示Makefile文件中的注释,下面是Makefile文件的具体内容

all:

@echo you have typed command “make all”

clean:

@echo you have typed command “make clean”

install:

@ehco you have typed command “make $@”

[root@xxx test]#make all

you have typed command “make all”

[root@xxx test]#make clean

you have typed command “make clean”

[root@xxx test]#make install

you have typed command “make install”

[root@xxx test]#

不知大家注意到没有,我们在Makefile文件里有一个符号$@,其中$表示变量名,其
后的要当作变量来解释,$@是Makefile预先定义的一个变量,表示目标命令,比如在
上面的文件里属于install目标,那么$@就表示install,同样,如果你将clean目标
下面的加引号的”make clean”换为:”make $@”,那么命令make clean的输出与
原来是一摸一样的。大家可以下来试试。

2.2 依赖

我们现在提出这样一个问题:我如何用一个make命令将替代所有的make all, make
install,make clean命令呢?当然我们可以象刚才那样写一个Makefile文件:

[root@xxx test]#cat Makefile

# #表示Makefile文件中的注释,下面是Makefile文件的具体内容

all:

@echo you have typed command “make all”

clean:

@echo you have typed command “make clean”

install:

@ehco you have typed command “make $@”

doall:

@echo you have typed command “make $@l”

@echo you have typed command “make all”

@echo you have typed command “make clean”

@ehco you have typed command “make install”

[root@xxx test]#make doall

you have typed command “make doall”

you have typed command “make all”

you have typed command “make clean”

you have typed command “make install”

[root@xxx test]#

在这里,doall:目标有4调语句,他们都是连在一起并都是由tab键开始的。当然,这
样能够完成任务,但是太笨了,我们这样来写:

[root@xxx test]#cat Makefile

# #表示Makefile文件中的注释,下面是Makefile文件的具体内容

all:

@echo you have typed command “make all”

clean:

@echo you have typed command “make clean”

install:

@ehco you have typed command “make $@”

doall: all clean install

@echo you have typed command “make $@l”

[root@xxx test]#make doall

you have typed command “make all”

you have typed command “make clean”

you have typed command “make install”

you have typed command “make doall”

[root@xxx test]#

相信大家已经看清了doall:的运行方式,它先运行all目标,然后运行clean目标,然
后是install,最后是自己本身的目标,并且每个$@还是保持着各自的目标名称。

在这里,我们称all, clean, install为目标doall所依赖的目标,简称为doall的依
赖。也就是你要执行doall,请先执行他们(all, clean, install),最后在执行我
的代码。

注意依赖一定是Makefile里面的目标,否则你非要运行,结局是注定的:

[root@xxx test]#cat Makefile

all:

@echo you have typed command “make all”

xxx: all WAHAHA:

[root@xxx test]make xxx


you have typed command “make all”

make: *** No rule to make target ‘WAHAHA’, needed by `xxx’, Stop.

【轻松一下】我们能否利于“相互依赖”来作弄一下make?

[root@xxx test]#cat Makefile

tar1: tar2

tar2: tar1

@echo this line cann’t be shown on you screen!

[root@xxx test]make tar1

make: Circular tar2 <- tar1 dependency dropped.

呵呵,骗不了的



3.实战:

有了上面的说明,我们就可以开始写一些弱智一些地Makefile文件了。比如我们有如
下的文件:

tmp/
+---- include/
| +---- f1.h
| +----f2.h
+----f1.c
+----f2.c
+---main.c

其中f1.c中#include “include/f1.h”,f2.c中#include”include/f2.h”,main
.c中又#include”include/f1.h”, #include”include/f2.h”,主函数在main.c中
,要将他们联合起来编译为目标为testmf的文件,我们就可以按下面的方式写(当然
是弱智的):

[root@xxx test]#cat Makefile

main: main.o f1.o f2.o

gcc ?o testmf main.o f1.o f2.o

f1.o: f1.c

gcc ?c ?o file1.o file1.c

f2.o: f2.c

gcc ?c ?o file2.o file2.c

main.o

gcc ?c ?o main.o main.c

clean:

rm ?rf f1.o f2.o main.o testmf

[root@xxx test]make

gcc ?c ?o main.o main.c

gcc ?c ?o file1.o file1.c

gcc ?c ?o file2.o file2.c

gcc ?o testmf main.o f1.o f2.o

[root@xxx test]ls

gcc ?c ?o main.o main.c

gcc ?c ?o file1.o file1.c

gcc ?c ?o file2.o file2.c

gcc ?o testmf main.o f1.o f2.o

[root@xxx test]ls

f1.c f1.o f2.c f2.o main.c main.o include/ testmf

如果你的程序没有问题的话,就应该可以执行了./testmf
推荐阅读
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • windows便签快捷键_用了windows十几年,没想到竟然这么好用!隐藏的功能你知道吗?
    本文介绍了使用windows操作系统时的一些隐藏功能,包括便签快捷键、截图功能等。同时探讨了windows和macOS操作系统之间的优劣比较,以及人们对于这两个系统的不同看法。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文是一位90后程序员分享的职业发展经验,从年薪3w到30w的薪资增长过程。文章回顾了自己的青春时光,包括与朋友一起玩DOTA的回忆,并附上了一段纪念DOTA青春的视频链接。作者还提到了一些与程序员相关的名词和团队,如Pis、蛛丝马迹、B神、LGD、EHOME等。通过分享自己的经验,作者希望能够给其他程序员提供一些职业发展的思路和启示。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 电脑公司win7剪切板位置及使用方法
    本文介绍了电脑公司win7剪切板的位置和使用方法。剪切板一般位于c:\windows\system32目录,程序名为clipbrd.exe。通过在搜索栏中输入cmd打开命令提示符窗口,并输入clip /?即可调用剪贴板查看器。赶紧来试试看吧!更多精彩文章请关注本站。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
author-avatar
truelee的一些事一些情
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有