在 Mac OS X (sierra & Mojave) 中启用 OpenMP 支持

Posted

技术标签:

【中文标题】在 Mac OS X (sierra & Mojave) 中启用 OpenMP 支持【英文标题】:Enable OpenMP support in clang in Mac OS X (sierra & Mojave) 【发布时间】:2017-09-19 04:56:39 【问题描述】:

我使用的是 Mac OS X Sierra,我发现 clang(LLVM 版本 8.1.0 (clang-802.0.38))不支持 OpenMP: 当我运行clang -fopenmp program_name.c 时,出现以下错误:

clang: error: unsupported option '-fopenmp'

好像clang不支持-fopenmp标志。

我在自制软件中找不到任何 openmp 库。根据 LLVM 网站,LLVM 已经支持 OpenMP。但我在编译期间找不到启用它的方法。

这是否意味着 Mac 中的默认 clang 不支持 OpenMP? 您能提供什么建议吗?

(当我切换到GCC编译同一个程序(gcc使用brew install gcc --without-multilib安装),编译成功。)

【问题讨论】:

确实,Apple 提供的 clang 不支持 OpenMP。 brew install llvm 应该安装最新的 LLVM 版本,即 4.0.0。这能解决问题吗? Apple 提供的 clang 默认情况下不支持 OpenMP。可以在 Apple 提供的 clang 中启用该功能,也可以安装默认支持 OpenMP 的更新版本的 clang。 @IncreasinglyIdiotic 我们如何启用它?我们只需要编译和安装 openmp 运行时吗? @MarcusJ 你应该只需要brew install llvm libomp 然后确保使用新的clang 来编译-fopenmp 标志 【参考方案1】:

    尝试使用Homebrew的llvm:

    brew install llvm
    

    然后你就拥有了/usr/local/opt/llvm/bin 中的所有 llvm 二进制文件。

    编译 OpenMP Hello World 程序。把omp_hello.c

    /******************************************************************************
         * FILE: omp_hello.c
         * DESCRIPTION:
         *   OpenMP Example - Hello World - C/C++ Version
         *   In this simple example, the master thread forks a parallel region.
         *   All threads in the team obtain their unique thread number and print it.
         *   The master thread only prints the total number of threads.  Two OpenMP
         *   library routines are used to obtain the number of threads and each
         *   thread's number.
         * AUTHOR: Blaise Barney  5/99
         * LAST REVISED: 04/06/05
         ******************************************************************************/
         #include <omp.h>
         #include <stdio.h>
         #include <stdlib.h>
    
         int main (int argc, char *argv[]) 
         
         int nthreads, tid;
    
         /* Fork a team of threads giving them their own copies of variables */
         #pragma omp parallel private(nthreads, tid)
           
    
           /* Obtain thread number */
           tid = omp_get_thread_num();
           printf("Hello World from thread = %d\n", tid);
    
           /* Only master thread does this */
           if (tid == 0) 
             
             nthreads = omp_get_num_threads();
             printf("Number of threads = %d\n", nthreads);
             
    
             /* All threads join master thread and disband */
    
         
    

    在文件中并使用:

    /usr/local/opt/llvm/bin/clang -fopenmp -L/usr/local/opt/llvm/lib omp_hello.c -o hello
    

    您可能还必须将CPPFLAGS 设置为-I/usr/local/opt/llvm/include

    makefile 应该如下所示:

    CPP = /usr/local/opt/llvm/bin/clang
    CPPFLAGS = -I/usr/local/opt/llvm/include -fopenmp
    LDFLAGS = -L/usr/local/opt/llvm/lib
    
    omp_hello: omp_hello.c
         $(CPP) $(CPPFLAGS) $^ -o $@ $(LDFLAGS)
    

更新

在 macOS 10.14 (Mojave) 中,您可能会收到类似的错误

/usr/local/Cellar/llvm/7.0.1/lib/clang/7.0.1/include/omp.h:118:13: fatal error: 'stdlib.h' file not found

如果发生这种情况,/usr/include 中缺少 macOS SDK 标头。他们使用Xcode 10 进入SDK 本身。使用

将标题安装到/usr/include
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

【讨论】:

您可能还需要brew install libomp 确实,使用llvm@8,我必须安装libomp 这导致我出现“缺少分隔符”错误。显然,这意味着标签必须是“硬”的。所以我找到了“软”选项卡并将其替换,然后我得到了错误:omp_hello'. Stop. 需要的*** No rule to make target omp_hello.c' 如果我这样做该死,如果我不这样做该死。 @rocksNwaves 这里给出的说明是如何编译一个名为omp_hello.c 的文件。 Make 告诉您该文件不存在并且它不知道该怎么做。解决方案:提供该文件。 @Ed。感谢您的注意,我在回答中包含了该文件。【参考方案2】:

基于 Conda 的编译环境

Conda 使用 clang 进行 OSX 编译(伞包 cxx-compiler),但我在使用 llvm-openmp-fopenmp 标志抛出错误时遇到了类似的问题。解决方案与其他答案非常相似,但我将这里包括在内,以防其他人有更确切的问题。

具体解决办法是在CFLAGS中包含Conda环境的include/目录,即:

CFLAGS="-I$CONDA_PREFIX/include"

注意,我还需要在链接的时候加上-lstdc++ -Wl,-rpath $CONDA_PREFIX/lib -L$CONDA_PREFIX/lib,类似于this GitHub Issue。

【讨论】:

【参考方案3】:

其他人给出了一种解决方案(使用 Homebrew llvm)。您还可以将 OpenMP 与 Apple Clang 和 Homebrew libomp (brew install libomp) 一起使用。只需将clang -fopenmp test.c 之类的命令替换为clang -Xpreprocessor -fopenmp test.c -lomp

【讨论】:

我试过了,但找不到 omp.h 包含。 如果你确定你已经在 Homebrew 下安装了 libomp,你可以在 Homebrew 论坛上提问discourse.brew.sh。就我而言,omp.h 安装在 /usr/local/Cellar/libomp/10.0.0/include 下,符号链接到 /usr/local/include。 知道为什么Apple clang 需要-Xpreprocessor 标志吗?【参考方案4】:

带有 CMake 的 MacOS Mojave

    用 openmp 安装 LLVM,用 brew 安装 libomp

     brew update
     brew install llvm libomp
    

    CMakeList.txt中添加包含目录和链接目录

     include_directories("/usr/local/include" "/usr/local/opt/llvm/include")
     link_directories("/usr/local/lib" "/usr/local/opt/llvm/lib")
    

    使用新的编译器运行 CMake

     cmake -DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" ..
    

撰写本文时,clang 版本为 7.0.1

【讨论】:

在尝试在 macOS(它具有 libomp 作为依赖项)上构建 Blender 3 天后,这是对我有用的解决方案,尽管我的症状有点不同。对我来说,编译完成了,但是关于 libomp 库中缺少 x86_64 符号的链接器错误。截至本评论为止,这适用于 Homebrew 的 GCC 9.1.0。 CMakelists.txt 在哪里?我至少有 6 个以这种方式命名的文件。 非常感谢!它适用于 Clion 和 Mac OS 10.14.6 对这个答案的改进是使用brew --prefix llvm 而不是假设/usr/local/opt/llvm。类似execute_process(COMMAND brew --prefix llvm OUTPUT_VARIABLE LLVM_PREFIX) 可以在CMakeList.txt中添加set(CMAKE_C_COMPILER "/usr/local/opt/llvm/bin/clang") set(CMAKE_CXX_COMPILER "/usr/local/opt/llvm/bin/clang++"),这样就可以不用-D运行cmake了

以上是关于在 Mac OS X (sierra & Mojave) 中启用 OpenMP 支持的主要内容,如果未能解决你的问题,请参考以下文章

在 Mac OS X Sierra 上为 Django Python 安装 mysqlclient

在 mac os x sierra 上使用 opencv c++ 编译 hello world

sh Mac OS X High Sierra / PHP Apache httpd配置节点NPM

Mac git pull失败,最新操作系统导致 SSH issues with Mac OS X High Sierra

无法在 Mac OS X 10.13 High Sierra 中为自制软件 chown /usr/local

mac os下的Apache配置 macOS Sierra 10.12