Makefile讲解
来源:互联网 发布:dictionary软件下载 编辑:程序博客网 时间:2024/06/04 19:11
最近接触到很多C++项目,其中很多项目中含有大量的Makefile文件,但是由于环境的不同Makefile也带来了很多问题,所以决定以ice中的多个Makefile文件为例进行了介绍,ice中的文件结构如下:
.├── BuildInstructions.md├── BuildInstructionsAIX.md├── BuildInstructionsLinux.md├── BuildInstructionsOSX.md├── BuildInstructionsWindows.md├── Makefile├── allTests.py├── bin│ ├── glacier2router│ ├── icebox│ ├── iceboxadmin│ ├── icegridadmin│ ├── icegriddb│ ├── icegridnode│ ├── icegridregistry│ ├── icepatch2calc│ ├── icepatch2client│ ├── icepatch2server│ ├── icestormadmin│ ├── icestormdb│ ├── slice2confluence│ ├── slice2cpp│ ├── slice2cs│ ├── slice2html│ ├── slice2java│ ├── slice2js│ ├── slice2objc│ ├── slice2php│ ├── slice2py│ └── slice2rb├── config│ ├── Make.rules│ ├── Make.rules.MINGW│ ├── Make.xcodesdk.rules│ ├── glacier2router.cfg│ ├── ice.cpp.props│ ├── ice_ca.cnf│ ├── icegridnode.cfg│ ├── icegridregistry.cfg│ └── templates.xml├── include│ ├── Glacier2│ ├── Ice│ ├── IceBT│ ├── IceBox│ ├── IceGrid│ ├── IceIAP│ ├── IcePatch2│ ├── IceSSL│ ├── IceStorm│ ├── IceUtil│ └── generated├── lib│ ├── libGlacier2.3.7a4.dylib│ ├── libGlacier2.37a4.dylib -> libGlacier2.3.7a4.dylib│ ├── libGlacier2.dylib -> libGlacier2.3.7a4.dylib│ ├── libGlacier2CryptPermissionsVerifier.3.7a4.dylib│ ├── libGlacier2CryptPermissionsVerifier.37a4.dylib -> libGlacier2CryptPermissionsVerifier.3.7a4.dylib│ ├── libGlacier2CryptPermissionsVerifier.dylib -> libGlacier2CryptPermissionsVerifier.3.7a4.dylib│ ├── libIce.3.7a4.dylib│ ├── libIce.37a4.dylib -> libIce.3.7a4.dylib│ ├── libIce.dylib -> libIce.3.7a4.dylib│ ├── libIceBox.3.7a4.dylib│ ├── libIceBox.37a4.dylib -> libIceBox.3.7a4.dylib│ ├── libIceBox.dylib -> libIceBox.3.7a4.dylib│ ├── libIceDB.3.7a4.dylib│ ├── libIceDB.37a4.dylib -> libIceDB.3.7a4.dylib│ ├── libIceDB.dylib -> libIceDB.3.7a4.dylib│ ├── libIceDiscovery.3.7a4.dylib│ ├── libIceDiscovery.37a4.dylib -> libIceDiscovery.3.7a4.dylib│ ├── libIceDiscovery.dylib -> libIceDiscovery.3.7a4.dylib│ ├── libIceGrid.3.7a4.dylib│ ├── libIceGrid.37a4.dylib -> libIceGrid.3.7a4.dylib│ ├── libIceGrid.dylib -> libIceGrid.3.7a4.dylib│ ├── libIceLocatorDiscovery.3.7a4.dylib│ ├── libIceLocatorDiscovery.37a4.dylib -> libIceLocatorDiscovery.3.7a4.dylib│ ├── libIceLocatorDiscovery.dylib -> libIceLocatorDiscovery.3.7a4.dylib│ ├── libIcePatch2.3.7a4.dylib│ ├── libIcePatch2.37a4.dylib -> libIcePatch2.3.7a4.dylib│ ├── libIcePatch2.dylib -> libIcePatch2.3.7a4.dylib│ ├── libIceSSL.3.7a4.dylib│ ├── libIceSSL.37a4.dylib -> libIceSSL.3.7a4.dylib│ ├── libIceSSL.dylib -> libIceSSL.3.7a4.dylib│ ├── libIceStorm.3.7a4.dylib│ ├── libIceStorm.37a4.dylib -> libIceStorm.3.7a4.dylib│ ├── libIceStorm.dylib -> libIceStorm.3.7a4.dylib│ ├── libIceStormService.3.7a4.dylib│ ├── libIceStormService.37a4.dylib -> libIceStormService.3.7a4.dylib│ ├── libIceStormService.dylib -> libIceStormService.3.7a4.dylib│ ├── libIceUtil.a│ ├── libIceXML.3.7a4.dylib│ ├── libIceXML.37a4.dylib -> libIceXML.3.7a4.dylib│ ├── libIceXML.dylib -> libIceXML.3.7a4.dylib│ ├── libSlice.a│ ├── libTestCommon.3.7a4.dylib│ ├── libTestCommon.37a4.dylib -> libTestCommon.3.7a4.dylib│ └── libTestCommon.dylib -> libTestCommon.3.7a4.dylib├── msbuild│ ├── ice.cpp.props│ ├── ice.cpp11.props│ ├── ice.cpp98.props│ ├── ice.nuget.targets│ ├── ice.nuget.uwp.arch.targets│ ├── ice.nuget.uwp.targets│ ├── ice.proj│ ├── ice.test.props│ ├── ice.test.sln│ ├── ice.testuwp.props│ ├── ice.testuwp.sln│ ├── ice.uwp.props│ ├── ice.uwp.sln│ ├── ice.v120.sln│ ├── ice.v140.sln│ ├── icebuilder.cpp.props│ ├── zeroc.ice.uwp.arch.targets│ ├── zeroc.ice.uwp.arm.nuspec│ ├── zeroc.ice.uwp.nuspec│ ├── zeroc.ice.uwp.props│ ├── zeroc.ice.uwp.x64.nuspec│ ├── zeroc.ice.uwp.x86.nuspec│ ├── zeroc.ice.v120.nuspec│ ├── zeroc.ice.v120.props│ ├── zeroc.ice.v120.targets│ ├── zeroc.ice.v140.nuspec│ ├── zeroc.ice.v140.props│ └── zeroc.ice.v140.targets├── src│ ├── Glacier2│ ├── Glacier2CryptPermissionsVerifier│ ├── Glacier2Lib│ ├── Ice│ ├── IceBT│ ├── IceBox│ ├── IceDB│ ├── IceDiscovery│ ├── IceGrid│ ├── IceGridLib│ ├── IceIAP│ ├── IceLocatorDiscovery│ ├── IcePatch2│ ├── IcePatch2Lib│ ├── IceSSL│ ├── IceStorm│ ├── IceStormLib│ ├── IceUtil│ ├── IceXML│ ├── Slice│ ├── icegriddb│ ├── iceserviceinstall│ ├── slice2confluence│ ├── slice2cpp│ ├── slice2cs│ ├── slice2html│ ├── slice2java│ ├── slice2js│ ├── slice2objc│ ├── slice2php│ ├── slice2py│ └── slice2rb├── test│ ├── Common│ ├── Glacier2│ ├── Ice│ ├── IceBox│ ├── IceDiscovery│ ├── IceGrid│ ├── IceSSL│ ├── IceStorm│ ├── IceUtil│ ├── Slice│ ├── include│ ├── ios│ └── uwp└── tree
先看ice/cpp
下的Makefile文件:
#定义变量top_srcdir := ..lang_srcdir := $(top_srcdir)/cpp#包含其他Makefileinclude $(top_srcdir)/config/Make.rulesinclude $(lang_srcdir)/config/Make.rules## Create projects for all the Slice translators from src/slice2* and load source projects.#projects :=$(foreach t,$(wildcard $(lang_srcdir)/src/slice2*),$(eval $(call create-translator-project,$(call project,$t))))include $(shell find $(lang_srcdir)/src -name Makefile.mk)$(call make-projects,$(projects),make-cpp-src-project)## Now, create and load test projects.#projects :=tests := $(call tests-without-project-makefile,cpp)include $(shell find $(lang_srcdir)/test -name Makefile.mk)$(foreach t,$(tests),$(eval $(call create-cpp-test-project,$(t))))$(call make-projects,$(projects),make-cpp-test-project)install:: | $(DESTDIR)$(install_configdir) $(Q)$(INSTALL) $(lang_srcdir)/config/templates.xml $(DESTDIR)$(install_configdir)
foreach函数
foreach函数和别的函数非常的不一样。因为这个函数是用来做循环用的,Makefile中的foreach函数几乎是仿照于Unix标准Shell(/bin/sh)中的for语句,或是C-Shell(/bin/csh)中的foreach语句而构建的。它的语法是:
$(foreach <var>,<list>,<text> )
这个函数的意思是,把参数list中的单词逐一取出放到参数var所指定的变量中,然后再执行text所包含的表达式。每一次text会返回一个字符串,循环过程中,text的所返回的每个字符串会以空格分隔,最后当整个循环结束时,text所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
所以,var最好是一个变量名,list可以是一个表达式,而text中一般会使用var这个参数来依次枚举list中的单词。举个例子:
names := a b c dfiles := $(foreach n,$(names),$(n).o)
上面的例子中,$(name)中的单词会被挨个取出,并存到变量n中,$(n).o每次根据$(n)计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是a.o b.o c.o d.o。
注意
foreach中的参数是一个临时的局部变量,foreach函数执行完后,参数的变量将不在作用,其作用域只在foreach函数当中。
wildcard函数
在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数”wildcard”,它的用法是:$(wildcard PATTERN…) 。在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函数会忽略模式字符并返回空。
eval函数
函数原型 $(eval text)
它的意思是 text 的内容将作为makefile的一部分而被make解析和执行。
例如:
define MAaa:aa.c gcc -g -o aa aa.cendef $(eval $(call MA) )会产生一个这样的编译:gcc -g -o aa aa.c
call函数
call函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。其语法是:
$(call ;,;,;,;...)
当make 执行这个函数时,;参数中的变量,如
reverse = $(1) $(2) foo = $(call reverse,a,b)
那么,foo的值就是“a b”。当然,参数的次序是可以自定义的,不一定是顺序的,如:
reverse = $(2) $(1) foo = $(call reverse,a,b)
此时的foo的值就是“b a”。
参考资料
- Makefile 中:= ?= += =的区别
- makefile讲解...
- makefile讲解
- makefile讲解
- Makefile讲解
- makefile文件讲解
- makefile常用讲解(2)
- Android Makefile 文件讲解
- 通用Makefile讲解【转】
- Android Makefile 文件讲解
- Makefile使用讲解
- 通用makefile讲解
- makefile常用讲解二
- makefile常用讲解三
- makefile常用讲解(3)
- makefile常用讲解(2)
- Android Makefile 文件讲解
- makefile的详细讲解
- makefile基础实例讲解
- 2017年要学习的三个CSS新特性
- 10G/11G/12cr1版本中backup archivelog命令是否会触发归档current logfile操作
- gcc 程序内存使用分析
- 在macOS 10.12 上编译 Android 5.1
- FBI树(提高组)
- Makefile讲解
- PHP Call to undefined function mysql_connect()
- 2017.1.21【初中部 GDKOI】模拟赛B组
- C++的tie()函数
- Tango 开发指南 — 参考帧
- 3D游戏开发之在UE4中创建非玩家角色(NPC)
- 利用pushState, popState和location.hash等方法自己实现一个小型路由
- 浅析Spring的JdbcTemplate
- 多读书少睡觉