Reputation: 343
I am trying to build my program but keep getting the same error messages:
undefined reference to pthread_create
undefined reference to pthread_join
I have included pthread.h and in my makefile im compiling with -pthread
.
int threadAmount = strtol(nrthr, NULL, 0);
threadAmount--;
if(threadAmount > 0){
pthread_t tids[threadAmount];
for(int i = 0;i < threadAmount; i++){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tids[i],&attr,search,&t1);
}
for(int i = 0;i < threadAmount; i++){
pthread_join(tids[i],NULL);
}
}
It's where I'm calling create and join where it's complaining. What could be the problem?
The makefile used to build:
CC=gcc
CFLAGS= -pthread -std=gnu11 -Wall -Wextra -Werror -Wmissing-declarations -Wmissing-prototypes -Werror-implicit-function-declaration -Wreturn-type -Wparentheses -Wunused -Wold-style-definition -Wundef -Wshadow -Wstrict-prototypes -Wswitch-default -Wunreachable-code
all: mfind
list.o: list.c list.h
$(CC) -c list.c $(CFLAGS)
mfind.o: mfind.c list.h
$(CC) -c mfind.c $(CFLAGS)
mfind: mfind.o list.o
$(CC) mfind.o list.o -o mfind
clean:
rm -f *.o mfind
mfind
is the main program and list.c
is an implemented list.
Upvotes: 5
Views: 12696
Reputation: 102376
list.o: list.c list.h $(CC) -c list.c $(CFLAGS) mfind.o: mfind.c list.h $(CC) -c mfind.c $(CFLAGS) mfind: mfind.o list.o $(CC) mfind.o list.o -o mfind
It looks like some of your recipes are missing CFLAGS
, which includes the option -pthread
. I believe it should be:
list.o: list.c list.h
$(CC) $(CFLAGS) -c list.c
mfind.o: mfind.c list.h
$(CC) $(CFLAGS) -c mfind.c
mfind: mfind.o list.o
$(CC) $(CFLAGS) mfind.o list.o -o mfind
...
Its OK to CFLAGS
to the output artifact. In fact, you should use the same CFLAGS
(and CXXFLAGS
) when the compiler driver drives link. You should also always use the compiler driver because it takes care of turning options, like -pthread
, -fopenmp
and -fsanitize=undefined
, into the proper options and libraries for the linker.
If interested, here are the default rule used with GNUmake: Catalogue of Built-In Rules. Notice the recipe for *.c
files includes CFLAGS
:
Compiling C programs
n.o
is made automatically fromn.c
with a recipe of the form$(CC) $(CPPFLAGS) $(CFLAGS) -c
.
If you use the following from the GNU Make manual, then you should also add -pthread
to LDFLAGS
. But I recommend you follow what the compiler guys tell us, and that is to drive link through the compiler driver.
Linking a single object file
n
is made automatically fromn.o
by running the linker (usually calledld
) via the C compiler. The precise recipe used is$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
.
Upvotes: 2
Reputation: 121417
-pthread
doesn't belong in CFLAGS
. As you already found, the libraries that are needed must be at the end of the command line options after all the object files. You need to put -pthread
in LDLIBS
since you have a makefile.
From https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html:
LDLIBS
Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.
Upvotes: 1