Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using openmp on windows with mingw. Cannot find -lpthread

I have a CMake project which is using OpenMP and works on linux. When I went to compile it on my windows machine it looked like CMake was having trouble finding the openmp flags for mingw's gcc.

I decided to try a smaller test case and just compile 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;
}

Then when I try to compile

gcc -o OpenMPTest2 main_testomp.c -fopenmp

I get

>>> 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

I attempted to find the solution online and tried variants of -lgomp, -lpthreadgc2, and -lpthreadvc2, with no improvement.

I searched my C:\MinGw directory recursively for any filenames containing lpthread and got this:

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

I'm not sure if I'm missing a flag, or a package, or what I'm doing wrong. For good measure here is the output of 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)

Any idea what's wrong?

like image 662
Erotemic Avatar asked May 09 '14 00:05

Erotemic


People also ask

Is OpenMP installed by default?

OpenMP is not something that you install. It comes with your compiler. You just need a decent compiler that supports OpenMP and you need to know how to enable OpenMP support since it is usually disabled by default.


2 Answers

I was finally able to get things working.

First, using mingw-get I installed mingw32-pthreads-w32

This allowed me to use the -fopenmp flag with gcc.

But when using CMake I had to include the lines:

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()

as normal, but I also had to make sure I had the OpenMP_CXX_FLAGS in my target_link_libraries command

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})
like image 134
Erotemic Avatar answered Oct 06 '22 10:10

Erotemic


In your CMakeLists.txt file, you should use the following:

find_package(OpenMP REQUIRED)

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

If you get an error when you are configuring cmake, then that means you don't have the necessary libraries, or at least cmake can't find them. If you have the libraries and cmake can't find them, then make sure the find path is set:

set (CMAKE_FIND_ROOT_PATH C:/MinGW)

You might want to try creating a "toolchain" file as described here.

I would also suggest you try mingw-w64 for cross-compiling for Windows. I use it successfully for both 32-bit and 64-bit applications. I use mingw[32/64]-cmake, and then everything just works.

I'm using Fedora 19 and 20, and some packages relevant to your question are (for 32-bit):

mingw32-filesystem
mingw32-libgomp
like image 39
Patrick Avatar answered Oct 06 '22 09:10

Patrick