在Windows上使用Mingw和OpenMP。无法找到-lpthread。

7
我有一个使用OpenMP的CMake项目,可以在Linux上运行。但是当我尝试在Windows机器上编译它时,CMake似乎无法找到mingw's gcc的openmp标志。
我决定尝试一个更小的测试案例,只编译main_openmp.c文件。
#include <omp.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
    int id;
    #pragma omp parallel private(id)
        {
        id = omp_get_thread_num();
        printf("%d: Hello World!\n", id);
        }
    return 0;
}

然后,当我尝试编译时。
gcc -o OpenMPTest2 main_testomp.c -fopenmp

我理解

>>> gcc -o OpenMPTest2 main_testomp.c -fopenmp
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lpthread
collect2.exe: error: ld returned 1 exit status

我试图在网上找到解决方案,并尝试使用-lgomp、-lpthreadgc2和-lpthreadvc2的变体,但没有改善。

我递归地搜索了我的C:\MinGw目录,查找任何包含lpthread的文件名,结果如下:

C:\MinGW\bin\pthreadgc2.dll
C:\MinGW\bin\pthreadgce2.dll
C:\MinGW\var\cache\mingw-get\packages\pthreads-w32-2.9.1-1-mingw32-dll.tar.lzma
C:\MinGW\var\lib\mingw-get\data\mingw32-pthreads-w32.xml

我不确定是否缺少标志、包或者我做错了什么。为了保险起见,这里是gcc -v的输出结果。

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic
 --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --ena
ble-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32
-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gm
p-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-sy
stem-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv
-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIM
E_T
Thread model: win32
gcc version 4.8.1 (GCC)

有什么想法是出了什么问题?
3个回答

21

我终于成功让事情运作起来了。

首先,我使用mingw-get安装了mingw32-pthreads-w32。

这使我能够在gcc中使用-fopenmp标志。

但是,在使用CMake时,我必须包含以下几行:

message(STATUS "Checking OpenMP")
find_package(OpenMP)
IF(OPENMP_FOUND)
    message("Found OpenMP! ^_^")
    # add flags for OpenMP
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenMP_SHARED_LINKER_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
ELSE()
    message("Missed OpenMP! x_x")
ENDIF()

除了正常操作外,我还必须确保在我的target_link_libraries命令中使用了OpenMP_CXX_FLAGS。

set(SOURCE_FILES 
    src/foo.cpp 
    src/bar.cpp
    src/baz.cpp)
add_library(<mylib> SHARED ${SOURCE_FILES})
target_link_libraries(<mylib> ${OpenMP_CXX_FLAGS})

3
在你的 CMakeLists.txt 文件中,你应该使用以下内容:
find_package(OpenMP REQUIRED)

set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")

如果在配置cmake时出现错误,那么这意味着您没有必要的库,或者至少cmake找不到它们。如果您有这些库但是cmake找不到它们,请确保设置了查找路径:
set (CMAKE_FIND_ROOT_PATH C:/MinGW)

您可能想尝试创建一个“toolchain”文件,如此处所述:这里
我还建议您尝试使用mingw-w64进行跨平台编译Windows。我成功地使用它编译了32位和64位应用程序。我使用mingw[32/64]-cmake,然后一切都顺利运行。
我正在使用Fedora 19和20,与您的问题相关的一些软件包是(32位):
mingw32-filesystem
mingw32-libgomp

我在我的CMakeLists.txt中有那行代码,但我不确定为什么它找不到包。我会看一下mingw-w64。我有C:\MinGW\bin\libgomp-1.dll。当我在C:\MinGW中搜索filesystem时,我什么也没找到,在mingw-get窗口中也没有类似的东西。我该如何安装它? - Erotemic
我尝试了工具链和设置cmake_find_root_path,但两个想法都失败了。路径应该使用Windows风格的路径,而且不应该用引号括起来,对吧? - Erotemic
@Erotemic,cmake在Windows上处理正斜杠,我认为您不需要为设置根路径使用引号(链接中的示例未使用引号)。 您设置了CMAKE_FIND_ROOT_PATH而不是cmake_find_root_path,对吗? 在cmake中,变量名区分大小写。 - Patrick
是的,我在脚本中使用了allcaps变量。我还没有时间研究mingw-w64,但是当我开始研究时,我会告诉你进展如何。 - Erotemic

2

非常简单的步骤,适用于我:

  • 打开MinGW安装管理器
  • 在左侧找到MinGW标准库部分
  • 安装mingw32-pthreads-w32包。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接