-1

I am working on a project that uses some code written by someone else inside a folder called CommandParser. My project is called TCP_IP and inside it there is the CommandParser folder. enter image description here

This is my makefile.

TARGET = $(BIN_DIR)/sim_tcp_ip
LIBS = -lpthread -L ./CommandParser -lcli
OBJS = $(OBJ_DIR)/prueba.o \
       $(OBJ_DIR)/ListaEnlazada.o \
       $(OBJ_DIR)/Grafico.o \
       $(OBJ_DIR)/Net.o \
       $(OBJ_DIR)/Topologias.o
BIN_DIR = ./bin
OBJ_DIR = ./obj
INC_DIR = ./inc
SRC_DIR = ./src
CFLAGS = -Wall -I$(INC_DIR)

$(TARGET): $(OBJS) CommandParser/libcli.a
    mkdir -p $(BIN_DIR)
    gcc $(CFLAGS) $(OBJS) -o $(TARGET) $(LIBS)
    
$(OBJ_DIR)/%.o : %.c
    mkdir -p $(OBJ_DIR)
    gcc -c -MD $(CFLAGS) $< -o $@
    
CommandParser/libcli.a:
    (cd CommandParser; make)

-include $(OBJ_DIR)/*.d
    
.PHONY: clean
clean:
    rm -rf $(OBJ_DIR) $(BIN_DIR)
    (cd CommandParser; make clean)
all:
    make
    (cd CommandParser; make)

CommandParser has its own makefile.

CC=gcc
CFLAGS=-g -Wall
INCLUDES=-I .
CLILIB=libcli.a
TARGET:exe ${CLILIB}
OBJ=cmd_hier.o parser.o serialize.o string_util.o clistd.o clicbext.o gluethread/glthread.o ut/utinfra/ut_parser.o
exe:testapp.o ${CLILIB}
    @echo "Building final executable"
    @ ${CC} ${CFLAGS} ${INCLUDES} testapp.o -o exe -L . -lcli -lpthread -lrt
cmd_hier.o:cmd_hier.c
    @echo "Building cmd_hier.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} cmd_hier.c -o cmd_hier.o
parser.o:parser.c
    @echo "Building parser.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} parser.c -o parser.o
gluethread/glthread.o:gluethread/glthread.c
    @echo "Building gluethread/glthread.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} gluethread/glthread.c -o gluethread/glthread.o
serialize.o:serialize.c
    @echo "Building serialize.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} serialize.c -o serialize.o
string_util.o:string_util.c
    @echo "Building string_util.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} string_util.c -o string_util.o
clistd.o:clistd.c
    @echo "Building clistd.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} clistd.c -o clistd.o
clicbext.o:clicbext.c
    @echo "Building clicbext.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} clicbext.c -o clicbext.o
testapp.o:testapp.c
    @echo "Building testapp.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} testapp.c -o testapp.o
ut/utinfra/ut_parser.o:ut/utinfra/ut_parser.c
    @echo "Building ut/utinfra/ut_parser.o"
    @ ${CC} ${CFLAGS} -c ${INCLUDES} ut/utinfra/ut_parser.c -o ut/utinfra/ut_parser.o
${CLILIB}: ${OBJ}
    @echo "Building Library ${CLILIB}"
    ar rs ${CLILIB} ${OBJ}
clean:
    rm -f exe
    rm -f *.o
    rm -f gluethread/*.o
    rm -f ut/utinfra/*.o
    rm -f ${CLILIB}
    rm -f CMD_HIST_RECORD_FILE.txt
install:
    cp ${CLILIB} /usr/local/lib/
    cp libcli.h /usr/include/
    cp cmdtlv.h /usr/include/
uninstall:
    rm -f /usr/local/lib/${CLILIB}
    rm -f /usr/include/libcli.h
    rm -f /usr/include/cmdtlv.h

When do make inside CommandParser, I don't get any error. However, something seems to be wrong with my makefile because if I do make in my TCP_IP folder, I get some undefined reference errors.

/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función ut_parser_init': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:52: referencia a mq_open' sin definir

/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función run_test_case': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:261: referencia a mq_timedreceive' sin definir

/usr/bin/ld: ./CommandParser/libcli.a(ut_parser.o): en la función cli_out': /home/darinel/Documentos/Cursos/C++/TCP_IP/CommandParser/ut/utinfra/ut_parser.c:517: referencia a mq_send' sin definir

collect2: error: ld returned 1 exit status

make: [makefile:16: bin/sim_tcp_ip] Error 1

The message shows that these errors come from the CommandParser code, and not from my code, even though it previously worked fine in the CommandParser folder.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
EmTor
  • 107
  • 9
  • Please don't paste images to StackOverflow; instead cut and paste the text into your question with proper formatting. Images are not searchable, we cannot cut/paste content into answers, and they aren't easy to read for some people. Thanks! – MadScientist Sep 06 '21 at 01:03

1 Answers1

3

It appears that the CommandParser library is looking for another library, that contains functions like mq_open, mq_send, and mq_timedreceive. If you look up these functions you'll see that they're provided by the realtime library, librt. So, you need to add the -lrt option to your link line.

Also, please pay close attention to the order of libraries on the link line. You should always order them highest-level to lowest-level. You have:

LIBS = -lpthread -L ./CommandParser -lcli

but -lpthread is a lower-level library so it should come after -lcli. Also, the modern way of building executables using threads is to use the -pthread option on BOTH the compile line AND the link line, so you should use:

LIBS = -pthread -L ./CommandParser -lcli -lrt

CFLAGS = -pthread -Wall -I$(INC_DIR)
MadScientist
  • 92,819
  • 9
  • 109
  • 136