如何编译静态库

时间:2012-07-05 12:40:07

标签: c linux gcc x86-64

我正在尝试编译静态库。我按照this question的回答中给出的步骤,但它不起作用。以下是我的makefile。

PROJECT = lq.a
OBJECTS = dlmalloc.o queue.o.o
CFLAGS  = -o -Wall -pedantic

all: $(PROJECT)

.c.o:
    gcc -c $(CFLAGS) $<

$(PROJECT): $(OBJECTS)
    libtool -o  $(PROJECT) -static $(OBJECTS)

我收到以下错误。

libtool: unrecognized option `-o'

编写这个makefile的正确方法是什么?

4 个答案:

答案 0 :(得分:7)

您可以使用以下语法使用程序ar to create static libraries

 ar rcs my_library.a file1.o file2.o

所以,在你的情况下:

$(PROJECT): $(OBJECTS)
     ar rcs $(PROJECT) $(OBJECTS)

您可以在the man page上找到有关选项的说明,但基本上是:

  • r说将给定的目标文件插入到存档中(替换相同内容的任何旧版本)
  • c表示创建存档(如果它尚未存在)(通常无论如何都会发生这种情况,但此选项会禁止警告)。
  • s表示将对象文件索引写入存档。

答案 1 :(得分:3)

使用libtool或不使用libtool --mode=compile。如果您要使用它,那么您应该使用libtool --mode=link编译单个文件以及与libtool链接。如果您不打算使用gcc,则您的链接也应该使用man libtool完成,如另一个答案所述。此外,您是否尝试过{{1}}?

答案 2 :(得分:2)

以下命令将构建静态库:

$gcc -c file1.c -o libfile.o
$ar rcs libfile.a libfile.o

答案 3 :(得分:2)

嗯,这很令人困惑;但我认为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:unrecognized option'-o'”。看看它们,似乎OS X上的libtool和Linux上的libtool是两个完全不同的程序。 ...
  跟进:是的,似乎Linux上的libtool确实是OS X上的glibtool。在OS X上将“glibtool --help”作为“libtool --help”在Linux上运行时得到的输出基本相同。

好的,这解释了差异 - 但仍然没有解释-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 - ,我会指定一个以{{结尾的OUTPUT-FILE 1}};然后应该运行哪个命令.a - 或者扩展名LINK-COMMAND指定的ar + ranlib?好吧 - 这是一个终端片段,只是测试.a的{​​{1}}脚本逻辑 - 没有任何编译(尽管创建了一个空档案):

bash

所以 - 你不仅需要指定一个libtool,而且如果这个模式是$ 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 ,你必须指定某种参数(LINK-COMMAND)引用一个工具;但是LINK-COMMAND参数甚至不需要作为真正的程序存在 - 因为你必须指定一个输出文件;如果该输出文件在--mode结束,则会强制使用link / .a

此外,如果您对标记有问题 - 只需在LINK-COMMAND参数之前移动ar参数 - 您可以强制ranlib使用不存在的标记和非标记运行 - 存在LINK-COMMAND(其操作仅由输出文件的扩展名--tag指定) - 只要以libtool语法的正确顺序输入参数;我必须承认,在脚本本身并没有真正记录。


但回到Mac .a行,它将组合静态库;如果您尝试对正确的静态库libtool文件执行相同操作,您会注意到libtool -o $(PROJECT) -static $(OBJECTS)在输出存档中将.a存档推送到 ,< em> not 他们的组成对象文件 - 所以此输出不再是有效的ELF对象;这是一个相应的Linux libtool行的示例,其中包含两个我生成的正确库文件:

.a

因此,正如accepted answer所说 - 在Linux上,手动使用libtool解压缩并再次打包,以组合静态库。

希望这有助于某人,
干杯!