【问题标题】:"Undefined reference" when linking C code in Linux在 Linux 中链接 C 代码时出现“未定义的引用”
【发布时间】:2011-05-03 11:18:04
【问题描述】:

我有一个代码库(完全用 C 编写),我通常在 Windows 下编译成 .DLL

我想在 Linux 下编译它,以便分发它。我不在乎我是否将其分发为 .a.so 或一堆 .o 文件。

所有单独的.c 文件都编译成功。但是当我尝试编译一个包含所有.o 文件的测试可执行文件时,我得到了一堆未定义的引用错误。

所有.o 文件都作为完整路径在命令行上,我没有收到任何有关丢失文件的错误。

cc testctd.c -o testctd.out -lm -lc $LIBRARY-PATH/*.o

我还对_open_write 等有未定义的引用。

【问题讨论】:

  • 能否粘贴完整的编译命令行和错误信息?
  • 您使用什么命令将内容链接到可执行文件中?除了 _open、_write 等,还有哪些未定义的引用?
  • 编辑显示命令行。错误消息是“未定义对 ... 的引用”,其中 ... 是 _open、_write 以及我的库中在程序中使用的一堆例程。
  • 我们能看到完整的、未经编辑的链接器输出吗?

标签: gcc linker undefined-reference cc


【解决方案1】:

你把 -l 选项放错地方了

-图书馆

-l 库

链接时搜索名为 library 的库。 (将库作为单独参数的第二种选择仅用于 POSIX 合规性>,不推荐。)

在命令的哪个位置编写此选项会有所不同;链接器按照指定的顺序搜索和处理库和目标文件。因此,

foo.o -lz bar.o

在文件 foo.o 之后但在 bar.o 之前搜索库 z。如果 bar.o 引用 z 中的函数,则可能不会加载这些函数。

链接器搜索库的标准目录列表,该库实际上是一个名为 liblibrary.a 的文件。链接器然后使用这个文件,就好像它是通过名称精确指定的一样。

【讨论】:

    【解决方案2】:

    您没有提供足够的信息来获得完整的答案,但我想我知道一个您的问题:函数openreadwriteclose、等在 Windows 上的名称前有下划线,但在 Linux(或任何其他 Unix 上)上它们。当您编译 .c 文件时,编译器应该会警告您——如果没有,请打开警告!无论如何,您将不得不删除所有这些下划线。我会推荐一个执行以下操作的头文件:

    #ifdef _WIN32
    #define open(p, f, m) _open(p, f, m)
    #define read(f, b, n) _read(f, b, n)
    #define write(f, b, n) _write(f, b, n)
    #define close(f) _close(f)
    /* etc */
    #endif
    

    然后在您的实际代码中只使用不带下划线的名称。

    另外,-l 选项(例如-lm)必须放在所有对象文件之后。没有必要指定-lc(这可能会导致问题,在这种情况下太神秘而无法进入这里)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-03
      • 2014-12-25
      • 2020-06-30
      • 1970-01-01
      • 2011-06-08
      • 2014-12-08
      • 1970-01-01
      相关资源
      最近更新 更多