代码之家  ›  专栏  ›  技术社区  ›  Daniel P.

无法编译和链接动态库

  •  1
  • Daniel P.  · 技术社区  · 6 年前

    我试图通过在共享库中定义函数来编译一个简单的hello世界,但是在编译主程序时,我得到了:

    /tmp/hello-ca67ea.o: In the function 'main':
    hello.c:(.text+0x1a): reference to 'greeting(char const*)' not defined
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    我都试过了 铿锵声 海湾合作委员会 同样的错误也会发生。

    我已经搜索过了,但没有找到类似的东西。

    这个 目录 如下:

    shared-test
     |
     |--greeting.c
     |--greeting.h
     |--hello.c
    

    你好,C

    #include "greeting.h"
    
    int main ()
    {
        greeting("Daniel");
        return 0;
    }
    

    问候

    #ifndef GREETING_H
    #define GREETING_H
    
    void greeting(const char* text);
    
    #endif
    

    问候

    #include <stdio.h>
    #include "greeting.h"
    
    void greeting(const char* text)
    {
        printf("%s\n", text);
    }
    

    问候。 正在用编译 clang greeting.c -o greeting.so -shared -fPIC

    我正在编译hello with clang hello.c -o hello -Igreeting

    有人能帮我找出我做错了什么吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Petr Skocik    6 年前

    clang hello.c -o hello -Igreeting

    尝试编译 和链接 ,但您没有提供要链接的库的名称:

    clang hello.c -o hello -Igreeting greeting.so #<= greeting.so added
    

    然后,您应该能够使用以下命令运行输出:

    LD_LIBRARY_PATH=. ./hello 
    

    其思想是将lib放在系统库路径中,因为您没有这样做,所以ld_library_path环境变量是一种黑客,可以让它在没有它的情况下工作。

    在Linux上使用gcc/clang,还可以硬编码完整路径:

    clang hello.c -o hello -Igreeting $PWD/greeting.so
    

    或者,您可以让动态链接器搜索与可执行文件位置相关的依赖项

    clang hello.c -o hello -Igreeting '-Wl,-rpath=$ORIGIN' greeting.so
    

    使用上述两种方法中的任何一种,您都不需要 LD_LIBRARY_PATH=. 部分不再。

    动态图书馆还有很多,我建议你多研究一下,例如,从乌尔里希·德雷珀那里 DSO Howto 编撰。

    推荐文章