【问题标题】:How to control clang default include path如何控制clang默认包含路径
【发布时间】:2019-07-18 12:57:27
【问题描述】:

我的 clang 副本尝试包含 Visual Studio 头文件,这是 clang -v hello.cc 的输出

clang version 9.0.0 (https://github.com/llvm/llvm-project.git 4f93b8b56f5982d19b8b55b8c575887c17e15588) 
Target: x86_64-pc-windows-msvc 
Thread model: posix 
InstalledDir: D:\llvm-project\build\Release\bin 
 "D:\\llvm-project\\build\\Release\\bin\\clang++.exe" -cc1 -triple x86_64-pc-windows-msvc19.21.27702 -emit-obj -mrelax-all
-mincremental-linker-compatible -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hello.cc -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -v -resource-dir "D:\\llvm-project\\build\\Release\\lib\\clang\\9.0.0"
-internal-isystem "D:\\llvm-project\\build\\Release\\lib\\clang\\9.0.0\\include"
-internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.21.27702\\ATLMFC\\include"
-internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.21.27702\\include"
-internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17763.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17763.0\\shared"
-internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17763.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17763.0\\winrt"
-internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.17763.0\\cppwinrt" -fdeprecated-macro
-fdebug-compilation-dir "D:\\llvm-project\\build\\Release\\bin" -ferror-limit 19 -fmessage-length 120 -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.21.27702 -std=c++14 -fdelayed-template-parsing -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -faddrsig -o "C:\\Users\\krono\\AppData\\Local\\Temp\\hello-19d364.o" -x c++ hello.cc 
clang -cc1 version 9.0.0 based upon LLVM 9.0.0svn default target x86_64-pc-windows-msvc
#include "..." search starts here:
#include <...> search starts here: 
 D:\llvm-project\build\Release\lib\clang\9.0.0\include 
 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\ATLMFC\include 
 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\include 
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt 
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\shared 
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\um 
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\winrt 
 C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\cppwinrt
End of search list.

这大概是因为我在构建它时犯了一些错误(我用 Visual Studio 构建它)。如何使它包含正确的头文件?我说的是永久解决方案,而不是每次编译时都覆盖包含搜索路径。

这方面的一些背景。我正在尝试使用 clang 构建一个 C++ 程序,但出现多个多重定义符号错误,如下所示

error LNK2005: "bool const std::_Is_integral<bool>" (??$_Is_integral@_N@std@@3_NB) already defined in ...

std::_Is_integral 是在 Visual Studio &lt;type_traits&gt; 头文件中定义的名称。我相信,如果我能在 LLVM libcxx 项目中包含 &lt;type_traits&gt;,这个错误就会消失。

【问题讨论】:

    标签: visual-studio clang llvm


    【解决方案1】:

    我自己在几个开源项目中也遇到过同样的问题。我没有答案,但我可以提供有关问题性质的更多详细信息:

    1) 问题来自 VS2019 中的 STL 标头,它使用以下结构:

    $ grep -r _Is_integral *
    include/xtr1common:// STRUCT TEMPLATE _Is_integral
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral = // determine whether cv-unqualified type _Ty is integral
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral = false; // determine whether cv-unqualified type argument is integral
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<bool> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<char> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<signed char> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<unsigned char> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<wchar_t> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<char16_t> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<char32_t> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<short> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<unsigned short> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<int> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<unsigned int> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<long> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<unsigned long> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<long long> = true;
    include/xtr1common:_INLINE_VAR constexpr bool _Is_integral<unsigned long long> = true;
    include/xtr1common:_INLINE_VAR constexpr bool is_integral_v = _Is_integral<remove_cv_t<_Ty>>; // determine whether _Ty is integral
    

    该行为与编译器如何评估“if constexpr”有关。根据标准,它应该从 C++17 开始支持,但 MSVC 编译器在运行(默认)C++14 模式时默默地支持它。

    另一方面,clang-cl 在 C++14 模式下运行时不会生成 C++17 代码,因此它会生成所有导出的符号,然后让 (MS) 链接器抱怨它们。

    到目前为止,我发现的解决方案(根据项目可能适用也可能不适用)将 clang-cl 强制转换为 C++17,然后使用“if constexpr”正确编译构造(没有符号)。

    另一个临时解决方法可能是在链接器标志中使用/force:multiple 来强制链接。由于它们的值不应该改变,多重定义应该没有问题,但它也是次优的。

    显然,MS 意识到了这个问题,但不想更改库。 https://developercommunity.visualstudio.com/content/problem/426829/xtgmathh-and-other-microsoft-include-files-use-if.html

    关于 Clang 的“原生”STL 的使用,我希望人们还需要使用“原生”clang(即不是clang-cl,它是 MSVC 的下拉替换)。这可能会怎样,但我不知道。

    【讨论】:

      猜你喜欢
      • 2014-07-02
      • 1970-01-01
      • 2010-12-06
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-22
      相关资源
      最近更新 更多