前言

由于历史遗留原因,Windows 的文件系统默认不区分大小写。如果你使用 WSL ( Windows Subsystem for Linux ) 通过 DrvFs 访问 Windows 下的目录来进行一些像编译这样的在 Linux 中习以为常的操作时就可能会遇到问题。

问题例子

这是我在编译 OpenWrt 时遇到的问题。

Build dependency: OpenWrt can only be built on a case-sensitive filesystem

/mnt/e/Downloads/OpenWrt/lede/include/prereq.mk:12: recipe for target 'prereq' failed
Prerequisite check failed. Use FORCE=1 to override.
/mnt/e/Downloads/OpenWrt/lede/include/toplevel.mk:167: recipe for target 'staging_dir/host/.prereq-build' faile
d
make: *** [staging_dir/host/.prereq-build] Error 1
Collecting package info: doneing...ing/visrouterd2criptsy-openwrt
Collecting target info: doneing...

其中第一行是关键。

Build dependency: OpenWrt can only be built on a case-sensitive filesystem
# OpenWrt只能构建在区分大小写的文件系统上

解决方案

据说微软很早就在解决这个历史遗留问题,所以 NTFS 支持了区分大小写特性的,只不过默认不开启。而开启需要修改注册表,这个操作是对整个系统的全局修改,其危险性可想而知。

值得庆幸的是从 Windows 10 insider build 17093 版本开始,新增了一种区分文件大小写的新方法:单个目录区分大小写。它可以良好的在 WSL 中和其他 Windows 应用程序中使用。这个功能仅修改指定目录本身的属性,故不会对系统有任何的影响。

以管理员权限运行 cmd 输入下面这个命令就可以开启某个目录区分大小写。

fsutil.exe file setCaseSensitiveInfo <path> enable

执行成功后会反馈一条信息

需要注意的是,这个操作不会对此目录中已有的文件生效,只有新写入的文件才会继承这个属性。所以对于目录中已有的文件,需要把文件剪切到其它目录,然后再复制回来。(同盘符下的剪切不是写入,所以后面的操作是复制。)

执行下面的命令可以查看某个目录是否有区分大小写。

fsutil.exe file queryCaseSensitiveInfo <path>

如果不需要区分大小写的属性可以设置为禁用。

fsutil.exe file setCaseSensitiveInfo <path> disable

参考资料

Per-directory case sensitivity and WSL