嗯,这很令人困惑;但我认为libtool -o $(PROJECT) -static $(OBJECTS) 行(objective c - Combine static libraries 中也提到)来自 Mac;显然libtool 与 Linux 上的 不 相同:
libtool or ar & ranlib - idevgames forums:
我正在使用 libtool 在 OS X 上创建一个静态库,因为这就是 Xcode 所做的,它似乎工作正常。然后我转到 Linux,它被我的 libtool 命令阻塞,说“libtool:无法识别的选项'-o'”。看着它们,似乎 OS X 上的 libtool 和 Linux 上的 libtool 是两个完全不同的程序。 ...
跟进:是的,Linux 上的 libtool 似乎确实是 OS X 上的 glibtool。在 OS X 上执行“glibtool --help”时,我得到的输出与 Linux 上的“libtool --help”基本相同。
好的,这解释了差异 - 但仍然没有解释-o 如何成为无法识别的选项,当我刚刚看到它从 Linux 上的 Makefile 运行时!所以我发现了这个:
bug-libtool mailing list (2001): Re: bug in libtool?
你需要在模式选项之前设置模式:
$ libtool --mode=link --help
用法:libtool [OPTION]... --mode=link LINK-COMMAND...
天哪……现在特别令人困惑的是,libtool --mode=link --help 中的这条注释:
$ libtool --mode=link --help
Usage: libtool [OPTION]... --mode=link LINK-COMMAND...
...
LINK-COMMAND is a command using the C compiler that you would use to create
a program from several object files.
The following components of LINK-COMMAND are treated specially: ...
-all-static do not do any dynamic linking at all ...
-o OUTPUT-FILE create OUTPUT-FILE from the specified objects ...
-static do not do any dynamic linking of uninstalled libtool libraries
...
All other options (arguments beginning with `-') are ignored.
Every other argument is treated as a filename. Files ending in `.la' are
treated as uninstalled libtool libraries, other files are standard or library
object files.
...
If OUTPUT-FILE ends in `.a' or `.lib', then a standard library is created
using `ar' and `ranlib', or on Windows using `lib'.
所以 - 如果我 必须 指定 LINK-COMMAND - 和 同时,我指定一个以 .a 结尾的 OUTPUT-FILE;然后应该运行哪个命令,LINK-COMMAND - 或扩展名.a 指定的ar+ranlib?好吧 - 这是一个终端 sn-p,只是测试 libtool 的 bash 脚本逻辑 - 没有任何编译(尽管确实创建了一个空存档):
$ libtool -o test.a
libtool: unrecognized option `-o'
libtool: Try `libtool --help' for more information.
$ libtool --mode=link -o test.a
libtool: link: unrecognized option `-o'
libtool: link: Try `libtool --help' for more information.
$ libtool --mode=link gcc -o test.a
libtool: link: ar cru test.a
libtool: link: ranlib test.a
$ libtool --mode=link ar -o test.a
libtool: link: unable to infer tagged configuration
libtool: link: specify a tag with `--tag'
$ cat $(which libtool) | grep "^# ### BEGIN LIBTOOL TAG CONFIG:"
# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
# ### BEGIN LIBTOOL TAG CONFIG: disable-static
# ### BEGIN LIBTOOL TAG CONFIG: CXX
# ### BEGIN LIBTOOL TAG CONFIG: F77
# ### BEGIN LIBTOOL TAG CONFIG: FC
# ### BEGIN LIBTOOL TAG CONFIG: GCJ
# ### BEGIN LIBTOOL TAG CONFIG: RC
# ### BEGIN LIBTOOL TAG CONFIG: BINCC
# ### BEGIN LIBTOOL TAG CONFIG: BINCXX
## CC tag is not listed, but it will (eventually) be accepted:
$ libtool --mode=link ar --tag CC -o test.a
libtool: link: unable to infer tagged configuration
libtool: link: specify a tag with `--tag'
$ libtool --mode=link --tag CC ar -o test.a
libtool: link: ar cru test.a
libtool: link: ranlib test.a
$ libtool --tag=CC --mode=link ar -o test.a
libtool: link: ar cru test.a
libtool: link: ranlib test.a
$ libtool --tag=XX --mode=link ar -o test.a
libtool: ignoring unknown tag XX
libtool: link: ar cru test.a
libtool: link: ranlib test.a
$ libtool --tag=XX --mode=link whatevar -o test.a
libtool: ignoring unknown tag XX
libtool: link: ar cru test.a
libtool: link: ranlib test.a
$ ls -la test.a
-rw-r--r-- 1 user user 8 2013-04-17 23:12 test.a
所以 - 你不仅必须指定--mode,而且如果这个模式是link,你必须指定某种类型的参数(LINK-COMMAND)来引用工具;但是那个 LINK-COMMAND 参数甚至不需要作为一个 real 程序存在——因为无论如何你都必须指定一个输出文件;如果该输出文件以.a 结尾,它将强制使用ar/ranlib 无论如何。
此外,如果您对标签有疑问 - 只需将 --tag 参数移到 LINK-COMMAND 参数之前 - 您可以强制 libtool 使用不存在的标签和不存在的 LINK 运行 - COMMAND(其操作仅由输出文件的扩展名.a 指定)——只要以libtool 语法的正确顺序输入参数;我必须承认,脚本本身并没有真正记录这一点。
但是回到 Mac libtool -o $(PROJECT) -static $(OBJECTS) 行,它将结合静态库;如果您尝试对正确的静态库 .a 文件执行相同操作,您会注意到 libtool 在输出存档中推送 .a 存档原样,不是 它们的组成对象文件 - 所以这个输出不再是一个有效的 ELF 对象;这是一个相应的 Linux libtool 行的示例,其中包含我生成的两个正确的库文件:
$ readelf --syms libmy1.a
File: libmy1.a(my1.o)
Symbol table '.symtab' contains 11 entries:
...
$ readelf --syms libmy2.a
File: libmy2.a(my2.o)
Symbol table '.symtab' contains 12 entries:
...
$ libtool --mode=link --tag=CC ar -o libtest.a -static libmy1.a libmy2.a
libtool: link: ar cru libtest.a libmy1.a libmy2.a
libtool: link: ranlib libtest.a
$ readelf --syms libtest.a
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
readelf: Error: libtest.a(libmy1.a): Failed to read file header
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start
readelf: Error: libtest.a(libmy2.a): Failed to read file header
因此,正如 accepted answer 所说 - 在 Linux 上,手动使用 ar 解包并再次打包,以组合静态库。
希望这对某人有所帮助,
干杯!