我有一个格式如下的makefile。首先,我定义了我的输出;
EXEFILES = myexe1.exe myexe2.exe
然后我定义了那些输出的依赖关系;
myexe1.exe : myobj1.obj
myexe2.exe : myobj2.obj
然后我有一些宏定义了链接的额外依赖关系;
DEP_myexe1 = lib1.lib lib2.lib
DEP_myexe2 = lib3.lib lib4.lib
然后我有将.obj转换为.exe;
的目标$(EXEFILES):
$(LINK) -OUT:"Exe\$@" -ADDOBJ:"Obj\$<" -IMPLIB:$($($(DEP_$*)):%=Lib\\%)
我想要发生的是(myexe1.exe的示例)
DEP_$* -> DEP_myexe1
$(DEP_myexe1) -> lib1.lib lib2.lib
$(lib1.lib lib2.lib:%=Lib\\%) -> Lib\lib1.lib Lib\lib2.lib
不幸的是,这不起作用。当我运行make --just-print
时,-IMPLIB:
参数为空。但是,如果我运行$(warning DEP_$*)
,我会
DEP_myexe1
当我跑$(warning $(DEP_myexe1))
时,我得到了
lib1.lib lib2.lib
因某些原因,make
不喜欢$(DEP_$*)
的组合。也许它不能像这样动态地解析宏名称。我该怎么做才能让它发挥作用?还有其他选择吗?
答案 0 :(得分:1)
$(warning DEP_$*)
在哪里准确地为您提供DEP_myexe1
作为输出?因为上面给出了你的makefile,它不应该是
$*
是匹配的目标模式的主干。在您的情况下,因为您有明确的目标名称,所以没有模式匹配,因此没有词干,因此$*
始终为空。
此外,您正在尝试进行一些过多的扩展。您正在扩展$*
以直接获取myexe1
(假设该变量按照您的预期方式运行)。然后,您使用DEP_
作为前缀,并使用$(DEP_$*)
获取lib1.lib lib2.lib
。然后,您展开该结果$($(DEP_$*))
,然后再次展开该(空)结果(进行替换)$($($(DEP_$*)):%=Lib\\%)
。
您希望在规则正文中使用$(@:.exe=)
代替$*
,或者使用%.exe
作为目标,然后使用$*
获取myexe1
/ myexe2
。
然后,您希望从$($($(DEP_$*)):%=Lib\\%)
中删除两个级别的展开,而是使用$(DEP_$*:%=Lib\\%)
。
所以(假设您使用模式规则)最终得到:
%.exe:
$(LINK) -OUT:"Exe\$@" -ADDOBJ:"Obj\$<" -IMPLIB:$(DEP_$*:%=Lib\\%)
答案 1 :(得分:0)
我设法让它工作,而不需要以上述方式解析宏。我像这样修改了链接依赖项;
myexe1.exe : myobj1.obj lib1.lib lib2.lib
myexe2.exe : myobj2.obj lib3.lib lib4.lib
然后我需要在目标配方中按扩展名过滤这些文件;
$(EXEFILES):
$(LINK) -OUT:"$(EXE_PATH)\$@" -ADDOBJ:$(patsubst %, Obj\\%, $(filter %.obj, $^)) -IMPLIB:$(patsubst %, Lib\\%, $(filter %.lib, $^))
$(pathsubst ...)
用于添加相关文件所在的路径。
对于myexe1.exe,链接命令扩展为;
slink -OUT:"Exe\myexe1.exe" -ADDOBJ: Obj\myexe1.obj -IMPLIB: Lib\lib1.lib Lib\lib2.lib
出于兴趣的缘故,我仍然想知道是否有可能解决问题中的宏名称。