我正在尝试编译一个静态库。 我遵循了这个问题的答案,但它不起作用的步骤。 以下是我的makefile。
PROJECT = lq.a OBJECTS = dlmalloc.o queue.oo CFLAGS = -o -Wall -pedantic all: $(PROJECT) .co: gcc -c $(CFLAGS) $< $(PROJECT): $(OBJECTS) libtool -o $(PROJECT) -static $(OBJECTS)
我得到以下错误。
libtool: unrecognized option `-o'
写这个makefile的正确方法是什么?
您可以使用以下语法使用程序ar
创建静态库 :
ar rcs my_library.a file1.o file2.o
所以,在你的情况下:
$(PROJECT): $(OBJECTS) ar rcs $(PROJECT) $(OBJECTS)
你可以在手册页上找到选项的解释,但基本上:
r
说插入给定的对象文件到档案(替换任何旧版本的同一件事) c
说创建档案,如果它不在那里(通常这发生,但这个选项抑制警告)。 要么使用libtool
要么不要。 如果你打算使用它,那么你应该使用libtool --mode=compile
来编译单独的文件,以及使用libtool --mode=link
。 如果你不打算使用libtool
,那么你的链接也应该用gcc
来完成,正如另一个答案中指出的那样。 另外,你有没有尝试过man libtool
?
那么,这是令人困惑的; 但我认为libtool -o $(PROJECT) -static $(OBJECTS)
行(在目标c中也提到- Combine静态库 )来自Mac; 显然libtool
和Linux上的不一样:
libtool或者ar&ranlib – idevgames论坛 :
我正在使用libtool在OS X上创建一个静态库,因为这是Xcode正在做的,这似乎工作正常。 然后我去Linux,它扼死我的libtool命令说:“libtool:无法识别的选项”-o“”。 看着他们,似乎在Linux上的libtool和Linux上的libtool是两个完全不同的程序。 …
后续工作:是的,似乎Linux上的libtool确实是OS X上的glibtool。在Linux上执行“glibtool --help
”时,我得到的输出基本上与Linux上的“libtool --help
”相同。
好的,这解释了这种差异 – 但是仍然没有解释如何-o
可以是一个无法识别的选项,当我刚刚看到它从Linux上的Makefile运行! 所以我找到了这个:
bug-libtool邮件列表(2001):Re:libtool中的bug?
您需要在模式选项之前设置模式:
$ 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
? 那么这里是一个终端片段,只是测试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参数甚至不需要作为真正的程序存在 – 因为无论如何你必须指定一个输出文件; 如果输出文件以.a
结尾,则会强制使用ar
/ ranlib
。
另外,如果你有一个标签的问题 – 只需在LINK-COMMAND参数之前移动--tag
参数 – 你可以强制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
所以,正如接受的答案所说 – 在Linux上,手动使用ar
解包并重新打包,组合静态库。
希望这有助于某人,
干杯!
以下命令将构建您的静态库:
$gcc -c file1.c -o libfile.o $ar rcs libfile.a libfile.o