将 clang-cl 与 NMake 样式的 Makefile 一起使用无法回显
Using clang-cl with an NMake style Makefile cannot echo
我有一个现有的 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 触发之前我得到了“访问被拒绝”错误,之后磁盘上不存在命名的“header”文件。事实上,通过对代码进行细微更改,我发现我也无法回显到标准输出。但是当我使用默认 CL 时它会起作用。那么为什么编译器重写会改变回显的能力呢?
如果您有兴趣,可以在我的 GitHub 上找到完整的 Makefile,但请注意它是非常规的。
问题是 .make.cc
文件中的以下两行:
DIR=\ //
ENT=;
第二行看起来很奇怪,但是是正确的:它用于指定 Windows 列表分隔符 ;
而不是 Unix :
。第一行的目标是将 $(DIR)
设置为单个反斜杠,\
.
cl
在创建 .make
时生成:
DIR=\ ^M$
ENT=;^M$
(为清楚起见添加了 ^M
和 $
)而 clang-cl
去掉了每行末尾的白色 space 并生成:
DIR=$
ENT=;$
所以对于 cl
,$(DIR)
根据需要扩展为一个反斜杠 \
。但在 clang-cl
中它扩展为 ENT=;
,这导致文件名 $(MAKHDR)
变为 obj ENT=;header.mak
而不是 obj\header.mak
.
Alse $(HDRDIR)
变成 src ENT=;
,破坏 for %i in ($(HDRDIR)*...
。
一种解决方案是在 .make.cc
中替换:
DIR=\ //
与
DIR=\ #
(我也尝试过使用 ^\
,但那是一场灾难。)
我有一个现有的 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 触发之前我得到了“访问被拒绝”错误,之后磁盘上不存在命名的“header”文件。事实上,通过对代码进行细微更改,我发现我也无法回显到标准输出。但是当我使用默认 CL 时它会起作用。那么为什么编译器重写会改变回显的能力呢?
如果您有兴趣,可以在我的 GitHub 上找到完整的 Makefile,但请注意它是非常规的。
问题是 .make.cc
文件中的以下两行:
DIR=\ //
ENT=;
第二行看起来很奇怪,但是是正确的:它用于指定 Windows 列表分隔符 ;
而不是 Unix :
。第一行的目标是将 $(DIR)
设置为单个反斜杠,\
.
cl
在创建 .make
时生成:
DIR=\ ^M$
ENT=;^M$
(为清楚起见添加了 ^M
和 $
)而 clang-cl
去掉了每行末尾的白色 space 并生成:
DIR=$
ENT=;$
所以对于 cl
,$(DIR)
根据需要扩展为一个反斜杠 \
。但在 clang-cl
中它扩展为 ENT=;
,这导致文件名 $(MAKHDR)
变为 obj ENT=;header.mak
而不是 obj\header.mak
.
Alse $(HDRDIR)
变成 src ENT=;
,破坏 for %i in ($(HDRDIR)*...
。
一种解决方案是在 .make.cc
中替换:
DIR=\ //
与
DIR=\ #
(我也尝试过使用 ^\
,但那是一场灾难。)