3

私はZedShawのLearnCを使ってCプログラミングを難しい方法で学ぼうとしています。私は、ソフトウェアのインストールに使用するプログラム「devpkg」を作成するex26に取り組んでいます。この演習では、ApachePortableRuntimeライブラリをインストールする必要があります。この演習のコードを記述した後、次のmakefileを使用してプログラムをコンパイルできませんでした。

    PREFIX?=/user/local
    CFLAGS=-g -Wall -I${PREFIX}/apr/include/apr-1 -I{PREFIX}/apr/include/apr-util-1
    LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1

    all: devpkg

    install: all
             install -d${DESTDIR}/${PREFIX}/bin/
             install devpkg ${DESTDIR}/${PREFIX}/bin/

    clean:
            rm -f *.o
            rm -f devpkg
            rm -f *.dSYM

「$makedevpkg」を使用したとき、すべてのAPRライブラリ関数が宣言されていなかったため、このmakefileは機能していないようでした。ちなみに、私はこれをUbuntu仮想マシンで実行しています。本文に記載されている解決策は、構成ファイルを変更してから「ldconfigを実行」して、リンカが適切なライブラリを見つけられるようにすることです。
関数を正しく利用するために、ldconfigのマニュアルページを十分に理解していません。ldconfigを正しく実行するにはどうすればよいですか?

また、いくつか掘り下げた後、makefileで「LDFLAGS」の代わりに「LDLIBS」を使用すると問題が修正されたという参照を見つけました。makefileを変更し、プログラムをコンパイルしました。

CコンパイラがAPRライブラリに正しくリンクできるようにした「LDFLAGS」と「LDLIBS」の違いは何ですか?makefileが正しく生成される方法をよりよく理解するのに役立つコマンドの便利なリストがどこかにありますか?

御時間ありがとうございます。

4

2 に答える 2

3

GNU Make Manual、セクション10.2暗黙的ルールのカタログから:

単一のオブジェクトファイルのリンクは 、Cコンパイラを介してリンカ(通常はと呼ばれます)を実行することによって
n自動的に行われます。使用される正確なレシピは' 'です。n.old$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)

ご覧のとおりLDFLAGS、オブジェクトファイルの前とLDLIBS後です。時々、その順序が重要になることがあります-明らかにあなたの場合はそうです。

編集者注:makeの暗黙的なルールのサポートを使用すると便利な場合もありますが、ほとんどの場合、将来的にはさらに混乱することになります。完全なmakefileを作成することをお勧めします。これは、何が起こっているのかを理解するのに役立ち、将来この種の問題を回避できることを願っています。

于 2013-03-01T19:42:22.843 に答える
3

「LDFLAGS」を「LDLIBS」に変更する代わりに、この回答を追加したかっただけです。上記の解決策は私の場合は機能しましたが、他の人が役立つまたは興味深いと思うかもしれないこのスレッドを見る前に、代替の(直接的ではありませんが)解決策を見つけました。コンパイルすると、「未定義の参照」エラーがたくさん表示されました。例:

/MyCode/LCTHW/devpkg/devpkg.c:18: undefined reference to `apr_pool_initialize'

多くの試行錯誤の末、私はmakefileを次のように変更しました(まだLDFLAGSを使用しています)。

CC=gcc
PREFIX?=/usr/local
CFLAGS=-g   -Wall   -I$(PREFIX)/apr/include/apr-1   -I$(PREFIX)/apr/include/apr-util-1
LDFLAGS=-L$(PREFIX)/apr/lib -lapr-1 -laprutil-1 -pthread
OBJECTS=bstrlib.o   db.o    shell.o commands.o  devpkg.o

all:    devpkg

devpkg: $(OBJECTS)
    $(CC)   $(CFLAGS)   $(OBJECTS)  -o  devpkg  $(LDFLAGS)

install:    all
    install -d $(DESTDIR)/$(PREFIX)/bin/
    install devpkg $(DESTDIR)/$(PREFIX)/bin/

clean:
    rm -f *.o
    rm -f devpkg
    rm -rf *.dSYM

次に、aprライブラリへのパスを含む.confファイルを/etc/ld.so.conf.dに追加する必要がありました。

/usr/local/apr/lib

そして、実行します

sudo ldconfig

そのため、システムは新しい.confファイルを取得し、ライブラリの場所を認識します。私が読んだところによると、ライブラリが/ usr / local / libに保存されていなかったため、この最後のステップが必要だったようです。.confファイルを削除し、ldconfigを再実行して更新すると、プログラムはコンパイルされますが、実行時にライブラリを見つけることができません(makefileまたはOPでコンパイルされているかどうかに関係なく)。

私は自分の解決策を完全には理解していませんが、少なくともエラーなしでプログラムをコンパイルして実行することができました。このソリューションが他の人の興味を引くことを願っています。おそらく、より知識のある人が、なぜそれが機能するのかをより詳細に説明できるでしょう。

于 2013-06-26T05:03:01.270 に答える