【问题标题】:Simple OpenMP-enabled code does not compile: "clang: error: linker command failed with exit code 1"启用 OpenMP 的简单代码无法编译:“clang:错误:链接器命令失败,退出代码为 1”
【发布时间】:2021-12-12 08:37:00
【问题描述】:

我尝试使用 Xcode 附带的 Apple Clang 编译器在 MacOS 上测试 OpenMP。

代码:

#include <iostream>
#include <cmath>
#include </usr/local/opt/libomp/include/omp.h>

int main() {
    std::cout << "Hello, World!" << std::endl;
    #pragma omp parallel
    {
        printf("Hello World! \n");
    }
    return 0;
}

这是我的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.19)
project(untitled)

set(CMAKE_CXX_STANDARD 14)
include (FindOpenMP)
if (OPENMP_FOUND)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
    message (VERBOSE "OpenML library found")
else()
    message (FATAL_ERROR "OpenML library not found (required for multithreading)")
endif ()
add_executable(untitled main.cpp)

这是编译器的错误:

Scanning dependencies of target untitled
[ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
[100%] Linking CXX executable untitled
Undefined symbols for architecture x86_64:
  "___kmpc_fork_call", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2

OpenMP 是使用 hombrew libomp 安装的,我也尝试添加环境变量 LDFLAGS=-L/usr/local/opt/libomp/lib/ 并不会影响结果


更新:使用 VERBOSE=1 进行编译:

...
[100%] Linking CXX executable untitled
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_link_script CMakeFiles/untitled.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/c++  -Xclang -fopenmp -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names -L/usr/local/opt/libomp/lib/  CMakeFiles/untitled.dir/main.cpp.o -o untitled 
Undefined symbols for architecture x86_64:
  "___kmpc_fork_call", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [untitled] Error 1
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2

【问题讨论】:

  • 你能用make VERBOSE=1添加详细make的输出吗?这看起来像在链接行,-fopenmp 没有正确传递。
  • 尽管在highly upvoted answer 中写了什么,变量OpenMP_EXE_LINKER_FLAGS 从未创建,即它的取消引用给出了一个空字符串。由于您需要 CMake 3.19,因此最好(且更简单)使用 IMPORTED 库,如 other answer 中所述。

标签: c++ cmake clang openmp


【解决方案1】:

通过使用set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") 并在其他地方使用set,您正在替换CMAKE 放置的标志。在这种情况下最好追加而不是替换。你可以使用add_compile_options(-Wall)here

正如@Tsyvarev 所提到的,使用导入的库可能会更好。 Here 是您可以使用 target_link_libraries 的其他几种方式。

对于您的特殊情况,最好更换

find_package(OpenMP REQUIRED)

您当前拥有include (FindOpenMP) 的位置。此外,还要删除 if 条件。最后,将以下内容添加到 CMakeLists.txt 文件的末尾。

target_link_libraries(
  untitled
  PRIVATE
  OpenMP::OpenMP_CXX
)

Here 很好地解释了 PRIVATE 和 PUBLIC 之间的区别。

您的最终 CMakeLists.txt 文件应如下所示:

cmake_minimum_required(VERSION 3.19)
project(untitled)

set(CMAKE_CXX_STANDARD 14)
find_package(OpenMP REQUIRED)

add_executable(
  untitled 
  main.cpp
)

target_link_libraries(
  untitled
  PRIVATE
  OpenMP::OpenMP_CXX
)

感谢 Tsyvarev 在几个月前帮助我使用 CMake。此外,感谢 Tsyvarev 指出的答案,我的答案基于(以及我自己的测试)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多