`
javasee
  • 浏览: 965525 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

开发工具(二)

阅读更多

Makefile中的注释

makefile文件中的注释以#开始,并且直到本行结束。正如在C源文件中一样,makefile文件中的注释有助于作者也其他人更好的理解文件编写时所期望的作用。

Makefile中的宏


即使有make与makefile是管理多个源码文件工程的强大工具。然而,对于由大量的文件所组成的工程来说,他们仍显得庞大和不灵活。所以Makefile允许我们使用宏,从而我们可以将其写为更为通用的形式。

我们在makefile文件中以MACRONAME=value的形式定义一个宏,然后以$(MACRONAME)或是${MACRONAME}的形式来访问MACRONAME的值。一些版本的make也可以接受$MACRONAME的形式。我们也可以通过将=之后的部分留空来设置一个空的宏。

在makefile文件中,宏通常用于编译的选项。通常,当正在开发一个程序时,我们通常并不会使用优化选项来进行编译,但是却需要包含调试信息。而对于发布一个程序通常是相反的情况:发布一个运行速度尽量快而不带任何调试信息的二进制程序。

Makefile1的另一个问题是他假定编译器为gcc。在其他的Unix系统上,我们也许会使用cc或是c89。如果我们希望将我们的makefile运行在其他版本的Unix系统上,或是如果我们在我们的系统上使用一个不同的编译器,我们就需要修改makefile的多行来使其工作。宏是用于收集系统相关部分的好方法,从而可以很容易的进行修改。

宏通常是在makefile文件本身内部定义的,但是也可以通过带有宏定义的make命令来指定,例如make CC=c89。类似这样的命令行定义可以覆盖makefile文件中的定义。当在makefile文件外部使用时,宏定义必须作为一个单独的参数进行传递,所以要避免空格或是使用引号的形式:make "CC = c89"。

试验--带有宏的Makefile

下面是我们的makefile的一个修正版本,Makefile2,其中使用一些宏:

all: myapp
# Which compiler
CC = gcc
# Where are include files kept
INCLUDE = .
# Options for development
CFLAGS = -g -Wall -ansi
# Options for release
# CFLAGS = -O -Wall -ansi
myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c

如果我们删除我们原有的安装,而使用这个新的makefile来创建一个新的安装,我们会得到下面的信息:

$ rm *.o myapp
$ make -f Makefile2
gcc -I. -g -Wall -ansi -c main.c
gcc -I. -g -Wall -ansi -c 2.c
gcc -I. -g -Wall -ansi -c 3.c
gcc -o myapp main.o 2.o 3.o
$

工作原理

make程序使用合适的定义来替换$(CC),$(CFLAGS)以及$(INCLUDE),与带有#define形式的C编译器类似。现在如是我们需要修改编译命令,我们只需要修改makefile文件中的一行。

事实上,make有多个内部宏,从而我们可以更为简洁的来使用。在下表中,我们列出其中最常用的一些;我们会在后的例子中看到他们的使用。这些宏中的每一个仅会在他们刚要被使用时进行扩展,所以宏的语义会随着makefile文件的处理而变化。事实上,如果这些不以这样的方进行工作,他们就不会太大的作用。

$? 距离当前目标最近一次修改的需求列表
$@ 当前目标的名字
$< 当前需求的名字
$* 不带前缀的当前需求的名字

还有另外两个有用的特殊字符,也许我们会在makefile文件中的命令前遇到:

-选择make忽略所有错误。例如,如果我们希望创建一个目录,但是希望忽略错误,也许是因为这个目录已经存在了,我们只需要在mkdir命令之前带有一个负号。我们将会在后面的章节中看到-的使用。

@告诉make在执行命令之前不要将命令输出到标准输出。如果我们希望使用echo来显示一些指令时,这个字符就特别有用。

多个目标

通常需要构建多个目标文件,而不是一个目标文件,或者是在一个地方收集多个命令组。我们可以扩展我们的makefile文件来完成这些任务。下面我们添加一个"clean"选项来移除不需要的目标文件,以及一个"install"选项来将完成的程序移动到另一个不同的目录中。

试验--多个目标

下面是下一个版本的makefile,Makefile3。

all: myapp
# Which compiler
CC = gcc
# Where to install
INSTDIR = /usr/local/bin
# Where are include files kept
INCLUDE = .
# Options for development
CFLAGS = -g -Wall -ansi
# Options for release
# CFLAGS = -O -Wall -ansi
myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
-rm main.o 2.o 3.o
install: myapp
@if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo “Installed in $(INSTDIR)”;\
else \
echo “Sorry, $(INSTDIR) does not exist”;\
fi

在这个makefile中需要注意多个地方。首先,特殊目标all仍然只是指定myapp作为目标。所以,当我们执行make命令而没有指定一个目标时,默认的行为就是构建目标myapp。

接下来需要特别注意的另外两个目标,clean与install。clean目标使用rm命令来移除目标文件。这个命令以-开头,这会使得make命令忽略命令的结果,所以make clean总会成功,即使并没有目标文件而rm命令返回一个错误。目标"clean"并没有为clean指定任何所依赖的条件;clean之后的行是空的。所以这个目标总是被认为是最新的,并且如果clean被指定为一个目标,那么其规则总是被执行。

install目标依赖于myapp,所以make会知道在执行其他命令运行install之前必须先创建myapp。install的规则由一些shell脚本命令所组成。因为make会为执行规则而调用shell,并且第一条规则使用一个新的shell,所以我们必须添加反斜线,这样所有的脚本命令就全在一个逻辑行,并且会全部传递给一个单独的shell调用。这个命令以@开头,这会通知make命令在执行规则之前不要在标准输出上打印出命令。

install目标顺序执行命令将程序安装在其最终位置上。他在执行下一条命令之前并不会检测前一条命令是否执行成功。如果只有前一条命令成功执行之后才可以执行后续的命令,那么我们必须使用&&符号将其联合,如下所示:

@if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR) &&\
chmod a+x $(INSTDIR)/myapp && \
chmod og-w $(INSTDIR/myapp && \
echo “Installed in $(INSTDIR)” ;\
else \
echo “Sorry, $(INSTDIR) does not exist” ; false ; \
fi

也许我们会回想起第2章的内容,这就是一个shell "and"命令,而且其效果是只有前一条命令执行成功之后才会执行后续的命令。在这里我们并不会关心是否保证前一条命令执行成功,所以我们只是使用这种较为简单的形式。

也许我们作为一个普通用户并不具有在/usr/local/bin目录下安装程序的权限。我们可以修改makefile文件从而使用另一个不同的安装目录,或是改变这个目录的权限,或者是在执行make install之前切换到root用户。

$ rm *.o myapp
$ make -f Makefile3
gcc -I. -g -Wall -ansi -c main.c
gcc -I. -g -Wall -ansi -c 2.c
gcc -I. -g -Wall -ansi -c 3.c
gcc -o myapp main.o 2.o 3.o
$ make -f Makefile3
make: Nothing to be done for ‘all’.
$ rm myapp
$ make -f Makefile3 install
gcc -o myapp main.o 2.o 3.o
Installed in /usr/local/bin
$ make -f Makefile3 clean
rm main.o 2.o 3.o
$

工作原理

首先,我们删除myapp与所有的目标文件。make命令会使用目标all,从而构建myapp。接下来我们再次运行make玲,因为myapp已经是最新的了,所以make不会做任何事情。然后我们删除myapp并且运行make install。这会重新构建这个二进制文件,并且将其拷贝到安装目录。最后我们运行make clean,这会删除目标文件。

分享到:
评论

相关推荐

    solidworks二次开发工具

    然而,对于有更高级需求的用户,如定制化功能、自动化设计流程或者集成企业内部系统,SolidWorks的二次开发工具就显得尤为重要。 在SolidWorks的二次开发中,主要涉及到以下几个方面: 1. **API接口**:SolidWorks...

    用友二次开发工具

    《用友二次开发工具在分销与零售系统的应用详解》 用友二次开发工具,作为一款专为用友软件量身定制的开发辅助平台,极大地简化了企业信息化建设过程中的复杂编程工作,使得非专业程序员也能高效地进行系统扩展与...

    基于用友U8产品二次开发工具介绍

    基于用友U8产品的二次开发工具,即U8快速开发工具,旨在解决上述问题。该工具原本是北京齐力创辉科技公司内部针对U8开发团队的一种内部开发工具,其初衷是降低成本并提高效率,从而在用友的互联网思维指导下,将好...

    U8二次开发工具包.rar

    U8二次开发工具包···一些控件调用说明·U8二次开发工具包···一些控件调用说明·

    MES软件:AVEVA二次开发-AVEVA与外部系统的集成.docxMES软件:AVEVA二次开发-AVEVA二次开发工具与技

    MES软件:AVEVA二次开发_AVEVA二次开发工具与技术.docx MES软件:AVEVA二次开发_AVEVA二次开发案例分析与实践.docx MES软件:AVEVA二次开发_AVEVA安全性与权限管理.docx MES软件:AVEVA二次开发_AVEVA工作流与业务...

    SCADA软件:Rockwell Software二次开发-RockwellSoftware二次开发工具介绍

    SCADA软件:Rockwell Software二次开发_RockwellSoftware二次开发工具介绍.docx SCADA软件:Rockwell Software二次开发_RockwellSoftware二次开发环境搭建.docx SCADA软件:Rockwell Software二次开发_...

    MES软件:Rockwell Automation FactoryTalk二次开发-FactoryTalk二次开发工具与环境

    MES软件:Rockwell Automation FactoryTalk二次开发_FactoryTalk二次开发工具与环境.docx MES软件:Rockwell Automation FactoryTalk二次开发_FactoryTalk安全性和权限管理.docx MES软件:Rockwell Automation ...

    NX11.0森焱工具V11.0.0二次开发工具中文安装版(附使用说明)

    森焱工具是一款集成在NX11.0版上的相关二次开发工具,方便设计者提高设计效率。工具大部分采用NXOpen C 代码完成,画面的直观感受就是摒弃了“非主流”与“老怪物”的操作界面。需要的朋友可下载试试! 注: 1、本...

    AutoCAD二次开发 ObjectARX侧边工具栏示例,在CAD2010上实现的屏幕菜单

    AutoCAD的二次开发是利用其提供的开发工具和接口来扩展或定制CAD软件功能的过程,而ObjectARX是AutoCAD的主要开发平台。ObjectARX是一种基于C++的编程库,允许开发者深入到AutoCAD的内核,创建能够与AutoCAD内部对象...

    MCGS_脚本驱动开发工具

    二、脚本驱动开发工具的特性 1. 自动化脚本生成:MCGS脚本驱动开发工具提供自动脚本生成功能,用户只需配置相关的硬件接口和参数,工具即可自动生成对应的脚本代码,极大地减少了开发时间。 2. 灵活性高:通过脚本...

    Epulis开发工具类

    《Epulis开发工具类详解》 在软件开发领域,工具类是程序员的得力助手,它们提供了一系列常用功能,使得代码编写更为高效便捷。Epulis开发工具类就是这样一个旨在优化开发流程、提升代码复用性的重要工具集。本文将...

    金蝶bos万能工具类和开发工具类代码.rar

    金蝶bos万能工具类和开发工具类代码,java源代码打包,金蝶给用户使用时需要二次开发,因此需要一些类的说明。金蝶BOS是一个开放的集成与应用平台,是金蝶ERP解决方案、合作伙伴解决方案以及客户定制应用的技术平台...

    PML二次开发工具

    PML二次开发工具则是基于PDMS(Plant Design Management System)系统,为用户提供了对PML进行扩展和定制的强大平台。PDMS是由AVEVA公司开发的一款三维工厂设计软件,它允许用户创建、管理和协作大型复杂工程的设计...

    CAD二次开发工具概述

    ### CAD二次开发工具概述 #### AutoCAD二次开发工具发展历程与特性 AutoCAD,作为全球领先的计算机辅助设计(CAD)软件,不仅以其强大的通用性和开放的架构在各行各业中得到广泛应用,而且通过不断迭代的二次开发...

    CAD二次开发托管工具

    用C#语言,CAD二次开发的托管工具,无需每次打开CAD加载文件,支持多个版本CAD

    基于Visionpro的二次开发,机器视觉相关基于康耐视工具Pma的封装与定义

    在机器视觉领域,康耐视VisionPro是一款广泛使用的专业图像处理软件,它提供了丰富的视觉工具和强大的二次开发能力。本文将深入探讨如何基于VisionPro进行二次开发,特别是针对康耐视工具Pma进行封装和定义的过程,...

    组态王图库开发工具

    组态王图库开发工具是一种专门用于创建和定制工控软件界面的专业软件,它为用户提供了自定义图形界面的能力,使工业自动化应用的可视化设计更加灵活、个性化。在这个“kv图库开发包”中,我们可以预见到包含了一系列...

    U8二次开发工具包.chm

    U8二次开发工具的详细说明,内容详实,操作性强,是U8开发不可多得的资料

Global site tag (gtag.js) - Google Analytics