如何动态地包含makefile?
是否可以动态包含makefile?例如,取决于某些环境变量?我有以下生成文件:如何动态地包含makefile?,makefile,aix,Makefile,Aix,是否可以动态包含makefile?例如,取决于某些环境变量?我有以下生成文件: makefile app1.1.mak app1.2.mak 还有一个环境变量APP\u VER,可以设置为1.1.0.1、1.1.0.2、1.2.0.1、1.2.0.2。 但是对于1.1和1.2行,只有两个不同的makefile 我已尝试编写以下生成文件: MAK_VER=$$(echo $(APP_VER) | sed -e 's/^\([0-9]*\.[0-9]*\).*$$/\1/') include
makefile
app1.1.mak
app1.2.mak
还有一个环境变量APP\u VER
,可以设置为1.1.0.1、1.1.0.2、1.2.0.1、1.2.0.2。但是对于1.1和1.2行,只有两个不同的makefile 我已尝试编写以下生成文件:
MAK_VER=$$(echo $(APP_VER) | sed -e 's/^\([0-9]*\.[0-9]*\).*$$/\1/')
include makefile$(MAK_VER).mak
all: PROD
echo MAK_VER=$(MAK_VER)
但它不起作用:
$ make all
"makefile$(echo", line 0: make: Cannot open makefile$(echo
make: Fatal errors encountered -- cannot continue.
更新:
据我所知,make
在计算宏之前包含文件。这就是它试图执行以下语句的原因
include makefile.mak
而不是
include makefile1.1.mak
试试这个:
MAK_VER=$(shell echo $(APP_VER) | sed -e 's/^\([0-9]*\.[0-9]*\).*$$/\1/')
MAK_FILE=makefile$(MAK_VER).mak
include $(MAK_FILE)
all:
echo $(MAK_VER)
echo $(MAK_FILE)
include app$(APP_VER).mak
您有两个问题:获取版本的方法太复杂,并且
include
行有缺陷。试试这个:
include app$(APP_VER).mak
如果APP\u VER
是一个环境变量,那么这将起作用。如果还希望包含名为makefile
的makefile(即,如果makefile
不是我们正在编写的文件),请尝试以下操作:
include makefile app$(APP_VER).mak
请注意,这被认为是一个坏主意。如果makefile依赖于环境变量,则它将适用于某些用户,而不适用于其他用户,这被视为不良行为
编辑:这应该做到:
MAK_VER := $(subst ., ,$(APP_VER))
MAK_VER := $(word 1, $(MAK_VER)).$(word 2, $(MAK_VER))
include makefile app$(MAK_VER).mak
修改大纲解决方案
有四个生成文件:
- 生成文件
- 附录1.1.mak
- 附录1.2.mak
- appdummy.mak
app.dummy.mak
makefile可以为空-如果愿意,可以是指向/dev/null的符号链接。app.1.1.mak和app.1.2.mak的当前内容不变
主makefile稍有更改:
MAK_VER = dummy
include makefile$(MAK_VER).mak
dummy:
${MAKE} MAK_VER=$$(echo $(APP_VER) | sed -e 's/^\([0-9]*\.[0-9]*\).*$$/\1/') all
all: PROD
...as now...
如果键入make
,它将读取(空)虚拟makefile,然后尝试构建dummy
目标,因为它首先出现。要构建虚拟目标,它将在命令行上再次运行make
,使用APP\u VER=1.1
或APP\u VER=1.2
:
make APP_VER=1.1 all
无法在makefile中更改命令行上设置的宏,因此这将覆盖makefile中的行。因此,第二次调用make
,将读取正确的特定于版本的makefile,然后构建all
这种技术有局限性,最明显的是,它很容易安排每一个目标都被这样对待。这是有办法的,但通常不值得
项目组织 更严重的是,我认为你需要重新审视你正在做的事情。您可能正在使用版本控制系统(VCS)来管理源代码。另外,据推测,版本1.1和1.2源代码之间存在一些(显著)差异。因此,为了能够为版本1.1进行构建,您必须从版本1.1维护分支切换到版本1.2开发分支,或者类似的东西。那么,为什么makefile的版本不是针对1.1或1.2的呢?如果在版本之间切换,则需要清除所有可能使用错误源生成的派生文件(对象文件、库、可执行文件等)。你必须重新修改源代码。那么为什么不也更改makefile呢 调用make的生成脚本 我还观察到,由于您有环境变量APP\u VER驱动您的流程,因此您可以通过要求一个标准化的“make invoker”来解决问题,该“make invoker”可以整理APP\u VER值并正确调用
make
。假设脚本名为build
:
#!/bin/sh
: ${APP_VER:=1.2.0.1} # Latest version is default
case $APP_VER in
[0-9].[0-9].*)
MAK_VER=`echo $APP_VER | sed -e 's/^\(...\).*/\1/'`
;;
*) echo "`basename $0 .sh`: APP_VER ($APP_VER) should start with two digits followed by dots" 1>&2;
exit 1;;
esac
exec make MAK_VER=$MAK_VER "$@"
此脚本验证是否设置了应用程序版本,如果未设置,则提供适当的默认值。然后,它处理该值以导出MAK\u VER(如果不正确,则会出错)。当然,在达到版本10后,您需要修改该测试,因为您计划获得成功,在适当的时候将达到两位数的版本号
如果提供了正确的版本信息,现在可以使用任何命令行参数调用makefile
makefile可以非常简单:
MAK_VER = dummy
include app$(MAK_VER).mak
all: PROD
...as now...
appdummy.mak文件现在包含一条规则:
error:
echo "You must invoke this makefile via the build script" 1>&2
exit 1
它只是指出了进行构建的正确方法
请注意,如果将产品版本号保存在VCS下的文件中,然后脚本从文件中读取版本号,则可以避免使用APP\u VER环境变量。脚本还可以完成各种其他工作,确保安装了正确的工具,设置了其他环境变量,等等。$export APP\u VER=1.1;生成所有“makefile”,第0行:make:无法打开makefile遇到make:致命错误--无法继续。上面发布的makefile有效(不会生成您显示的错误)。在不深入了解具体情况的情况下,关键部分是前三行,它们将shell命令的输出收集到一个变量中,“动态”创建makefile名称,然后将其包含在内。您的意思是说
APP\u VER
可能设置为“1.1”或“1.2”,还是可能设置为“1.1version”或“1.2vladimir”“简单makefile”是否与makefile
相同,或者与另一个可以设置为1.1.0.1、1.1.0.2、1.2.0.1、1.2.0.2的测试版相同。但是对于1.1和1.2行,只有两个不同的makefile。请阅读更新。APP\u VER可以设置为1.1.0.1、1.1.0.2、1.2.0.1、1.2.0.2等。但是我需要不同的make文件用于1.1和1.2行。不幸的是,我的make版本(用于AIX)既不支持subst函数也不支持word函数。@Vladimir Bezugliy:它支持$(shell…
)吗?不支持。我决定使用以下方法:INNER\u MAKEFILE=$(MAKEDIR)/MAKEFILE$(APP\u VER)。在AIX上,您要么需要设置环境变量,要么需要一些技术,例如将正确的特定于版本的makefile链接到始终包含的固定名称。(除非你在两者之间切换,否则效果很好