Windows Clang Hello World LNK4217 [英] Windows clang Hello World lnk4217

查看:89
本文介绍了Windows Clang Hello World LNK4217的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经安装了clang 6.0版和Visual Studio2017。我正在编译一个简单的'hello world'应用程序:

  #include< iostream> 

int main()
{
std :: cout<< 你好,世界! << std :: endl;
返回0;
}

使用

  clang hello.cpp 

这会给我警告:

  hello-d1b2c6.o:警告LNK4217:本地定义的符号__std_terminate 
在函数 int`public中导入:静态未签名__int64 __cdecl
std :: char_traits< char> :: length(char const * const)'::`1':: dtor $ 2
(?dtor $ 2 @?0 ?? length @?$ char_traits @ D @ std @@ SA_KQEBD @ Z @ 4HA)

hello-d1b2c6.o:警告LNK4217:本地定义的符号_CxxThrowException
导入了函数 public:void __cdecl std :: ios_base :: clear(int,bool)
(?clear @ ios_base @ std @@ QEAAXH_N @ Z)

我知道我可以使用 clang-cl 减轻这些警告(如建议的在这样的问题中此处),但是,我确实不想这样做完全理解其中的含义。



这是我的实际问题:


  1. 这些警告是什么意思或导致这些警告的原因是什么?

  2. 使用 clang-cl 更改有什么作用,我必须注意什么?使用时介意吗? (我猜有一个原因,就是不要一直使用它)

  3. 还有其他方法不接收这些警告(除了关闭警告)?


解决方案

我自己遇到了这个问题并进行了调查。



< h3>这些警告是什么意思?

有详细的答案此处(我不完全理解),但是据我了解,高层的想法是目标文件( .o 文件)之间不匹配编译的 clang 以及与之链接的库文件( .lib 文件)。



因此,尽管该程序似乎可以运行,但仅忽略警告可能不是一个好主意。



是什么引起了这些警告? / h3>

警告是由Microsoft链接程序 link.exe 发出的,其中 clang 调用。 Clang不包括自己的链接器。默认情况下,在Windows上,它将查找Microsoft Visual Studio C编译器头,库和链接器。通过在 clang 命令行中添加 -v (详细)开关,您可以确切地看到它在做什么。 / p>

我不确定Clang如何找到这些工具。我忘了我什至没有安装它们,而且它们肯定不在 PATH 上。我认为Clang必须以某种方式将它们从注册表中挖出。



使用clang-cl更改有什么作用?



它将更改传递给Clang编译器的开关(也称为 clang clang ++ clang -cl ,但通过了 -cc1 开关)和链接器(MSVC link.exe )。在较高级别上, clang-cl 尝试模拟MSVC cl.exe 编译器,而 clang ...还有其他事情。我不确定。它不是在模仿MinGW;



详细的区别可以在相应的 -v 输出中看到。使用LLVM 8.0.1中的 clang ++ clang-cl ,我看到了这些编译器切换差异:

  clang-cl有,但clang ++缺乏:
-消除锯齿
-mllvm
-x86-asm-syntax = intel
-D_MT
-flto-visibility-public-std
--dependent-lib = libcmt
--dependent-lib = oldnames
-堆栈保护器2
-fms-volatile
-fdiagnostics-format msvc

clang ++有但clang-cl缺少:
-fcxx-exceptions
-fexceptions

在链接期间, clang ++ 传递 -defaultlib:libcmt ,而 clang-cl 不传递。



我看到的最大区别是 clang-cl 传递了 -D_MT ,从而启用了线程-了解C和C ++标准库。我认为混合使用和不使用 _MT 编译的模块是个坏主意。关于 -fcxx-exceptions 的不匹配也令人担忧,这表明C ++异常可能不起作用。



clang-cl 还通过 -flto-visibility-public-std ,这是有关相关问题的答案。我不知道这个标志只是在抑制警告还是在显着改变代码的编译方式。



使用它时我要记住什么?



据我了解,当且仅当您希望Clang进行操作时,您才想使用 clang-cl 最好模拟Microsoft cl.exe 编译器,包括使用其头文件并使用其库调用Microsoft链接器。



此外,我不知道在Windows上使用 clang ++ 而不指定 -target 的理由(下一部分) )。如果没有 -target clang ++ 仍将使用MSVC标头,库和链接器,但不会将所需的开关传递给模拟 cl.exe 编译器。我怀疑这将始终导致目标代码不匹配的可执行文件。



还有其他方法不接收这些警告吗?



就我而言,我希望Clang模拟 MinGW gcc 编译器,然后调用其链接器。为此,请按照此答案,添加 -target x86_64-pc-windows-gnu clang ++ 命令行:

  $ clang ++ .exe -target x86_64-pc-windows-gnu -o cpphello.exe cpphello.cpp 

该命令



通过在该命令行中添加 -v ,您可以看到详细信息,包括调用MinGW ld.exe 链接器。



注意:您需要一个MinGW gcc 在您的 PATH 上!



c声与++声++有关? h3>

gcc clang 如果文件使用可识别的扩展名,则编译C ++代码,例如 .cc .cpp 。但是,即使您在单个命令中进行编译和链接,它也不会将C ++标准库传递给链接器。因此,通常最好在处理C ++代码时专门使用 clang ++



与之类似, clang -x c ++ 可用于编译C ++,但不会再次将C ++标准库传递给链接器。


I have installed clang version 6.0 as well as Visual Studio 2017. I am compiling a simple 'hello world' application:

#include <iostream>

int main()
{
  std::cout << "Hello, World!" << std::endl;
  return 0;
}

using

clang hello.cpp

This gives me warnings:

hello-d1b2c6.o : warning LNK4217: locally defined symbol __std_terminate 
imported in function "int `public: static unsigned __int64 __cdecl
std::char_traits<char>::length(char const * const)'::`1'::dtor$2"
(?dtor$2@?0??length@?$char_traits@D@std@@SA_KQEBD@Z@4HA)

hello-d1b2c6.o : warning LNK4217: locally defined symbol _CxxThrowException 
imported in function "public: void __cdecl std::ios_base::clear(int,bool)"
(?clear@ios_base@std@@QEAAXH_N@Z)

I am aware that I can mitigate these warnings by using clang-cl (as suggested in this SO question and here), however, I do not want to do that without fully understanding the implications.

So here are my actual questions:

  1. What do these warnings mean or what is causing them?
  2. What does using clang-cl change and what do I have to keep in mind when using it? (I guess there is a reason to not use it all the time)
  3. Are there other ways to not receive these warnings (except for turning off warnings)?

解决方案

I ran into this issue myself and did some investigation.

What do these warnings mean?

There is a detailed answer here (that I do not fully understand), but the high level idea, as I understand it, is there is a mismatch between the object file (.o file) that clang compiled and the library file (.lib file) that is being linked with.

Therefore, although the program seems to work, it's probably a bad idea to just ignore the warnings.

What is causing them?

The warning is being issued by the Microsoft linker, link.exe, which clang invokes. Clang does not include its own linker. By default, on Windows, it looks for the Microsoft Visual Studio C compiler headers, libraries, and linker. You can see exactly what it is doing by adding the -v (verbose) switch to the clang command line.

I'm not sure how Clang finds these tools. I'd forgotten I even had them installed, and they certainly are not on the PATH. I think Clang must have dug them out of the registry somehow.

What does using clang-cl change?

It changes the switches passed to the Clang compiler (also called clang or clang++ or clang-cl, but with the -cc1 switch passed) and the linker (MSVC link.exe). At a high level, clang-cl tries to emulate the MSVC cl.exe compiler, while clang ... does something else. I'm not sure what. It's not emulating MinGW; see below.

The detailed differences can be seen in the respective -v outputs. Using clang++ and clang-cl from LLVM 8.0.1, I see these compiler switch differences:

clang-cl has but clang++ lacks:
  -relaxed-aliasing
  -mllvm
  -x86-asm-syntax=intel
  -D_MT
  -flto-visibility-public-std
  --dependent-lib=libcmt
  --dependent-lib=oldnames
  -stack-protector 2
  -fms-volatile
  -fdiagnostics-format msvc

clang++ has but clang-cl lacks:
  -fcxx-exceptions
  -fexceptions

And during linking, clang++ passes -defaultlib:libcmt, while clang-cl does not.

The big difference I see is clang-cl passes -D_MT, enabling the thread-aware C and C++ standard libraries. I think it's a bad idea to mix modules compiled with and without _MT. The mismatch regarding -fcxx-exceptions is also concerning, suggesting that C++ exceptions might not work.

clang-cl also passes -flto-visibility-public-std, the flag recommended by this answer to a related question. I don't know whether this flag is merely suppressing a warning or significantly changing the way the code is compiled.

What do I have to keep in mind when using it?

As I understand it, you want to use clang-cl if and only if you want Clang to do its best to emulate the Microsoft cl.exe compiler, including using its header files and invoking the Microsoft linker with its libraries.

Furthermore, I'm unaware of a reason to use clang++ on Windows without also specifying -target (next section). Without -target, clang++ still uses the MSVC headers, libraries, and linker, but does not pass the switches needed to emulate the cl.exe compiler. I suspect this will always result in an executable with mismatched object code.

Are there other ways to not receive these warnings?

In my case, I want Clang to emulate the MinGW gcc compiler and invoke its linker instead. To do that, per this answer, add -target x86_64-pc-windows-gnu to the clang++ command line:

  $ clang++.exe -target x86_64-pc-windows-gnu -o cpphello.exe cpphello.cpp

That command produces no warnings, and a working executable.

By adding -v to that command line, you can see the details, including invocation of the MinGW ld.exe linker.

Note: You need a MinGW gcc on your PATH!

What about clang versus clang++?

Like gcc, clang will compile C++ code if the file uses an extension it recognizes, such as .cc or .cpp. However, it does not pass the C++ standard library to the linker, even when you compile and link in a single command. Therefore, it's generally best to use clang++ exclusively when working with C++ code.

Likewise, clang -x c++ can be used to compile C++, but again does not pass the C++ standard library to the linker.

这篇关于Windows Clang Hello World LNK4217的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆