• Mac 使用 OpenMP/Clang


    新建 hello.cpp 文件:

    #include <omp.h>
    #include <stdio.h>
    int main() {
        #pragma omp parallel
        printf("Hello from thread %d, nthreads %d
    ", omp_get_thread_num(), omp_get_num_threads());
        return 0;
    }
    

    编译会遇到如下错误:

    hello.cpp:1:10: fatal error: 'omp.h' file not found
    #include <omp.h>
              ^~~~~~
    1 error generated.
    

    因为默认的 g++ 编译器不支持 openmp,我们可以设置 LLVM/Clang 编译器来编译 openmp。
    执行以下命令:

    brew install llvm # 安装 LLVM 编译器
    brew install libomp # 安装 OpenMP 库
    echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.bash_profile # 将 llvm 的可执行文件添加到 PATH 目录
    

    然后执行

    clang -fopenmp hello.cpp -o hello
    ./hello
    

    我的CPP文件中用到了STL 中的 vector,然后就遇到了新的错误:

    Undefined symbols for architecture x86_64:
      "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
          std::__1::vector<int, std::__1::allocator<int> >::assign(unsigned long, int const&) in seq-3efcea.o
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          void std::__1::vector<int, std::__1::allocator<int> >::__push_back_slow_path<int>(int&&) in seq-3efcea.o
      "std::logic_error::logic_error(char const*)", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "std::length_error::~length_error()", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)", referenced from:
          _main in seq-3efcea.o
      "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::insert(unsigned long, char const*)", referenced from:
          _main in seq-3efcea.o
      "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
          _main in seq-3efcea.o
      "std::terminate()", referenced from:
          ___clang_call_terminate in seq-3efcea.o
      "typeinfo for std::length_error", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "vtable for std::length_error", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
      "operator delete(void*)", referenced from:
          std::__1::__vector_base<int, std::__1::allocator<int> >::~__vector_base() in seq-3efcea.o
          std::__1::__deque_base<int, std::__1::allocator<int> >::~__deque_base() in seq-3efcea.o
          std::__1::__deque_base<int, std::__1::allocator<int> >::clear() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*> >::~__split_buffer() in seq-3efcea.o
          std::__1::__vector_base<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::~__vector_base() in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::~__split_buffer() in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          ...
      "operator new(unsigned long)", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "___cxa_allocate_exception", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "___cxa_begin_catch", referenced from:
          ___clang_call_terminate in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*> >::shrink_to_fit() in seq-3efcea.o
      "___cxa_end_catch", referenced from:
          std::__1::__split_buffer<int*, std::__1::allocator<int*> >::shrink_to_fit() in seq-3efcea.o
      "___cxa_free_exception", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "___cxa_throw", referenced from:
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::__split_buffer<int, std::__1::allocator<int>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int>&) in seq-3efcea.o
          std::__1::deque<int, std::__1::allocator<int> >::__add_back_capacity() in seq-3efcea.o
          std::__1::__split_buffer<int*, std::__1::allocator<int*>&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator<int*>&) in seq-3efcea.o
      "___gxx_personality_v0", referenced from:
          _main in seq-3efcea.o
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::vector(unsigned long, std::__1::vector<int, std::__1::allocator<int> > const&) in seq-3efcea.o
          std::__1::vector<std::__1::vector<int, std::__1::allocator<int> >, std::__1::allocator<std::__1::vector<int, std::__1::allocator<int> > > >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::vector(std::__1::vector<int, std::__1::allocator<int> > const&) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::allocate(unsigned long) in seq-3efcea.o
          std::__1::vector<int, std::__1::allocator<int> >::vector(unsigned long, int const&) in seq-3efcea.o
          void std::__1::vector<int, std::__1::allocator<int> >::__push_back_slow_path<int>(int&&) in seq-3efcea.o
          ...
    ld: symbol(s) not found for architecture x86_64
    clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)
    

    是因为我们编译的是 C++文件,clang 没有链接 STL 库所以出错了,我们可以显式地链接标准库:

    clang -fopenmp hello.cpp -o hello -lstdc++
    #或者 clang -fopenmp hello.cpp -o hello -lc++
    ./hello 
    

    也可以直接用 clang++:

    clang++ -fopenmp hello.cpp -o hello
    ./hello 
    
  • 相关阅读:
    zr#955 折纸
    zr#954 分组
    p2513 [HAOI2009]逆序对数列
    p4161 [SCOI2009]游戏
    p4593 [TJOI2018]教科书般的亵渎
    622FThe Sum of the k-th Powers
    spoj1811 LCS
    后缀自动机
    p5342 [TJOI2019]甲苯先生的线段树
    p5339 [TJOI2019]唱、跳、rap和篮球
  • 原文地址:https://www.cnblogs.com/flipped/p/9763996.html
Copyright © 2020-2023  润新知