12

Mac では問題なくコンパイルされる autotools プロジェクトがありますが、Linux (Ubuntu 12.04.1 LTS) では、コマンド ラインが渡されgccて、ライブラリがオブジェクト ファイルに対して順不同になります。たとえば、autotools は次のコマンドを生成してコードをコンパイルしtest.cますtest

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -lglib-2.0 -o test test-test.o

このコマンド ラインは次のエラーで失敗します。

/home/user/glib-test/test.c:4: undefined reference to `g_malloc`
/home/user/glib-test/test.c:5: undefined reference to `g_free`

ただし、コマンドラインからコンパイルして切り替えて、ライブラリ参照がオブジェクトファイルの後にあるようにすると、問題なく動作します。

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -o test test-test.o -lglib-2.0

問題は、Autotools に正しい順序でコマンド ラインを生成させる方法を理解できないことです。わかりやすくするために、ここでは単純なテスト ケースを再現しました。最初は次のconfigure.acとおりです。

dnl Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)
AC_INIT(glib-test, 1.0)

AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE()

AC_PROG_CC
AM_PROG_CC_C_O
PKG_CHECK_MODULES(GLIB, glib-2.0 > 2.0)
AC_CONFIG_FILES(Makefile)
AC_OUTPUT

次は簡単Makefile.amです:

CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDFLAGS=$(GLIB_LIBS)
test_SOURCES=test.c

最後に、この最小限のテスト ケースのソース コードtest.c:

#include <glib.h>

int main(int argc, char **argv) {
    gchar *foo = g_malloc(100);
    g_free(foo);
    return 0;
}

次に、次の一連のコマンドを使用してコンパイルを実行します。

touch NEWS README AUTHORS ChangeLog
aclocal
autoconf
automake --add-missing
./configure
make

コードがコンパイルされない理由を理解しています。automakeライブラリをコマンドラインの最後に配置して、gcc適切に実行およびリンクする方法を考えているだけです。gccMac OS X Lion では、この問題はないようです。

4

2 に答える 2

16

LDFLAGS解は と の差であることが判明しましたLDADD。つまりLDFLAGS、コマンド ラインでオブジェクト ファイルの前にLDADD追加され、その後に追加されます。したがって、次のように変更Makefile.amすると問題が解決しました。

CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDADD=$(GLIB_LIBS)
test_SOURCES=test.c

職場の GCC 開発者を追跡するだけで解決できました。testまた、私が提供したこの例は、autotool のいくつかのコンテキストで定義された意味を持っているため、かなり貧弱です。

于 2012-11-28T20:05:25.240 に答える
1

同様の問題を解決しました。問題の ./configure スクリプトは、シンボルが欠落しているため、関数の存在のチェックを完了できませんでした。正しいライブラリを$LDFLAGSなどに追加する.cと、ファイルの前に追加され、ライブラリは無視されました。

チェックする関数の名前が最初に追加され、次にそれぞれの関数が呼び出され、次に呼び出される関数ac_func_listの本体にループがあります。./configureac_fn_c_check_func ()ac_fn_c_try_link ()

チェック関数 ac_fn_c_try_link () は、次のパターンのコマンドを使用します。

ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS \
         $LDFLAGS conftest.$ac_ext $LIBS >&5'

$LDADDここでは完全に無視されます。したがって、ここでの唯一の解決策は、-l変数にフラグを追加することです$LIBS

于 2013-11-25T14:59:05.507 に答える