在 #65 和 #133 中,我们都涉及到了 `Cygwin` 和 `MSYS2` 的问题。 ## 第一次错误的认识 在第一次尝试解决这个问题的时候,我花了一下午,最终确认是在 `Cygwin` 上的 `/usr/bin/curl` 的问题。即,我认为三种不同环境下编译的 `curl.exe` (`Cygwin` 下、`MSYS2`下、原生Windows下)的行为不一致,所以最终归咎于上游。 <br> ## 新的认识 然而今天经过再次研究,发现这一问题的根源,并不是上述编译 `curl` 的环境或者编译配置等问题。而是整个 `Cygwin` 环境的问题:`Cygwin` 无法识别 `nul` 文件。而 `MSYS2` 修正了这个问题。 所以判断 `Cygwin` 环境成为了我们的一个主要目标。 <br> ## 检测`Cygwin`的方案 上一次,我们是使用 `cygcheck.exe` 这一命令来检测的,这一命令在 `Cygwin` 和 `MSYS2` 中都存在。@Yangmoooo 指出用户很有可能把 Git Bash 的路径加入 Windows 原生环境变量中,导致上述检测方案失效。 接着寻求其它方案:`Cygwin` 环境并没有暴露出任何环境变量,唯一的 `CYG_SYS_BASHRC` 也没有被 `export` 出来。通过环境变量的检测手段失败了,接着我想要通过路径来检测,然而 Windows 上的 `access()` 以及原生的 `GetFileAttribute()` 都无法检测到 `/usr` 这种目录。遂这种方案也失效。 <br> ## 鸡蛋问题 我们可以通过调用 `which`, `test` 等命令检测,但是在原生 Windows 上这个命令不存在,因而需要 `>nul 2>nul`,此时在 Cygwin 环境中,又会生成 `nul` 文件(即使内容为空,也会产生)。我们发现,我们又回去了,陷入了鸡生蛋蛋生鸡的问题。 所以我提出这个方案:仍然基于第一次的修改,但现在额外让用户付出一个小的代价:让 `Cygwin` 用户主动暴露一个 `export ON_CYGWIN=1` 供我们检测,检测到后,再利用我们现有的实现去迂回地测速。即,修改这一条件:https://github.com/RubyMetric/chsrc/blob/main/src/framework/core.c#L498 ```c #if XY_On_Windows // if (0==system ("cygcheck --version >nul 2>nul")) if (getenv ("ON_CYGWIN")) { on_cygwin = true; os_devnull = "/tmp/chsrc-measure-downloaded"; } #endif ```
Activity
ccmywish commentedon Dec 8, 2024
相关用户:@anaer @xyx1926885268
方案协助审核:@happy-game @Yangmoooo
Yangmoooo commentedon Dec 8, 2024
@ccmywish 感谢您详尽的回复。事实上,我在尝试了几种方式后,初步得出了两个解决方案:
根据
uname命令可以正确区分 Windows、MSYS2 和 Cygwin 环境,以此改进之前的判断逻辑将 Windows 平台上的测速工具统一指定为
C:\Windows\System32\curl.exe根据我的测试,这两种方案都能够解决现有的环境判断和
nul文件的问题,但我更倾向于方案二,原因如下:这三种环境本质上都属于 Windows 平台,都存在
C:\Windows\System32\curl.exe,且对于原生 Windows 程序的处理相同统一的工具能够简化未来的开发工作
统一使用 Windows 原生的
curl.exe可以去除之前不必要的环境判断补丁,代码更加清晰如果需要,我会在晚些时候提交 PR
ccmywish commentedon Dec 8, 2024
@Yangmoooo 感谢你持续关注这个问题,并提出自己的方案。
用
uname还是避免不了鸡蛋问题。因为 Windows 里没有uname,用system()去调用时,只能又去添加>nul 2>nul或者说,你的方案里不需要加
>nul 2>nul吗?C:\Windows\System32\curl.exe在 Windows 7 中是没有的统一指定为
C:\Windows\System32\curl.exe刚才测试了一下,在
MSYS2中成功,但在Cygwin中无法找到该路径Yangmoooo commentedon Dec 8, 2024
我前面说的比较笼统,对于这三个问题:
我是先通过
MSYSTEM环境变量判断 MSYS2,然后用uname 2>nul区分 Windows 和 Cygwin,因为 Cygwin 正好无法识别nul文件Windows 7 的兼容性我确实没有考虑到 😂,但是我看到较新版本的 MSYS2 和 Cygwin 也不再支持 Windows 7,那么可能本来也没有
curl命令在 Cygwin 的终端中确实不能直接调用 Windows 的
curl.exe,但在 C 程序中的popen函数(即 chsrc 里的xy_run)是可以的happy-game commentedon Dec 8, 2024
也许可以使用libcurl进行测速, 并最终静态编译发布, 这样就不用再考虑
curl的问题了, 也可以简化用户的操作(因为有些发行版甚至不会默认安装curl).但也存在几个问题:
libcurl再编译Drop previous devious support for `curl` built by `Cygwin`
Drop previous devious support for `curl` built by `Cygwin`
ccmywish commentedon Dec 9, 2024
已修复,见 #144
感谢各位 ❤️ @anaer @xyx1926885268 @happy-game @Yangmoooo