Reputation: 3374
I am trying to compile the following program with mingw:
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <iostream>
#include <cstdio>
void *hello(void *id) {
int nid = *static_cast<int*>(id);
std::printf("Hello from thread %d\n", nid);
return 0;
}
int main(int argc, char **argv) {
pthread_t ids[2];
int *params[2];
for (int i = 0; i < 2; ++i) {
params[i] = new int;
*params[i] = i;
pthread_create(&ids[i], 0, hello, params[i]);
}
for (int i = 0; i < 2; ++i)
pthread_join(ids[i], 0);
for (int i = 0; i < 2; ++i)
delete params[i];
return 0;
}
using this command:
g++ -lpthread -ohello.exe hello.cc
And I get the following message:
C:\Users\XXXXXX~1\AppData\Local\Temp\cczPlv0w.o:hello.cc:(.text+0xad): undefined
reference to `_imp__pthread_create'
C:\Users\XXXXXX~1\AppData\Local\Temp\cczPlv0w.o:hello.cc:(.text+0xe9): undefined
reference to `_imp__pthread_join'
collect2: ld returned 1 exit status
But with an older version of MingGW I had no problems running pthreads programs. (This is just the simple of all the programs that failed, but basically everything that uses pthreads ends up with the same error, C and C++)
Upvotes: 3
Views: 10427
Reputation: 206861
Move -lpthread
to the end of that command:
g++ -ohello.exe hello.cc -lpthread
The order of the arguments is important. (Using -pthread
throughout instead of -lpthread
for linking is actually recommended, since it sets flags both for the preprocessor and the linker.)
Upvotes: 9
Reputation: 882326
Library specifications are position dependent with gcc
, it will only bring in unresolved symbols at the point where the library is listed.
Because you haven't listed your main object file at that point, the only unresolved symbol is main
. You need to move the library specifications to the point where there will be unresolved symbols they can satisfy.
I've never really understood why gcc
chose this path since it sometimes leads to situations where you have to list libraries more than once (such as with circular dependencies). The only reason I've ever thought of is to keep control as to what libraries are allowed to resolve specific symbols.
I've seen more "intelligent" linkers where they simply batch up all the libraries till the end then go through them over and over again until either all symbols are satisfied or there is no chance that they can be. This saves a lot of effort but you do lose that aforementioned control.
Upvotes: 3