13

私は他の人が持っているのと同じ問題を抱えています:

  • Automakeプロジェクトでlibtoolによって生成された*.laファイルがあります (例: )。module.la
  • しかし、それを使用するにはが必要*.sodlopen()です(例: module.so)。

--disable-sharedただし、プロジェクトは、作成されたメインバイナリが静的にリンクされた1つの大きなプログラムであることを確認するために構成およびビルドされます。たとえばmain.x、展開とデバッグが容易になります。したがって、*.soファイルは作成されません。

このプログラムは、静的にリンクされているにもかかわらず、main.x拡張機能 (モジュール) をロードできる巨大なフレームワークのようなアプリケーションです。dlopen()

これは、手動でビルドするときにうまく機能module.soします。しかし、これを機能させることは私にMakefile.amは不可能に思えます。はい、書くことはできますlib_LTLIBRARIESが、私の標準--disable-sharedではファイルを取得できません*.so

lib_LTLIBRARIES = module.la
module_so_SOURCES = module.cpp

ファイルmodule.laが作成されますが、dlopen()ロードは拒否されます (もちろん)。

Makefile.am私はそれを手動で構築するためにルールを入れようとしましたが、それはうまくいきます:

# Makefile.am (yes, .am)
all: mm_cpp_logger.so

SUFFIXES = .so

%.so: %.cpp
    $(CXX) $(CXXFLAGS) -fPIC -fpic -c -I $(top_srcdir)/include -o $@  $<

%.so: %.o
    $(CXX) $(LDFLAGS) -shared -fPIC -fpic -o $@  $<

しかし、これは回避策にすぎません。依存関係チェックやインストールなどの優れた自動機能をすべて利用できるわけではありません。

途中で(または同じ効果で)module.soメインプログラムをビルドしたままビルドするにはどうすればよいですか?--disable-sharedMakefile.am

  • 特別な automake ルールを使用して、*.laファイルをファイルに後処理できますか?*.so
  • いずれにせよ、ファイルlib_LTLIBRARIESを作成するプロセスを微調整できますか?*.so
4

3 に答える 3

14

あなたが探しているものはモジュールと呼ばれます。-all-staticアプリケーションの に追加することで、Autotools に静的バイナリ (実行可能ファイル) を作成するように指示できLDFLAGSます。これはconfigureフラグを使用するよりも好ましい方法だと思います--disable-shared(これは実際には実行可能ファイルではなくライブラリを対象としています)

このような何かがうまくいくはずです:

AM_CPPFLAGS=-I$(top_srcdir)/include

lib_LTLIBRARIES = module.la
module_la_LDFLAGS = -module -avoid-version -shared
module_la_SOURCES = mm_cpp_logger.cpp

bin_PROGRAMS = application
application_LDFLAGS = -all-static
application_SOURCES = main.cpp

.soファイルは (いつものように) 最終的にサブディレクトリに.libs/置かれます (もちろんインストールしない限り)。

また、アプリケーションとプラグインの両方を一度に (単一の であっても) ビルドできるため、複数回Makefile.am呼び出す必要はありません。configure

(および友人)の使用は-fPIC、Autotools によって自動検出される必要があります。


更新:共有ライブラリを期待する場所で利用できるようにするためのちょっとしたトリックがあります。すべての shlib は最終.libs/的に .

次の makefile スニペットは、便利なリンクを作成します (シンボリック リンクをサポートするプラットフォーム上で、それ以外の場合はコピーされます)。スニペットを makefile に追加するだけで (私は通常 を使用します-include convenience-link.mk)、十分なはずです ( AC_PROG_LN_Sconfigure.ac に が必要になる場合があります)。

.PHONY: convenience-link clean-convenience-link

convenience-link: $(lib_LTLIBRARIES)
    @for soname in `echo | $(EGREP) "^dlname=" $^ | $(SED) -e "s|^dlname='\(.*\)'|\1|"`; do  \
        echo "$$soname: creating convenience link from $(abs_builddir)/.libs to $(top_builddir)"; \
        rm -f $(top_builddir)/$$soname ; \
        test -e $(abs_builddir)/.libs/$$soname && \
        cd $(top_builddir) && \
        $(LN_S) $(abs_builddir)/.libs/$$soname $$soname || true;\
    done 

clean-convenience-link:
    @for soname in `echo | $(EGREP) "^dlname=" $(lib_LTLIBRARIES) | $(SED) -e "s|^dlname='\(.*\)'|\1|"`; do  \
        echo "$$soname: cleaning convenience links"; \
        test -L $(top_builddir)/$$soname && rm -f $(top_builddir)/$$soname || true; \
    done 
        
all-local:: convenience-link

clean-local:: clean-convenience-link
于 2013-01-08T16:34:09.543 に答える
1

LT_INITの libtool ドキュメントに従って動作する可能性のある方法の 1 つは、ビルドをメイン アプリケーションとプラグインの 2 つのパッケージに分割することです。そうすれば、(理論的には)次のように呼び出すことができます。

./configure --enable-shared=plugins

そして、物事はあなたが期待するように機能します。

于 2012-12-19T18:51:51.143 に答える