macos 如何在 OS X 上静态链接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/844819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 06:08:55  来源:igfitidea点击:

How to static link on OS X

macoslinkerstatic-libraries

提问by Employed Russian

I'm trying to link to a static library on OS X. I used the -staticflag in the gcc command but I get the following error message:

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

ld_classic: can't locate file for: -lcrt0.o
collect2: ld returned 1 exit status

I looked in the man pages and it reads something like:

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

This option will not work on Mac OS X unless all libraries (including libgcc.a) have also been compiled with -static. Since neither a static version of libSystem.dylib nor crt0.o are provided, this option is not useful to most people.

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

Is there another way to link to this static library?

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

回答by Employed Russian

In order to link to an archive library (sometimes also called static library), just add it to the link line:

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

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

The linker will search for libfoo.dylib, and then libfoo.a, which is all you need.

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

If you have bothversions of the library, and want to link with an archive version in preference of the dynamic one, just specify the full path to the archive on the link line:

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

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

回答by alecco

Regretfully, it's not supported. Some people reported it's possible to manually compile crt0 but nobody confirms it.

遗憾的是,它不受支持。有些人报告说可以手动编译 crt0,但没有人确认

回答by Michael Chinen

A common case is to static link against a third user library while dynamically linking against the system frameworksand libraries, so your users don't need to install third party libs before using your program. If the library is dynamically linked against frameworks (as is often the case), it may still ship with a static .a, but it is not sufficient just to replace -l<libname>with /path/to/libname.abecause the .a will not have the dependencies in it. You will also have to dynamically link against those frameworks that your library was using.

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

For example, say you want to write a program that uses the open source libusb without requiring your user to download and install libusb. Say you have a dynamically linked binary you built with this:

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

clang -lusb-1.0 main.c -o myprogram

To statically link on OS X, the command looks like this (note the -frameworkarguments):

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

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

To find what system frameworks and libraries you need to add, look at the third party dylib using otool:

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

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

which shows:

这表现了:

/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)  

You can start by adding the frameworks, followed by the libraries one at a time and you will see the list of undefined reference errors shrink. Note you probably won't need to add every library, because some may be loaded as dependencies for the ones you explicitly added.

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

If you aren't sure where the dylib exists, build your program the original dynamic way (with -lusb-1.0), and run otool on it:

如果您不确定 dylib 的位置,请以原始动态方式(使用 -lusb-1.0)构建您的程序,并在其上运行 otool:

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

which gives:

这使:

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)

Also, read the license of the library you are linking to.

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

回答by atrens

-Bstaticseems to be a no-op on OS-X Lion - used gcc -vto confirm this.

-Bstatic似乎是 OS-X Lion 上的空操作 - 用于gcc -v确认这一点。

回答by Zhi Q.

I've been run into the same issue. Here is an example to work around:

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

STEP1: create files

STEP1:创建文件

myfunc1.c:

myfunc1.c:

#include <stdio.h>

void myfunc1() {
    printf( "This is my func1!\n" );
}

myfunc2.c:

myfunc2.c:

#include <stdio.h>

void myfunc2() {
    printf( "This is my func2!\n" );
}

and myfunc.c:

和 myfunc.c:

#include <stdio.h>

void myfunc1( void );
void myfunc2( void );

int main() {
    myfunc1();
    myfunc2();
    return 0;
}

STEP2: create the lib

STEP2:创建库

gcc -c myfunc1.c myfunc2.c

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

STEP3: link

第3步:链接

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

Do not forget to type "-L."; dot indicates the current path.

不要忘记输入“-L”。点表示当前路径。

Hope that helps.

希望有帮助。