0

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

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

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

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

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

我也对 , 等有未定义的_open引用_write

4

2 回答 2

2

你在错误的地方有 -l 选项

-图书馆

-l 库

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

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

foo.o -lz bar.o

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

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

于 2010-11-01T15:09:28.707 回答
2

您没有提供足够的信息来获得完整的答案,但我想我知道您的一个问题:函数open, read, write,close等在 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(并且在过于神秘的情况下可能会导致问题,无法进入这里)。

于 2010-11-01T15:06:52.367 回答