如何为macOS构建一个可移植的静态C库
我想构建一个可移植的静态C库,它可以链接到macOS二进制文件中,而不管macOS版本如何。C库没有任何依赖项(即没有stdlib,没有特定于操作系统的调用)。唯一的依赖项是CPU,它必须是x86_64 在提取相关的编译器三元组时,对于Sierra,我得到了如何为macOS构建一个可移植的静态C库,c,macos,static-libraries,cross-compiling,portability,C,Macos,Static Libraries,Cross Compiling,Portability,我想构建一个可移植的静态C库,它可以链接到macOS二进制文件中,而不管macOS版本如何。C库没有任何依赖项(即没有stdlib,没有特定于操作系统的调用)。唯一的依赖项是CPU,它必须是x86_64 在提取相关的编译器三元组时,对于Sierra,我得到了x86_64-apple-darwin16.7.0,对于High Sierra,我得到了x86_64-apple-darwin17.2.0。此外,当我在High Sierra上构建时,如果我使用Sierra的静态库(即使我为clang指定了-
x86_64-apple-darwin16.7.0
,对于High Sierra,我得到了x86_64-apple-darwin17.2.0
。此外,当我在High Sierra上构建时,如果我使用Sierra的静态库(即使我为clang指定了--target x86\u 64-apple-darwin16.7.0
),也会有一个警告
- 如何为macOS构建真正可移植的静态库?如果不可能,那怎么办?从同一版本构建的每个主要macOS版本有一个不同的版本?从过时的Xcode版本复制SDK进行黑客攻击?请记住,我的库是完全可移植的,不以任何方式依赖于macOS或stdlib
- 编译器三元组末尾的版本部分重要吗
$ls-al
⏎
$cat foo.c
⏎
$cat foo.h
⏎
$cat bar.c
⏎
在我的测试中,libfoo.a可以在三个平台中的任何一个平台上生成,并复制到三个平台中的任何一个,用于在本地生成test
nm测试
在所有三个上显示静态链接到二进制文件的库
希望这有帮助
关于macosx libtool
注:macosx libtool与gnu libtool不同,只是名称不同。完全不同的用法和功能。macosx libtool本质上是AR+ranlib+一些达尔文主义。我不确定问题出在哪里。建设图书馆;使用它。如您所说,如果您的代码没有进行任何系统调用(不寻常,甚至非常出色,但并非实际上不可能),那么您在Mavericks上编译的代码将在High Sierra上运行。从另一个角度来看,这并不十分清楚;若您在High Sierra上编译,并且并没有遵守系统调用约束,那个么在Mavericks上使用它应该没问题。有一个编译时环境变量可以设置(但是我把它的名字放错了,并且我发现了一个选项“-mmacosx version min=10.11”的证据,这个选项可以用GCC设置)。我发现了一个Perl版本(5.10.0-仿古版),配置为使用
ld='env MACOSX\u DEPLOYMENT\u TARGET=10.3 cc'
,也就是说,我认为,我想到的环境变量。@AhmedMasud:那是关于静态链接的可执行文件。我的问题是关于纯可移植代码的静态链接库。哇,感谢您的详细回答。知道在这种情况下,叮当声使用的是--target
开关吗?似乎只有-mmacosx version min
与您的示例相关。OSX bundled clang中的目标选择由架构的四个参数-arch
控制,-mmacox-min-version
用于darwin-min-version-miphone-os-min-version
用于ios-min-version和-march
用于您要生成代码表单的cpu类型
total 64
drwxr-xr-x 8 masud staff 272 Dec 5 11:12 .
drwxr-xr-x 7 masud staff 238 Dec 5 10:35 ..
-rw-r--r-- 1 masud staff 386 Dec 5 11:11 Makefile
-rwxr-xr-x 1 masud staff 8464 Dec 5 10:38 bar
-rw-r--r-- 1 masud staff 69 Dec 5 11:11 bar.c
-rw-r--r-- 1 masud staff 53 Dec 5 11:10 foo.c
-rw-r--r-- 1 masud staff 84 Dec 5 11:11 foo.h
-rw-r--r-- 1 masud staff 83 Dec 5 11:11 test.c
LIBTOOL=libtool
STATIC=-static
LIBFOO_A=libfoo.a
SRC=foo.c bar.c
OBJ=$(SRC:.c=.o)
LIBFOOCFLAGS=-mmacosx-version-min=10.1
TESTSRC=test.c
TESTCFLAGS=-mmacosx-version-min=10.7
$(LIBFOO_A): $(OBJ)
$(LIBTOOL) $(STATIC) -o $@ $(OBJ)
%.o: %.c
$(CC) $(LIBFOOCFLAGS) -c -o $@ $<
test: $(LIBFOO_A) test.c
$(CC) $(TESTCFLAGS) -o $@ test.c -L. -lfoo
clean:
$(RM) test $(LIBFOO_A) $(OBJ)
int foo(void) {
volatile int a = 0;
return a;
}
#ifndef __FOO_H
#define __FOO_H
extern int foo(void);
#endif
#include "foo.h"
int bar(int k) {
return k-1;
}