【问题标题】:OpenMP linking errors in Visual Studio 2019 LLVMVisual Studio 2019 LLVM 中的 OpenMP 链接错误
【发布时间】:2020-09-19 03:57:48
【问题描述】:

我一直在尝试使用集成到 Visual Studio 2019 的 LLVM 编译器构建 OpenMP 示例程序。

LLVM 编译器是从 here(版本 10.0,win64)下载的,C:\Program Files\LLVM\bin 添加到 PATH 环境变量中。 LLVM Compiler Toolchain 扩展是从Visual Studio Marketplace 安装的。

它成功构建了一个 hello world 程序,但是当我尝试使用 OpenMP 时,链接器失败并出现以下错误:

1>clang version 10.0.0
1>Target: x86_64-pc-windows-msvc
1>Thread model: posix
1>InstalledDir: C:\Program Files\LLVM\bin
1> (in-process)
1> "C:\\Program Files\\LLVM\\bin\\clang-cl.exe" -cc1 -triple x86_64-pc-windows-msvc19.26.28805 -emit-obj -mrelax-all -mincremental-linker-compatible -disable-free -disable-llvm-verifier -discard-value-names -main-file-name llvmtest.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -mllvm -x86-asm-syntax=intel -D_DEBUG -D_MT -D_DLL --dependent-lib=msvcrtd --dependent-lib=oldnames -stack-protector 2 -fcxx-exceptions -fexceptions -fexternc-nounwind -fms-volatile -fdefault-calling-conv=cdecl -fdiagnostics-format msvc -gcodeview -debug-info-kind=limited -v -resource-dir "C:\\Program Files\\LLVM\\lib\\clang\\10.0.0" -D _DEBUG -D _CONSOLE -D _UNICODE -D UNICODE -internal-isystem "C:\\Program Files\\LLVM\\lib\\clang\\10.0.0\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.26.28801\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.26.28801\\atlmfc\\include" -internal-isystem "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\VS\\include" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\ucrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\um" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\shared" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\winrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.18362.0\\cppwinrt" -internal-isystem "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.6.1\\Include\\um" -O0 -Wall -Wno-error -fdeprecated-macro -fdebug-compilation-dir "Z:\\llvmtest" -ferror-limit 19 -fmessage-length 0 -fopenmp -fno-use-cxa-atexit -fms-extensions -fms-compatibility -fms-compatibility-version=19.26.28805 -std=c++14 -fdelayed-template-parsing -fobjc-runtime=gcc -fno-caret-diagnostics -fdiagnostics-show-option -faddrsig -o "Debug\\llvmtest.obj" -x c++ llvmtest.cpp
1>clang -cc1 version 10.0.0 based upon LLVM 10.0.0 default target x86_64-pc-windows-msvc
1>#include "..." search starts here:
1>#include <...> search starts here:
1> C:\Program Files\LLVM\lib\clang\10.0.0\include
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\include
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\atlmfc\include
1> C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\VS\include
1> C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt
1> C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um
1> C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared
1> C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt
1> C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\cppwinrt
1> C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\Include\um
1>End of search list.
1>lld-link : error : undefined symbol: __kmpc_global_thread_num
1>>>> referenced by Z:\llvmtest\llvmtest.cpp:9
1>>>>               Debug\llvmtest.obj:(main)
1>
1>lld-link : error : undefined symbol: __kmpc_push_num_threads
1>>>> referenced by Z:\llvmtest\llvmtest.cpp:15
1>>>>               Debug\llvmtest.obj:(main)
1>
1>lld-link : error : undefined symbol: __kmpc_fork_call
1>>>> referenced by Z:\llvmtest\llvmtest.cpp:15
1>>>>               Debug\llvmtest.obj:(main)
1>
1>lld-link : error : undefined symbol: omp_get_thread_num
1>>>> referenced by Z:\llvmtest\llvmtest.cpp:19
1>>>>               Debug\llvmtest.obj:(.omp_outlined._debug__)
1>
1>lld-link : error : undefined symbol: omp_get_num_threads
1>>>> referenced by Z:\llvmtest\llvmtest.cpp:25
1>>>>               Debug\llvmtest.obj:(.omp_outlined._debug__)
1>Done building project "llvmtest.vcxproj" -- FAILED.

代码比较简单:

    #include <omp.h>
    #include <stdio.h>

    int main()
    {
        int nthreads, tid;

        //omp_set_num_threads(4);   

    #pragma omp parallel private(tid) num_threads(3)
        {               
            tid = omp_get_thread_num();
            printf("Hello World from thread = %d\n", tid);

            if (tid == 0)
            {
                nthreads = omp_get_num_threads();
                printf("Number of threads = %d\n", nthreads);
            }

        }  /* All threads join master thread and terminate */
    }

项目设置如下图:

我尝试了不同的选项:-fopenmp-Xclang -fopenmp 编译器标志、传递 -openmp-fopenmp 作为链接器标志、将 x64 更改为 x86、添加 C:\Program Files\LLVM\lib 到 PATH。到目前为止没有任何帮助。

有趣的是,我可以通过从 x64 Native Tools Command Prompt for VS 2019 运行以下命令,从命令行构建相同的代码:

clang-cl -openmp llvmtest.cpp

所以,基本上,-openmp 标志就足够了......有人知道如何让它在 Visual Studio 中工作吗?

【问题讨论】:

  • 这些都是 OpenMP 运行时库中缺失的符号。在 LLVM 的 lib 目录中的某处应该有一个 libomp.lib 文件。您需要将其添加到链接器设置中的其他库中。问题是 VS 做了一个单独的链接步骤,链接器不知道您也需要 OpenMP 运行时。当您使用clang-cl -openmp ... 编译时,编译器驱动程序会在调用链接器时自动添加 OpenMP 运行时库。
  • @HristoIliev 我在想这个,但我不知道如何正确地将这些库添加到链接器中。在我看来,“通常”的 VS 链接器设置在这种情况下是无关紧要的,因为我使用的是 LLVM,因此使用 lld-link 而不是 Microsoft 链接器。 LLVM 下有“附加链接器选项”字段(见图),但我不知道该传递什么。你能给我一个提示吗?
  • 我猜是-lomp
  • @HristoIliev lld-link:警告:忽略未知参数“-lomp”
  • 假设lld-linklink 的命令行兼容,那么附加选项应该是libomp.lib。您可能还需要在某处添加 LLVM 的 lib 目录的路径。

标签: visual-studio clang openmp llvm linker-errors


【解决方案1】:

最后,我设法让它工作了(感谢 LLVM 工具链扩展的作者 Marek Aniola,他帮助了我)。

首先,我将/openmp 标志传递给LLVM -> 附加编译器选项(它也适用于-openmp)。

其次,事实证明,从 Visual Studio 构建时,OpenMP 不会自动链接(与使用 clang-cl 从命令行编译相反)。 LLVM 的链接器设置与 Microsoft 链接器的指定方式相同。

库的路径 C:\Program Files\LLVM\lib 必须添加到 Linker -> General -> 其他库目录

还需要在Linker -> Input -> Additional Dependencies中列出libomp.lib

链接器 -> 优化 -> 链接时间码生成必须设置为默认

这些步骤让我成功地构建了代码(64 位应用程序)。虽然 64 位 LLVM 编译器可以构建 32 位程序,但它只包含 x64 版本的 OpenMP 库,因此为了构建 32 位应用程序,我必须链接 libomp.lib 并复制libomp.dll 来自另一个 LLVM 发行版。如果有更好的方法可以做到这一点,请告诉我。

【讨论】:

  • Visual Studio 2019 16.6.0 附带针对 x86 和 x64 的 Clang 10.0.0。您可以使用 Visual Studio 安装程序安装它。
  • @HristoIliev 是的,我已经先尝试过了。但它似乎只适用于 CMake 项目。它在查找 OpenMP 方面也存在一些问题。我想这里讨论过:stackoverflow.com/questions/57209524/…
  • @mentalmushroom,如果您像这样&lt;!-- &lt;VCMessage Code="MSB8055" Type="Error" Condition="('%(ClCompile.OpenMPSupport)' == 'true')" /&gt; --&gt; 关闭Microsoft.Cpp.ClangCl.Common.targets 中的多线程错误,它会起作用。
  • 顺便说一句:Clang 在 VS2019 中支持哪个 OpenMP 版本?
【解决方案2】:

除了@mentalmushroom 的回答,现在似乎只需要第二步:

"...还需要在Linker -> Input -> Additional Dependencies...中列出libomp.lib..."

Visual Studio 2019 16.10.3 使用 LLVM 工具集。

【讨论】:

    【解决方案3】:

    我还花了一些时间让 Clang + OpenMP 在 Visual Studio 2019 中工作。这是我的方法,希望它对某人有用。它在很大程度上模仿了在 Linux 上使用 gcc 的方法。

    在 Visual Studio 的解决方案资源管理器中右键单击项目 > 属性:
    (1) 常规 > 平台工具集 > LLVM (clang-cl)
    (2) C/C++ > General > Additional Include Directories > C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\Llvm\lib\clang\10.0.0\include //告诉编译器在哪里可以找到 omp.h(在 gcc 中:-I)
    //64 位版本位于 C:\Program Files (x86)\Microsoft Visual Studio\2019\ Professional\VC\Tools\Llvm\x64\lib\clang\10.0.0\include
    (3) C/C++ > Command Line > Additional Options > -openmp //告诉编译器使用OpenMP (gcc: -fopenmp)
    (4) Linker > General > Additional Library Directories > C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\Llvm\lib //告诉链接器在哪里寻找OpenMP库( in gcc: -L)
    //64位.lib文件位于C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\Llvm \x64\lib
    (5) Linker > Input > Additional Dependencies > libomp.lib (或在 C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\Llvm\lib 中调用的任何库文件) //告诉链接器要链接到哪个库(NB libomp.lib 依赖于 libomp.dll)(在 gcc 中:-l)
    (6) 添加到PATH系统环境变量:C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\Llvm\bin //这里libomp.dll所在,所以windows可以动态将构建的可执行文件链接到 libomp.dll(在 Linux 中:LD_LIBRARY_PATH)
    //64 位 .dll 文件位于 C:\Program Files (x86)\Microsoft Visual Studio\2019 \Professional\VC\Tools\Llvm\x64\bin
    //重启CommandPrompt/PowerShell或电脑重新加载环境变量
    (7) 另外,对于 64 位 (fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'):
    (7.1) 链接器 > 目标机器 > MachineX64 (/MACHINE:x64)
    (7.2) VC++目录>可执行目录>C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\Llvm\x64\bin

    需要对 Release/Debug 和 x86(或 Win32)/x64 的每种组合重复上述过程(为什么人们更喜欢构建系统中的 GUI...)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 2021-02-10
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 2021-09-02
      相关资源
      最近更新 更多