【问题标题】:How do I compile code using Clang with the MinGW C/C++ Library? (Particular issue with float.h)如何使用 Clang 和 MinGW C/C++ 库编译代码? (float.h 的特殊问题)
【发布时间】:2019-07-23 14:24:52
【问题描述】:

我有一个简单的程序,我可以使用 MinGW 的 C/C++ 库通过 clang 成功编译:

#include <stdio.h>
int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }

我可以使用 mingw-gcc 成功编译:

 $ gcc test.c -o test
 $ ./test
 Hello world!

我也可以使用 clang+mingw 成功编译:

 $ clang test.c -o test -target
 $ ./test
 Hello world!

但是,如果我对我的程序(包括 float.h)做一个小改动,它会继续使用 gcc 编译,但不再使用 clang 编译:

#include <stdio.h>
#include <float.h>
int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }
 $ gcc test.c -o test
 $ ./test
 Hello world!

 $ clang test.c -o test -target x86_64-pc-windows-gnu
 In file included from test.c:2:
 In file included from C:\llvm\built\lib\clang\8.0.0\include\float.h:45:
 C:\mingw64-8.1.0\x86_64-w64-mingw32\include\float.h:28:15: fatal error: 'float.h' file not found
 #include_next <float.h>
               ^~~~~~~~~
 1 error generated.

clang 是否存在配置问题或缺少命令行参数?谷歌搜索了一下,似乎包含 float.h 时的路径顺序很重要,但这一切都应该由 clang 驱动程序在内部处理。

【问题讨论】:

  • 有趣,我什至不知道 Clang 可以针对 windows :d
  • 一个不同的环境,但我无法在 MSYS2 Mingw-w64 Win64 构建环境中重现该问题。
  • lib\clang\8.0.0\include\float.h:45 包含一个 ming 头文件 x86_64-w64-mingw32\include\float.h。 lib\clang\8.0.0\include\float.h 的第 45 行是什么?
  • @IanAbbott 这似乎适用于 C 示例,但 clang++ 似乎无法识别 msys gcc 包含路径,因此找不到 C++ 标头。
  • @effbiae #include_next

标签: c gcc clang mingw llvm


【解决方案1】:

MinGW-w64 的旧二进制版本与 Clang 8.0+ 的 float.h 不兼容。要解决此问题,请将this specific revision of float.h 复制到正确的位置并使用它。

【讨论】:

  • 使用此版本时,我收到链接器错误(找不到 -lgcc_eh)。我假设这是支持 SEH 的 libgcc - 我尝试使用 -fno-exceptions 重新编译,但这也会产生错误。
  • 它有没有可能被合并到“在线”安装程序中?我很困惑,我既不能选择异常处理也不能选择线程模型。还有那个“ada”的东西......
  • @VladFaust Ada 只是 GCC 支持的另一种语言。但是,它需要一个 Ada 编译器来构建自己。我个人不使用它,因为整个概念并不理想。我认为在线安装程序已经一年多没有更新了。
  • @HarryWagstaff 通常,这是 i686 上的默认设置...而不是 x86_64。
  • @JL2210 我也收到了cannot find -lgcc_eh 错误。我在 x86-64 上
【解决方案2】:

我认为将此问题传递给一个 clang 开发人员是可取的。

将之前版本 7.1.0 的 float.h 与 8.0.0 中的 float.h 进行比较,只发现了一些差异。我自己要问的第一个问题是,为什么他们将头部保护从 __FLOAT_H 更改为 __CLANG_FLOAT_H。

尝试更改 8.0.0 标头保护,看看会发生什么。

编辑:做了更多的搜索。自 2018 年 8 月以来,MinGW-w64 开发人员知道此更改。将补丁从 https://sourceforge.net/p/mingw-w64/mailman/message/36386405/ 添加或调整到您的 MinGW 安装可能会解决。

编辑 2:我有一段时间没有使用的是我的 MinGW 的 MSYS2 安装。它显示 g++.exe(Rev1,由 MSYS2 项目构建)8.2.1 20181214。这已应用补丁到 float.h 的第 27 行。

#if !defined(_FLOAT_H___) &amp;&amp; !defined(__FLOAT_H) &amp;&amp; !defined(__CLANG_FLOAT_H)

虽然 MinGW-w64 8.1.0 的源代码伪造下载显示为 #if !defined(_FLOAT_H___) &amp;&amp; !defined(__FLOAT_H)

注意:我也确定 MSYS2 使用滚动发布更新,但我必须检查一下。这不是我经常使用的东西。

Edit3:MSYS2 看起来像是一个滚动版本。最新版本是 9.1.0。

我的意见,除非您需要独立的 MinGW,否则请使用带有最新更新的 MSYS2。只是尝试修补其中一个旧版本可能会起作用,但我可能会展示其他问题。如果您确实需要独立版本,那么我认为唯一的选择是直接从源代码构建 MinGW-w64。

注意:我会在上面的讨论中添加 cmets,但是我还没有被允许。

编辑 4: 注意:第三方多库工具链很可能是默认使用 sjlj 异常构建的。检查方法见https://stackoverflow.com/a/17968530/11879567

编辑 5: 希望这是我将要进行的最后一次编辑。 查看 MinGW-w64 论坛,看看是否有人询问下一次正式发布的时间。我遇到有人问过 8.2 何时发布。我的印象是你可能要等待很长时间才能等待任何新的 MinGW-w64 版本。 https://sourceforge.net/p/mingw-w64/discussion/723797/thread/ea9a5b00fb/

旁注: 正如我在处理 Clang 时发现的那样,无论是使用 MinGW 还是 Visual Studio,您总会遇到一个或另一个问题。

【讨论】:

  • 这与修补编译器以针对特定问题做其他事情一样糟糕......
  • 这不是最好的解决方案,但不幸的是,这是使用哪个 MinGW-w64 版本的问题。最新的 MinGW 资源显示了 MinGW 的 float.h 中第 27 行的补丁。虽然当前 MinGW-w64 二进制下载没有这个补丁。
  • 感谢您的努力,@dawlane!不幸的是,从源代码构建不是我可以依赖的选项。希望这个问题能让MinGW维护者尽快更新主流版本。
  • @VladFaust:上面的 -lgcc_seh 问题。您很可能会看到这种情况的原因是上述二进制文件的默认异常。有关如何检查,请参阅stackoverflow.com/a/17968530/11879567。我不依赖第三方下载的原因之一。
  • 如果您对 w.r.t 没有特定要求,建议使用基于 MSYS2 的 MinGW-w64 是一个很好的建议。工具链版本,并且只想要最好的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
  • 2015-01-29
  • 2014-05-19
  • 1970-01-01
  • 1970-01-01
  • 2020-07-27
  • 2012-04-01
相关资源
最近更新 更多