新建 hello.cpp 文件:
#include
#include
int main() {
#pragma omp parallel
printf("Hello from thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
return 0;
}
编译会遇到如下错误:
hello.cpp:1:10: fatal error: 'omp.h' file not found
#include
^~~~~~
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::__throw_length_error() const", referenced from:
std::__1::vector >::assign(unsigned long, int const&) in seq-3efcea.o
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
void std::__1::vector >::__push_back_slow_path(int&&) in seq-3efcea.o
"std::logic_error::logic_error(char const*)", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"std::length_error::~length_error()", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"std::__1::basic_string, std::__1::allocator >::__init(char const*, unsigned long)", referenced from:
_main in seq-3efcea.o
"std::__1::basic_string, std::__1::allocator >::insert(unsigned long, char const*)", referenced from:
_main in seq-3efcea.o
"std::__1::basic_string, std::__1::allocator >::~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::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"vtable for std::length_error", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) 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 >::~__vector_base() in seq-3efcea.o
std::__1::__deque_base >::~__deque_base() in seq-3efcea.o
std::__1::__deque_base >::clear() in seq-3efcea.o
std::__1::__split_buffer >::~__split_buffer() in seq-3efcea.o
std::__1::__vector_base >, std::__1::allocator > > >::~__vector_base() in seq-3efcea.o
std::__1::__split_buffer&>::~__split_buffer() in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
...
"operator new(unsigned long)", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"___cxa_allocate_exception", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"___cxa_begin_catch", referenced from:
___clang_call_terminate in seq-3efcea.o
std::__1::__split_buffer >::shrink_to_fit() in seq-3efcea.o
"___cxa_end_catch", referenced from:
std::__1::__split_buffer >::shrink_to_fit() in seq-3efcea.o
"___cxa_free_exception", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"___cxa_throw", referenced from:
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
std::__1::deque >::__add_back_capacity() in seq-3efcea.o
std::__1::__split_buffer&>::__split_buffer(unsigned long, unsigned long, std::__1::allocator&) in seq-3efcea.o
"___gxx_personality_v0", referenced from:
_main in seq-3efcea.o
std::__1::vector >, std::__1::allocator > > >::vector(unsigned long, std::__1::vector > const&) in seq-3efcea.o
std::__1::vector >, std::__1::allocator > > >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::vector(std::__1::vector > const&) in seq-3efcea.o
std::__1::vector >::allocate(unsigned long) in seq-3efcea.o
std::__1::vector >::vector(unsigned long, int const&) in seq-3efcea.o
void std::__1::vector >::__push_back_slow_path(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