OS X链接器无法从仅包含变量的C文件中找到符号 [英] OS X linker unable to find symbols from a C file which only contains variables
问题描述
将C库从Linux(Ubuntu)移植到OS X时,链接器出现问题.C代码是从Matlab自动生成的,因此理想情况下,我不想更改代码本身.
I am having problems with the linker when porting a C library from Linux (Ubuntu) to OS X. The C code is auto-generated from Matlab, so ideally I don't want to change the code itself.
问题似乎出在C文件中,其中仅包含未初始化的变量声明,然后其他C文件对其进行扩展以实现Matlab算法.OS X链接器显然无法识别该文件中的符号.相同的源代码在Linux上可以正常工作,因此我想了解OS X链接器的行为方式是否不同,以及是否可以传递给我一个标志来更改行为.
The problem seems to be in a C file which contains ONLY uninitialised variable declarations, which are then EXTERNed by other C files to implement the Matlab algorithms. The OS X linker is apparently unable to recognise symbols from this file. The same source code works fine on Linux, so I want to understand how the OS X linker is behaving differently, and whether there is a flag I can pass to it to change the behaviour.
静态库的构建没有错误/警告.但是,当构建引用静态库的应用程序时,会抛出以下错误消息(在OS X上):
The static library builds without errors/warnings. But when building an application which references the static library, the following error message (on OS X) is thrown:
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.
An 'nm' shows that libtestlibrary.a does indeed contain symbol _my_var.
下面是Matlab代码的简化版本.
A much simplified version of the code from Matlab follows below.
库代码:
// 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自动生成的.
If I change the definition in data.c to 'int my_var=0', so that the variable is initialised, then the library and application build correctly on both Linux and OS X. However, as I said above, I don't want to change the code because it is auto-generated from Matlab.
提前感谢您的帮助!
推荐答案
您的问题是您没有初始化 may_var
.
Your problem is that you do not initialise may_var
.
如果不初始化数据符号并将其放入静态库,则会将其创建为通用符号.链接静态库时,那些不能在OS X链接器中识别.
If you do not initialise a data symbol and put it into a static library then it will be created as a common symbol. Those are not recognised my the OS X linker when linking static libraries.
如果您将其初始化(data.c):
If you initialise it (data.c):
#include "data.h"
int my_var = 0;
然后,编译器会将其放在不同的部分,并将正确链接到静态库中.
Then the compiler will put it into a different section and it will properly link in a static library.
或者,您可以将 -fno-common
选项传递给gcc
Alternatively you can pass the -fno-common
option to gcc
gcc -c data.c -fno-common
然后这将指示 gcc
不要为未初始化的变量生成通用符号,然后可以在库中链接它们.
Then this will instruct gcc
not to generate common symbols for uninitialised variables and then you can link them in libraries.
This is an issue with the Mach-O executable format on OS X and is described here.
这篇关于OS X链接器无法从仅包含变量的C文件中找到符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!