通过makefile链接共享库

问题描述 投票:0回答:1

代码按预期编译,但不知何故,二进制文件不知道库在哪里。

❯ ldd myteams_cli 
        linux-vdso.so.1 (0x00007ffcbc1b4000)
        libmyteams.so => not found
        libc.so.6 => /usr/lib/libc.so.6 (0x00007414e0bf3000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007414e0e1d000)

这是Makefile,我知道它找到了库,因为当我故意拼错库名称时它无法编译:

CFLAGS  = -Wall -Wextra -Werror -L../libs/myteams -lmyteams
NAME    = myteams_cli

SRC =   src/main.c  \

OBJ_DIR = obj
OBJ = $(SRC:%.c=$(OBJ_DIR)/%.o)

$(OBJ_DIR)/%.o: %.c
    @mkdir -p $(@D)
    @$(CC) $(CFLAGS) -c $< -o $@

all:    $(NAME)

$(NAME):    $(OBJ)
    @mkdir -p $(@D)
    gcc -o $(NAME) $(OBJ) $(CFLAGS)

clean:
    rm -f $(OBJ_DIR)/*.o
    rm -rf $(OBJ_DIR)/src

fclean: clean
    rm -f $(NAME)

re: fclean all

此外,项目编译后,二进制文件必须立即可执行。每次我想启动程序时,我不能只将库路径添加到我的

LD_LIBRARY_PATH
环境变量中(顺便说一下,它可以工作),也不能将库复制到
/usr/lib
,因为这需要触发 Makefile
sudo

c makefile linker shared-libraries dynamic-library
1个回答
2
投票

链接器的

-L
选项设置 链接时搜索路径。这仅在链接程序时有效,它不会更改运行时搜索路径,这是程序在运行时查找库的位置。正如评论中提到的,您想使用链接器选项
-rpath
。大多数编译器不知道该选项,因此您必须使用(对于 GCC 和 clang)
-Wl,-rpath

如果您在网上搜索“设置运行时搜索路径”和/或“rpath”,您会发现很多有用的信息。

在你的 makefile 中,你确实需要区分 linker 选项和 compiler 选项;像

CFLAGS
这样将它们全部放入同一个变量中是不好的。
CFLAGS
(按照惯例)是编译器标志。您应该使用
LDFLAGS
作为链接器标志,使用
LDLIBS
作为要链接的库(按照惯例)。所以尝试这样的事情:

CFLAGS  = -Wall -Wextra -Werror
LDFLAGS = -L../libs/myteams -Wl,-rpath=../libs/myteams
LDLIBS = -lmyteams

  ...

$(NAME):    $(OBJ)
        @mkdir -p $(@D)
        gcc -o $(NAME) $(CFLAGS) $(LDFLAGS) $(OBJ) $(LDLIBS)

(通常我们也会将编译器标志传递给链接器,以防万一)

© www.soinside.com 2019 - 2024. All rights reserved.