是否可以动态包含Makefile?例如,取决于一些环境变量?我有以下Makefile:
makefile
app1.1.mak
app1.2.mak
还有一个环境变量APP_VER
,可以设置为1.1.0.1,1.1.0.2,1.2.0.1,1.2.0.2。
但是1.1和1.2行只有两个不同的makefile。
我曾尝试编写以下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
答案 0 :(得分:2)
您有两个问题:获取版本的方法过于复杂,而您的include
行存在缺陷。试试这个:
include app$(APP_VER).mak
如果APP_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 :(得分:0)
试试这个:
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)
答案 2 :(得分:0)
有四个makefile:
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_VER=1.1
或APP_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呢?
我还观察到,由于你有环境变量APP_VER驱动你的过程,你可以通过要求标准化的'make invoker'来排除APP_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 "$@"
此脚本验证APP_VER已设置,如果不是,则给出相应的默认值。然后它处理该值以导出MAK_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_VER环境变量,然后脚本会从文件中读取版本号。并且脚本可以完成各种其他工作,确保安装正确的工具,设置其他环境变量等等。