【问题标题】:How to static link on OS X如何在 OS X 上进行静态链接
【发布时间】:2010-10-25 02:16:25
【问题描述】:

我正在尝试链接到 OS X 上的静态库。我在 gcc 命令中使用了 -static 标志,但收到以下错误消息:

ld_classic:找不到文件:-lcrt0.o collect2: ld 返回 1 个退出状态

我查看了手册页,内容如下:

除非所有库(包括 libgcc.a)也已使用 -static 编译,否则此选项在 Mac OS X 上不起作用。由于既没有提供静态版本的 libSystem.dylib 也没有提供 crt0.o,因此该选项对大多数人来说没有用处。

还有其他方法可以链接到这个静态库吗?

【问题讨论】:

  • 愚蠢的 Apple 文档推荐动态链接,但他们没有显示任何实际执行此操作的 ld 命令。

标签: macos linker static-libraries


【解决方案1】:

要链接到存档库(有时也称为静态库),只需将其添加到链接行:

gcc main.o ... -lfoo ...

链接器将搜索 libfoo.dylib,然后搜索 libfoo.a,这就是您所需要的。

如果您有 两个 版本的库,并且想要链接存档版本而不是动态版本,只需在链接行上指定存档的完整路径:

gcc main.o ... /path/to/libfoo.a ...

【讨论】:

  • 在 OS X 和 XCode 上没有 crt0.o 或 crt0.a 或类似的东西。
  • @alecco 你可以通过Csu(“C start up”的缩写)得到crt0.o,但不幸的是crt0.o无法与@987654328链接@ 因为没有 libSystem.dylib 的静态版本。在Github ticket 上为Csu 提供有关此问题的更多详细信息。
【解决方案2】:

很遗憾,it's not supported。有人报告说可以手动编译 crt0 但nobody confirms it

【讨论】:

  • 可以通过Csu(“C 启动”的缩写)编译crt0.o,但不幸的是crt0.o 无法与libc 链接,因为libSystem.dylib 没有静态版本。所以,是的,直到 Apple 为我们提供libSystem.dylib 的静态版本,它才被支持。要么,要么不使用libc。对于Csu,这个Github ticket 有更多详细信息。
【解决方案3】:

一个常见的情况是静态链接到第三方用户库,同时动态链接到系统框架和库,因此您的用户在使用您的程序之前不需要安装第三方库。如果库是针对框架动态链接的(通常是这种情况),它可能仍附带静态 .a,但仅将 -l<libname> 替换为 /path/to/libname.a 是不够的,因为 .a 将没有依赖项在里面。您还必须动态链接到您的库正在使用的那些框架。

例如,假设您想编写一个使用开源 libusb 的程序,而无需您的用户下载和安装 libusb。假设您有一个使用此构建的动态链接二进制文件:

clang -lusb-1.0 main.c -o myprogram

要在 OS X 上静态链接,命令如下所示(注意 -framework 参数):

clang -framework CoreFoundation -framework IOKit main.c /path/to/libusb-1.0.a -o myprogram

要查找需要添加哪些系统框架和库,使用otool查看第三方dylib:

otool -L /usr/local/opt/libusb/lib/libusb-1.0.0.dylib

其中显示:

/usr/local/opt/libusb/lib/libusb-1.0.0.dylib:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1348.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)  

您可以从添加框架开始,然后一次添加一个库,您将看到未定义的引用错误列表缩小。请注意,您可能不需要添加每个库,因为有些库可能会作为您明确添加的库的依赖项加载。

如果您不确定 dylib 存在于何处,请使用原始动态方式(使用 -lusb-1.0)构建您的程序,然后在其上运行 otool:

clang -lusb-1.0 main.c -o myprogram
otool -L myprogram

给出:

myprogram:
    /usr/local/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 2.0.0, current version 2.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)

另外,请阅读您要链接到的库的许可证。

【讨论】:

    【解决方案4】:

    -Bstatic 似乎在 OS-X Lion 上没有任何操作 - 使用 gcc -v 来确认这一点。

    【讨论】:

      【解决方案5】:

      我也遇到过同样的问题。这是一个可以解决的示例:

      第 1 步:创建文件

      myfunc1.c:

      #include <stdio.h>
      
      void myfunc1() {
          printf( "This is my func1!\n" );
      }
      

      myfunc2.c:

      #include <stdio.h>
      
      void myfunc2() {
          printf( "This is my func2!\n" );
      }
      

      和 myfunc.c:

      #include <stdio.h>
      
      void myfunc1( void );
      void myfunc2( void );
      
      int main() {
          myfunc1();
          myfunc2();
          return 0;
      }
      

      第二步:创建库

      gcc -c myfunc1.c myfunc2.c
      
      ar -r libmyfuncs.a myfunc1.o myfunc2.o
      

      第三步:链接

      gcc -o myfunc -L. myfunc.c -lmyfuncs 
      

      别忘了输入“-L”;点表示当前路径。

      希望对您有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-11
        • 1970-01-01
        • 2015-06-02
        • 1970-01-01
        • 2014-02-03
        • 2010-09-26
        相关资源
        最近更新 更多