如何控制Clang默认包含路径

时间:2019-07-18 12:57:27

标签: visual-studio clang llvm

我的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构建它)时犯了一些错误。如何使其包含正确的头文件?我说的是永久解决方案,而不是每次编译时都覆盖include搜索路径。

对此有一些背景。我正在尝试使用clang构建C ++程序,并且遇到多个乘法定义的符号错误,例如

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

std::_Is_integral是在Visual Studio <type_traits>头文件中定义的名称。我相信,如果我能从LLVM libcxx项目中获得包含<type_traits>的lang声,此错误就会消失。

1 个答案:

答案 0 :(得分:0)

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

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

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

另一方面,

clang-cl在C ++ 14模式下运行时不会生成C ++ 17代码,因此它会生成所有这些导出的符号,然后让(MS)链接程序抱怨它们。 / p>

到目前为止,我发现的解决方案(可能因项目而定是否适用)强制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的下拉替代品)。那怎么可能,但是我不知道。