【问题标题】:Creating static Mac OS X C build创建静态 Mac OS X C 构建
【发布时间】:2011-07-12 16:02:58
【问题描述】:

如何在 Mac OS X 上创建 .c 文件的静态构建?当我尝试时:

gcc -o test Main.c -static

我明白了:

ld: library not found for -lcrt0.o
collect2: ld returned 1 exit status

【问题讨论】:

标签: c macos gcc static


【解决方案1】:

Mac OS X 的 gcc 不支持它:

http://discussions.apple.com/message.jspa?messageID=11053384

也许“-static”标志在 MacOS X 上不起作用。并非 gcc 的所有功能都在 MacOS X 上实现。Apple 甚至不会在未来版本的操作系统中使用 gcc。

我不知道如何使用“-static”进行链接。我想不出任何理由在 MacOSX 上这样做。如果我知道您为什么要使用“-static”,我可能会对这个问题更感兴趣。现在,我只是不明白。通过寻求帮助,您实际上是在寻求项目的合作者——即使只有 10 分钟。你需要让我感兴趣。

还有http://developer.apple.com/library/mac/#qa/qa2001/qa1118.html

Mac OS X 不支持用户二进制文件的静态链接。将用户二进制文件绑定到 Mac OS X 库和接口的内部实现会限制我们更新和增强 Mac OS X 的能力。相反,支持动态链接(链接例如,自动针对 crt1.o 而不是寻找 crt0.o)。

我们强烈建议您仔细考虑静态链接的局限性,并考虑您的客户及其需求,以及您需要提供的长期支持。

更新:禁止的是静态二进制文件。但是您仍然可以编译一些静态库并将其与另一个程序一起使用。程序将与您的库静态链接,但 libc 等其他库将是动态的,因此程序将是动态可执行文件。

【讨论】:

  • 在编译中使用-static 的一个原因是创建内核。我最近也遇到了这个问题。这是否意味着不能在 OS X 机器上开发内核?
  • 内核(OS内核)的链接在任何情况下都是一个特殊的阶段。内核通常没有外部库(所谓的 C 语言独立模式,gcc 的-nostdlib-nodefaultlibs 选项;不会使用 crt* 文件),并且不链接到典型的对象格式(ELF/Mach-O;或者至少不使用动态链接器 ld.so)。特殊的链接描述文件和一些后处理用于将对象转换为原始二进制启动映像。所以,我相信在 Mac OS X 上编译 Darwin 内核是可能的。
  • 我是 c 新手,但我可以看到至少 3 个静态原因:教学(遵循 ac book)、可移植性、稳定性(如果您不小心删除了链接文件,可执行文件不会工作)。
【解决方案2】:

没有动态加载库的二进制文件不能在 OSX 下构建。我尝试了苹果 llvm-gcc 和 macports gcc。然而,到目前为止没有提到的答案是这不是必需的。您可以静态链接 c/c++ 库(并使用一些动态部分)。

文件 hello.cpp:

#include <iostream>
using namespace std; 
int main()
{
    cout << "Hello World!";
}

照常编译:

g++ hello.cpp -o hello

检查联动:

otool -L hello
hello:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

我们无法摆脱 libSystem.B.dylib 依赖,但使用 macports gcc 我们可以做到这一点:

g++-mp-4.6 -static-libgcc -static-libstdc++ hello.cpp -o hello

otool -L hello
hello:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

显然只有 Apple 不支持静态链接:

llvm-g++ -static-libgcc -static-libstdc++ hello.cpp -o hello

otool -L hello
hello:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

【讨论】:

  • -static-libgcc -static-libstdc++ 是否适用于 gcc(不是 g++)?
  • -static-libstdc++ 对于 C 程序是不需要的,仅对于 C++ 程序是必需的。所以,是的,这两个选项都适用于 gcc。
【解决方案3】:

假设您想将一些函数转换为库。

文件:example.c

#include <stdio.h>

void aFunction( int a )
{
    printf( "%d\n", a );
}

文件:example.h

void aFunction( int a );

文件:main.c

#include "example.h"

int main( ) 
{
    aFunction( 3 );

    return 0;
}

创建库:

gcc -c example.c
ar -r libmylibrary.a  example.o

链接库:

gcc main.c -lmylibrary -L. -I.

然后文件 example.c 是整个程序的静态构建。

【讨论】:

  • 如何确认它是静态构建?
  • 但是程序a.out会动态链接!
  • 也就是说,您可以将库编译为静态而不是程序?
  • 预处理器会将库的代码包含到最终的可执行文件中。当需要函数“aFunction”时,o.s.不必与库绑定,因为代码在可执行文件中。
  • @momboco,不是预处理器,而是链接器 (ld)
猜你喜欢
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多