【问题标题】:Linking multiple C libraries to C create executable [duplicate]将多个 C 库链接到 C 创建可执行文件
【发布时间】:2017-07-15 04:15:48
【问题描述】:

我正在尝试创建一个依赖于多个 C 静态库的 C 可执行文件。 我有两个图书馆: ../libs/libsulibs.a ../ppm_client/libppm_client.alibppm_client.a调用libsulibs.a的部分函数

这是我的 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}

我通过这个makefile成功创建了libsulibs.a

../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}

这个makefile也成功创建了libppm_client.a

现在,在当前目录中,我有主 Makefile 来创建可执行文件

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

但是当我运行make 时,它以错误结束:undefined reference to pthread_init。 pthread_init 是libsulibs.a 中定义的函数,依赖于标准pthread 库。

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

请帮助我在这里缺少什么。

【问题讨论】:

  • 链接-lpthread
  • ${STANDARD_LIBS} 仅适用于 -lpthread。
  • 移动前面的 ${STANDARD_LIBS} 有帮助吗?
  • 不,在这种情况下。这是错误。 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):在函数 @987654336 @pthread_init' /home/vm/Documents/PeriodicPacketManager/ppm_client/ppm_client_sock.c:139:未定义对“pthread_create”collect2的引用:错误:ld返回1退出状态make:*** [exe]错误1
  • 图书馆订购很重要

标签: c linux makefile compilation linker


【解决方案1】:

哇!

@Antti Haapalam

更改库的工作顺序。

在 Main Makefile 中,我更改了顺序:

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

收件人:

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

任何人都可以评论推理吗?

【讨论】:

  • 我想,顺序是,先指定依赖库,再指定独立库。就我而言。 libppm_client.a 依赖于 libsulibs.a,而 libsulibs.a 又依赖于 pthread 标准库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多