使用带有 NMake 样式 Makefile 的 clang-cl 无法回显

Posted

技术标签:

【中文标题】使用带有 NMake 样式 Makefile 的 clang-cl 无法回显【英文标题】:Using clang-cl with an NMake style Makefile cannot echo 【发布时间】:2021-03-03 00:54:27 【问题描述】:

我有一个现有的 Makefile(用于 NMake,而不是 GNU),可以与默认的 CL 编译器一起正常工作。我打算使用 clang-cl 兼容性程序来试验 Clang。但是我似乎在 Makefile 中遇到了与编译器无关的错误。例如,我在 Makefile 中有一个代码片段

MAKHDR=$(MAKDIR)header.$(MAKEXT)
!if ![(echo HDR=\>$(MAKHDR)) && for %i in ($(HDRDIR)*.$(HDREXT)) do @echo %i\>>$(MAKHDR)]
!include $(MAKHDR)
!else
!error Cannot locate header files
!endif

从命令行

set CXX=clang-cl
nmake

这段代码应该定位所有头文件并将它们放入一个变量中(有点像 GNU Make 中的通配符宏)。但是我在上面的 !error 触发之前收到“访问被拒绝”错误,之后磁盘上不存在命名的“头”文件。事实上,通过对代码的细微更改,我发现我也无法回显到标准输出。但是当我使用默认的 CL 时它可以工作。那么为什么编译器会覆盖改变回显的能力呢?

如果您有兴趣,可以在我的 GitHub 上找到完整的 Makefile,但请注意它是非常规的。

【问题讨论】:

【参考方案1】:

问题是.make.cc文件中的以下两行:

DIR=\ //
ENT=;

第二行看起来很奇怪,但它是正确的:它用于指定 Windows 列表分隔符 ; 而不是 Unix 的 :。第一行的目标是将$(DIR) 设置为单个反斜杠\

cl 在创建 .make 时生成:

DIR=\ ^M$
ENT=;^M$

(为清楚起见添加了^M$)而clang-cl 去除了每行末尾的空白并生成:

DIR=\$
ENT=;$

因此,cl$(DIR) 根据需要扩展为仅一个反斜杠 \。但是在clang-cl 中它会扩展为 ENT=;,这会导致文件名$(MAKHDR) 变为obj ENT=;header.mak 而不是obj\header.mak

另外$(HDRDIR) 变成src ENT=;,破坏for %i in ($(HDRDIR)*...


一种解决方案是替换.make.cc:

DIR=\ //

DIR=\ #

(我也尝试过使用^\,但那是一场灾难。)

【讨论】:

出色的答案。谢谢。

以上是关于使用带有 NMake 样式 Makefile 的 clang-cl 无法回显的主要内容,如果未能解决你的问题,请参考以下文章

如何在makefile(nmake使用的makefile)中加入依赖文件的搜索路径(依赖文件不在当前目录)

寻找nmake和makefile结构的介绍[关闭]

如何为 Visual Studio 构建工具 cl.exe 编写 makefile(nmake)

如何使用 NMake 设置环境变量

nmake文件学习记录看《跟我一起写Makefile》

nmake文件学习记录看《跟我一起写Makefile》