6

静的ライブラリをコンパイルしようとしています。この質問への回答で与えられた手順に従いましたが、機能していません。以下は私の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

4 に答える 4

12

このプログラムを使用して、次の構文を使用しar て静的ライブラリを作成できます。

 ar rcs my_library.a file1.o file2.o

だから、あなたの場合:

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

オプションの説明はmanページにありますが、基本的には次のとおりです。

  • r指定されたオブジェクトファイルをアーカイブに挿入すると言います(同じものの古いバージョンを置き換えます)
  • cアーカイブがまだ存在しない場合はアーカイブを作成すると言います(通常、これはとにかく発生しますが、このオプションは警告を抑制します)。
  • sオブジェクトファイルインデックスをアーカイブに書き込むように言います。
于 2012-07-05T13:46:03.767 に答える
4

まあ、これは紛らわしいです。しかし、この行( Objective c-静的ライブラリの組み合わせlibtool -o $(PROJECT) -static $(OBJECTS)でも言及されています)はMacからのものだと思います。どうやらLinuxのものと同じものはありません:libtool

libtoolまたはar&ranlib-idevgamesフォーラム

私はlibtoolを使用してOSXで静的ライブラリを作成していました。これは、Xcodeが実行していたことであり、正常に機能しているようです。次に、Linuxに移動すると、libtoolコマンドで「libtool:認識されないオプション'-o'」と表示されます。それらを見ると、OSXのlibtoolとLinuxのlibtoolは完全に異なる2つのプログラムのようです。...
フォローアップ:はい、Linuxのlibtoolは確かにOS Xのglibtoolのようです。OSXでglibtool --helplibtool --help」を実行すると、Linuxで「」と基本的に同じ出力が得られます。

-oわかりました、それは違いを説明します-しかし、それがLinux上のMakefileから実行されるのを見たばかりのとき、認識されないオプションになる方法についてはまだ説明していません!だから私はこれを見つけました:

bug-libtoolメーリングリスト(2001):Re: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'.

したがって、 --指定する必要ある場合は、同時に、 ;で終わるanを指定します。次に、どのコマンドを実行する必要がありますか、-またはその拡張機能が指定する+ ?さて、これがターミナルスニペットです。コンパイルせずにスクリプトロジックをテストするだけです(空のアーカイブは作成されますが)。LINK-COMMANDOUTPUT-FILE.aLINK-COMMANDarranlib.abashlibtool

$ 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の使用を強制します。arranlib

また、タグに問題がある場合は(--tagLINK-COMMAND引数の前に引数を移動するだけですlibtool)、存在しないタグと存在しないLINK-COMMAND(その操作はによってのみ指定されます)で強制的に実行できます。出力ファイルの拡張子)-引数が構文.aに対して適切な順序で入力されている限り。libtool私が認めなければならないことは、スクリプト自体には実際には文書化されていません。


libtool -o $(PROJECT) -static $(OBJECTS)しかし、静的ライブラリを組み合わせるMacラインに戻ると。適切な静的ライブラリファイルで同じことを行おうとすると、アーカイブを構成オブジェクトファイルではなく、出力アーカイブにプッシュする.aことに気付くでしょう。したがって、この出力は有効なELFオブジェクトではなくなります。これは、対応するLinux行の例であり、私が生成した2つの適切なライブラリファイルがあります。libtool.alibtool

$ 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手動で解凍して再度パックし、静的ライブラリを結合します。

これが誰かに役立つことを願っています、
乾杯!

于 2013-04-17T21:21:41.923 に答える
3

使用するlibtoolかしないか。これを使用する場合は、でlibtool --mode=compileリンクするだけでなく、で個々のファイルをコンパイルする必要がありますlibtool --mode=link。を使用しない場合は、別の回答で指摘されているlibtoolように、リンクも使用する必要があります。gccまた、試したことはありますman libtoolか?

于 2012-07-05T13:56:14.923 に答える
2

次のコマンドは、静的ライブラリを構築します。

$gcc -c file1.c -o libfile.o
$ar rcs libfile.a libfile.o
于 2012-07-05T13:40:57.930 に答える