我正在交换一个大型代码库,从使用msvc到clang for windows产品。这个产品使用了大量的msvc编译器内在函数,如_InterlockedOr等。如果我在windows上使用clang构建一个小测试程序,它构建,链接和运行就好了,但如果我从我们的产品构建一个使用内在函数的库它出现了一个缺失的符号。
我尝试使用--verbose选项编译测试代码和我们的产品,并且无法发现两者之间的任何不同。调用它们的唯一区别是使用fastbuild构建大型产品,这需要使用-c来防止编译器调用链接器。 Clang显然在我自己手动调用链接器的时候添加了一些库,所以有人能告诉我它们可能是什么吗? (我已经在crt库中链接了(libcmt,msvcrt),所以不是那样。
我已经开始在汇编中编写我自己的内在函数库,这很有趣,但不是必需的。任何人?
根据请求,使用clang编译以下代码时可以直接使用它,即clang IntrinsicsTest.cpp
生成一个exe。
IntrinsicsTest.cpp
#include "stdio.h"
#include "intrin.h"
int _tmain(int argc, _TCHAR* argv[])
{
unsigned long long r = __rdtsc();
printf("Intrinsic: %llu\n", r);
}
然而在通过fastbuild调用时无法链接:
FBuild.exe -showcmds -clean IntrinsicsTest_debug_x86
clang.exe“\ IntrinsicsTest.cpp”-D_WINDOWS -c -m32 -mfpmath = sse -D_UNICODE -DUNICODE -fno-rtti -fexceptions -E ... \ IntrinsicsTest.debug.Win32.lib
lib.exe / NOLOGO /OUT:"...\IntrinsicsTest.debug.Win32.lib“”...... \ IntrinsicsTest.obj“...... \ IntrinsicsTest.debug.Win32.exe
link.exe / NOLOGO / INCREMENTAL:NO /OUT:"...\IntrinsicsTest.debug.Win32.exe“”... \ IntrinsicsTest.obj“-defaultlib:libcmt.lib -INCREMENTAL -MANIFEST / MACHINE: X86 / SUBSYSTEM:CONSOLE / OPT:NOICF / OPT:NOREF
IntrinsicsTest.obj:错误LNK2019:函数中引用了未解析的外部符号___rdtsc _wmain ... \ IntrinsicsTest.debug.Win32.exe
致命错误LNK1120:1个未解析的外部
答案 0 :(得分:3)
我已经解决了这个问题。有几个因素与fastbuild,clang和msvc的交互方式有关。
a /在Windows上使用Clang时,无需指定" system"包括。 在我们的项目中,我们将包含路径设为:ionic@beta
xmmintrin的clang版本声明内联内联,因此如果使用此标头,则测试程序编译正常。 Windows xmmintrin将内在函数声明为extern函数,因此程序编译,但没有链接 - 其中msvc构建从这些符号中获取这些符号现在是无关紧要的。
然而,即使首先包含clang包含路径,当任何内容包含-I"C:/Program Files/LLVM/lib/clang/3.8.0/include"
-I"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/include/"
-I"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/atlmfc/include"
-I"C:/Program Files (x86)/Windows Kits/8.1/include/um"
-I"C:/Program Files (x86)/Windows Kits/8.1/include/shared"
-I"C:/Program Files (x86)/Windows Kits/8.1/include/winrt"
时,它会拉入窗口标题。
b / Fastbuild允许您为构建环境设置环境变量。我们的脚本使用msvc路径定义了INCLUDE和PATH。删除这些有帮助。
c /和clang一样,我的机器上安装了几个版本的msvc。 Clang正在接受MSVC14,而fastbuild试图通过改变fastbuild来使用MSVC14。我终于能够通过内在函数解决问题。
答案 1 :(得分:1)
内在函数不应该是函数调用,它们应该内联到一个或几个指令。或者在某些情况下,没有指令(例如编译器内存屏障,如c ++的std::atomic_signal_fence
)。
MSVC和GNU C是C. clang实现GNU C的独立风格,AFAIK不支持MSVC内在函数。
如果GNU C __builtin_something
等效于MSVC内在函数,请通过包装函数使用它。
mingw-w64显然通过_Interlocked???
支持<winnt.h>
。 This mailing list post是一个补丁,它将实现从内联asm切换到GNU C __sync_fetch_and_???
函数。 IDK如果用当前的mingw运送,或者如果有一个mingw版本的clang。但这就是你应该寻找的东西。我确定你不是第一个想要使用不同编译器编译MSVC代码库的人。