c - OS X 链接器无法从仅包含变量的 C 文件中找到符号

标签 c macos linker ld unix-ar

我在将 C 库从 Linux (Ubuntu) 移植到 OS X 时遇到链接器问题。C 代码是从 Matlab 自动生成的,所以理想情况下我不想更改代码本身。

问题似乎出在一个 C 文件中,该文件仅包含未初始化的变量声明,然后被其他 C 文件外部化以实现 Matlab 算法。 OS X 链接器显然无法识别此文件中的符号。相同的源代码在 Linux 上工作正常,所以我想了解 OS X 链接器的行为有何不同,以及是否有一个标志我可以传递给它来改变行为。

静态库构建时没有错误/警告。但是在构建引用静态库的应用程序时,会抛出以下错误消息(在 OS X 上):

Undefined symbols for architecture x86_64:
  "_my_var", referenced from:
      _algorithm in libtestlibrary.a(algorithm.o)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

'nm' 表明 libteSTLibrary.a 确实包含符号 _my_var。

下面是来自 Matlab 的代码的简化版本。

库代码:

// DATA.C : declaration of data
#include "data.h"
int my_var;

// DATA.H - extern declaration of data
#ifndef H_DATA
#define H_DATA
extern int my_var;
#endif

// ALGORITHM.C - performs the calculation
#include "data.h"
int algorithm(int x) {
  my_var += x;
  return my_var;
}

//ALGORITHM.H - declaration of library API
#ifndef H_ALGORITHM
#define H_ALGORITHM
int algorithm(int x);
#endif

库构建命令:

gcc -c algorithm.c
gcc -c data.c
ar rcs libtestlibrary.a data.o algorithm.o

申请代码:

// MAIN.C : Code which calls into the static library
#include "algorithm.h"
int main() {
  int x = 1;
  x = algorithm(x);
  return 0;
}

应用程序构建命令:

gcc -c main.c
gcc -o testapp main.o -ltestlibrary

如果我将 data.c 中的定义更改为“int my_var=0”,以便初始化变量,则库和应用程序可以在 Linux 和 OS X 上正确构建。但是,正如我上面所说,我不' 不想更改代码,因为它是从 Matlab 自动生成的。

预先感谢您的帮助!

最佳答案

你的问题是你没有初始化may_var

如果您不初始化数据符号并将其放入静态库中,那么它将被创建为一个公共(public)符号。链接静态库时,我的 OS X 链接器无法识别它们。

如果你初始化它(data.c):

#include "data.h"
int my_var = 0;

然后编译器会将其放入不同的部分,并正确地链接到静态库中。

编辑:

或者,您可以将 -fno-common 选项传递给 gcc

gcc -c data.c -fno-common

然后这将指示 gcc 不要为未初始化的变量生成公共(public)符号,然后您可以将它们链接到库中。

这是 OS X 上 Mach-O 可执行格式的问题,描述为 here .

关于c - OS X 链接器无法从仅包含变量的 C 文件中找到符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19398742/

相关文章:

macos - -string 中的正确反斜杠定义(macOS 默认通过 shell 写入)

ruby - 在 RVM 中安装 Ruby 1.9.3 时出错 - Make error

c++ - 链接器如何确定链接到哪个函数?

visual-studio - 如何从 Visual Studio 获取确切的编译器命令行?

c - 如何在 NASM for Linux 中正确使用 C 函数 "Exp"?

c - 即使没有分配足够的内存,strcat() 和 strcpy() 也能工作

C LUA API - 获取索引处的表值

macos - Apples GCC 在哪里/如何在可执行文件中存储 DWARF

c++ - 链接错误在 32 位 XP 机器上构建 64 位 Qt 应用程序

c - 取消引用 int 指针与 char 指针