如何在Automake和libtool使用项目中构建*.so模块?

tow*_*owi 10 automake shared-libraries libtool

我和其他人有同样的问题:

  • 我在Automake项目中有一个*.lalibtool生成的文件(例如),module.la
  • 但是我需要把*.so它用于dlopen()(例如module.so).

但是:项目已配置和构建,--disable-shared以确保创建的主二进制文件是一个大的静态链接程序,例如main.x(更容易部署和调试).因此*.so不会创建文件.

该程序main.x是一个巨大的框架式应用程序,它能够通过加载扩展(模块)dlopen()- 尽管它是静态链接的.

当我module.so手工构建时,这很好用.但是这Makefile.am对我来说似乎是不可能的.是的,我可以写lib_LTLIBRARIES,但按照我的标准,--disable-shared我没有得到*.so文件.

lib_LTLIBRARIES = module.la
module_so_SOURCES = module.cpp
Run Code Online (Sandbox Code Playgroud)

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 $@  $<
Run Code Online (Sandbox Code Playgroud)

但这只能是一种解决方法.我没有得到所有漂亮的自动功能,如依赖检查和安装.

如何module.so在仍然建立主程序--disable-shared(或具有相同效果)的情况下构建Makefile.am

  • 我可以使用特殊的automake规则*.la*.so文件后处理到文件吗?
  • 在任何情况下我都可以调整lib_LTLIBRARIES创建*.so文件的过程吗?

uml*_*ute 12

你在寻找的是一个所谓的" 模块 ".并且您可以通过添加-all-static到应用程序的LDFLAGS 来告诉autotools创建静态二进制文件(可执行文件).我认为这是使用LDFLAGSconfigure标志的首选方式(实际上是针对库而不是可执行文件)

像这样的东西应该做的伎俩:

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
Run Code Online (Sandbox Code Playgroud)

--disable-shared文件将(像往常一样)最终在.so子目录中(当然,除非你安装它)

并且您可以一次性构建应用程序和插件(即使只有一个.libs/,因此无需Makefile.am多次调用.

configureautotools应该自动检测(和朋友)的使用

更新

这里有一个小技巧可以让共享库在你期望的地方可用.因为所有shlib都会进入-fPIC,所以将它们放在非隐藏目录中有时会很好.以下makefile片段创建便利链接(在支持符号链接的平台上;否则复制它们).只需将片段添加到您的makefile(我通常使用的.libs/)就足够了(您可能需要-include convenience-link.mk在您的configure.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
Run Code Online (Sandbox Code Playgroud)