2

I am trying create a C executable which depends on multiple C static libraries. I have two libraries : ../libs/libsulibs.a and ../ppm_client/libppm_client.a. libppm_client.a calls some functions of libsulibs.a

Here are my Makefiles

../libs/Makefile

LIBS=-lpthread
CC=gcc
CFLAGS=-Wall -g
INCLUDES=-I .
OBJ=WheelTimer.o threadApi.o LinkedListApi.o
TARGET=libsulibs.a
${TARGET}:$(OBJ)
    ar rs ${TARGET} $(OBJ)
%.o:%.c
     ${CC} ${CFLAGS} -c ${INCLUDES} $<
clean:
    rm *.o
    rm ${TARGET}

I successfully create libsulibs.a through this makefile

../ppm_client/Makefile

CC=gcc
CFLAGS=-Wall -g
INCLUDES=-I . -I ../libs -I ../ppm
OBJ=ppm_pkt_enums.o ppm_client.o ppm_client_sock.o
TARGET=libppm_client.a
${TARGET}:$(OBJ)
    ar rs ${TARGET} ${OBJ}
ppm_pkt_enums.o:ppm_pkt_enums.c
    gcc -g -c ${INCLUDES} ppm_pkt_enums.c -o ppm_pkt_enums.o
ppm_client.o:ppm_client.c
    gcc -g -c ${INCLUDES} ppm_client.c -o ppm_client.o
ppm_client_sock.o:ppm_client_sock.c
    gcc -g -c ${INCLUDES} ppm_client_sock.c -o ppm_client_sock.o
clean:
    rm *.o
    rm ${TARGET}

This makefile too successfully create the libppm_client.a.

Now, in current dir, I have main Makefile to create executable

CC=gcc
CFLAGS=-g -Wall
STANDARD_LIBS=-lpthread
PPM_OBJ=ppm.o ppm_main.o
LIBS_OBJ=libs/LinkedListApi.o libs/threadApi.o libs/WheelTimer.o
PPM_LIBS=../libs/libsulibs.a
PPM_CLIENT_LIBS=../ppm_client/libppm_client.a
INCLUDES=-I . -I ../libs -I ../ppm_client
TARGET:exe ${PPM_LIBS} ${PPM_CLIENT_LIBS}

ppm.o:ppm.c
    gcc -g -c ${INCLUDES} ppm.c -o ppm.o
ppm_main.o:ppm_main.c
    gcc -g -c ${INCLUDES} ppm_main.c -o ppm_main.o

${PPM_LIBS}:
    (cd ../libs; make)
${PPM_CLIENT_LIBS}:
    (cd ../ppm_client; make)
exe:${PPM_LIBS} ${PPM_OBJ} ${STANDARD_LIBS} ${PPM_CLIENT_LIBS}
    ${CC} ${CFLAGS} ${PPM_OBJ} -o exe -L ../libs -lsulibs -L ../ppm_client -lppm_client ${STANDARD_LIBS}
clean:
    rm *.o
    (cd ../libs; make clean)
    (cd ../ppm_client; make clean)
    rm exe

But when I run make, it ends up with the error : undefined reference to pthread_init . pthread_init is a function defined in libsulibs.a and is dependent on standard pthread library.

vm@vm:~/Documents/PeriodicPacketManager/ppm$ make
(cd ../libs; make)
make[1]: Entering directory `/home/vm/Documents/PeriodicPacketManager/libs'
gcc -Wall -g -c -I . WheelTimer.c
gcc -Wall -g -c -I . threadApi.c
gcc -Wall -g -c -I . LinkedListApi.c
ar rs libsulibs.a WheelTimer.o threadApi.o LinkedListApi.o
ar: creating libsulibs.a
make[1]: Leaving directory `/home/vm/Documents/PeriodicPacketManager/libs'
gcc -g -c -I . -I ../libs -I ../ppm_client ppm.c -o ppm.o
gcc -g -c -I . -I ../libs -I ../ppm_client ppm_main.c -o ppm_main.o
(cd ../ppm_client; make)
make[1]: Entering directory `/home/vm/Documents/PeriodicPacketManager/ppm_client'
gcc -g -c -I . -I ../libs -I ../ppm ppm_pkt_enums.c -o ppm_pkt_enums.o
gcc -g -c -I . -I ../libs -I ../ppm ppm_client.c -o ppm_client.o
gcc -g -c -I . -I ../libs -I ../ppm ppm_client_sock.c -o ppm_client_sock.o
ar rs libppm_client.a ppm_pkt_enums.o ppm_client.o ppm_client_sock.o
ar: creating libppm_client.a
make[1]: Leaving directory `/home/vm/Documents/PeriodicPacketManager/ppm_client'
gcc -g -Wall ppm.o ppm_main.o -o exe -L ../libs -lsulibs -L ../ppm_client -lppm_client -lpthread
../ppm_client/libppm_client.a(ppm_client_sock.o): In function `ppm_client_init_socket':
/home/vm/Documents/PeriodicPacketManager/ppm_client/ppm_client_sock.c:138: undefined reference to `pthread_init'
collect2: error: ld returned 1 exit status
make: *** [exe] Error 1

Kindly help what am I missing here.

dlmeetei
  • 9,905
  • 3
  • 31
  • 38
Abhishek Sagar
  • 1,189
  • 4
  • 20
  • 44
  • Link with `-lpthread` also – dlmeetei Jul 15 '17 at 04:19
  • 1
    ${STANDARD_LIBS} is -lpthread only. – Abhishek Sagar Jul 15 '17 at 04:20
  • 1
    Does moving the ${STANDARD_LIBS} in the front part helps? – dlmeetei Jul 15 '17 at 04:23
  • No, in that case. this is the error. gcc -g -Wall ppm.o ppm_main.o -o exe -lpthread -L ../libs -lsulibs -L ../ppm_client -lppm_client ../ppm_client/libppm_client.a(ppm_client_sock.o): In function `ppm_client_init_socket': /home/vm/Documents/PeriodicPacketManager/ppm_client/ppm_client_sock.c:138: undefined reference to `pthread_init' /home/vm/Documents/PeriodicPacketManager/ppm_client/ppm_client_sock.c:139: undefined reference to `pthread_create' collect2: error: ld returned 1 exit status make: *** [exe] Error 1 – Abhishek Sagar Jul 15 '17 at 04:24
  • this may help https://stackoverflow.com/questions/10201743/undefined-reference-to-pthread-init-when-using-lpthread-flag – army007 Jul 15 '17 at 04:28
  • No, i dont use -lpthread in Makefiles which create libraries. Could you pls tell, how to use -lpthread if at all to be used in related makefiles. – Abhishek Sagar Jul 15 '17 at 04:36
  • 2
  • Are you sure `pthread_init` is really defined in `libsulibs.a`. Did you check? e.g. with `nm libsulibs.a | grep pthread_init`? – Renaud Pacalet Jul 15 '17 at 06:49
  • vm@vm:~/Documents/PeriodicPacketManager/libs$ nm libsulibs.a | grep pthread_init U pthread_init 000004ed T pthread_init – Abhishek Sagar Jul 15 '17 at 08:37

1 Answers1

0

Woa !!

@Antti Haapalam

Changing the order of libraries worked.

In Main Makefile, i changed the order from :

${CC} ${CFLAGS} ${PPM_OBJ} -o exe -L ../libs -lsulibs -L ../ppm_client -lppm_client ${STANDARD_LIBS}

To:

${CC} ${CFLAGS} ${PPM_OBJ} -o exe -L ../ppm_client -lppm_client -L ../libs -lsulibs ${STANDARD_LIBS}

Can anyone comment the reasoning ?

Abhishek Sagar
  • 1,189
  • 4
  • 20
  • 44
  • I think, the order is , specify the dependent libraries first, and then independent one.In my case. libppm_client.a is dependent on libsulibs.a which in turn depends on pthread standard library. – Abhishek Sagar Jul 15 '17 at 08:44