【问题标题】:how to create binary and .so using libtool如何使用 libtool 创建二进制文件和 .so
【发布时间】:2011-04-05 23:31:32
【问题描述】:

我有一组 cpp 文件,我想直接编译成二进制文件并编译成共享库。

我有

bin_PROGRAMS=mybin
lib_LTLIBRARIES=libmylib.la

COMMON_SOURCES=f1.cpp f2.cpp f3.cpp

mybin_SOURCES=main.cpp $(COMMON_SOURCES)
libmylib_la_SOURCES=$(COMMON_SOURCES)

当我运行它时,cpp 文件被编译两次,一次使用 libtool,一次没有,有时 libtool/automake 会报错

Makefile.am: object `f1.$(OBJEXT)' created both with libtool and without`

我尝试将 COMMON_SOURCES 放入 .a 文件,但当我将 .a 与 .la 链接时 libtool 会抱怨(说它不可移植)。

我需要的是类似的东西

bin_LTPROGRAMS=mybin

但那不存在

编辑:澄清 - 我正在使用 automake/autoconf。我上面展示的是我的 automake Makefile.am

【问题讨论】:

  • 我不认为你可以用 libtool 创建共享库。我相信你需要使用编译器。但是你忘记了一些细节。看起来您正在使用某种形式的自动制作等。所以您需要告诉我们您正在使用的确切设置(因为它似乎不是直接制作)。
  • libtool 专门用于制作共享库gnu.org/software/libtool/manual/libtool.html
  • 为什么要创建libmylib.so,而不是将mybin 链接到此共享对象,而是静态链接到组成它的源中?
  • 我希望能够将二进制文件作为独立模块分发。我希望能够对 .so 做同样的事情。老实说,这是有道理的

标签: c++ gcc autoconf automake libtool


【解决方案1】:

您必须为使用 libtool 创建的目标文件赋予不同的扩展名,以免它们发生冲突。事实上,这些文件是包含具有可重定位和不可重定位代码的目标文件的元信息的文本文件(这由 -fPIC gcc 命令行参数控制)。 libtool 创建的真实文件通常存储在“.libs”子目录中。基本的 makefile 将如下所示:

CC = $(CXX)
LIBTOOL = libtool --quiet

SRC = lib.cpp test.cpp
LIB_SRC = lib.cpp $(SRC)
LIB_OBJ = $(LIB_SRC:.cpp=.lo)

EXE_SRC = exe.cpp $(SRC)
EXE_OBJ = $(EXE_SRC:.cpp=.o)

EXE = test
LIB = libmylib.la

all: $(EXE) $(LIB)

clean:
    $(RM) *.o *.lo $(EXE) $(LIB)

$(EXE): $(EXE_OBJ)

$(LIB): $(LIB_OBJ)
    $(LIBTOOL) --tag=CXX --mode=link $(LINK.cc) -shared -version-info 1:0 -rpath $(shell readlink -f .) -o $@ $< $(LDLIBS)

%.o: %.cpp
    $(COMPILE.cc) -o $@ $<

%.lo: %.cpp
    $(LIBTOOL) --mode=compile --tag=CXX $(COMPILE.cc) -o $@ $<

【讨论】:

  • 谢谢。但 automake 正是这样做的。这就是为什么我最终得到关于同时拥有 .o 和 .lo 的错误消息的原因。我需要的是只编译一次 .lo 并将 .lo 文件链接到二进制文件和库中。 .o 和 .lo 之间的唯一区别是一个有 -fPIC 而另一个没有(并且将 -fPIC 代码链接到二进制文件是无害的)
  • 您不能链接到 .lo 文件,这些只是文本文件而不是目标代码。但是,在我的示例中,它编译了两次。如果你想用 libtool 创建的不可重定位代码(“.o”)文件链接对象,你可以在你的构建目录中找到它们,在“.libs”子目录下。
【解决方案2】:

专门针对公共资源库的链接:

bin_PROGRAMS = mybin
lib_LTLIBRARIES = libmylib.la

mybin_SOURCES = main.cpp
mybin_LDADD = libmylib.la
libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp

如果 libmylib.la 最终使用了不应链接到 mybin 的文件,请创建一个 libtool convenience library,使用类似这样的 Makefile.am

bin_PROGRAMS = mybin
noinst_LTLIBRARIES = libcommon.la
lib_LTLIBRARIES = libmylib.la

mybin_SOURCES = main.cpp
mybin_LDADD = libcommon.la

libmylib_la_SOURCES = f4.cpp f5.cpp f6.cpp
libmylib_la_LIBADD = libcommon.la

libcommon_la_SOURCES = f1.cpp f2.cpp f3.cpp

这会将f1.cppf2.cppf3.cppf4.cppf5.cppf6.cpp 链接到 libmylib.lamain.cppf1.cppf3.cpp 和 @98654337@3 mybin.

【讨论】:

  • 我这样做了,但我最终将 libmylib.la 动态链接到 mybin。我想要它是静态的。我输入了 mybin_LDFLAGS=-static 但它仍然是动态的
  • 如果你希望 mybin 被静态链接,我认为 libtool 会希望你输入 mybin_LDFLAGS = -all-static,而不是 -static。见info (libtool)Link mode。请注意,这将破坏 --disable-static 构建,除非您执行类似 AM_CONDITIONAL([HAVE_STATIC], [test "$enable_static" = yes]) 的操作并将 -all-static 放入条件中。
  • @pm100:当你说你尝试过这个时,你是直接链接到libmylib.la,还是链接到便利库?便利库可能会静态链接,这对您来说问题最少。尝试使用便利库。
  • 我都试过了,在这两种情况下,我都得到了动态链接库的二进制文件。我会用便利库再试一次
  • 如果你绝对必须有静态链接(我不确定为什么会这样,因为无论如何你都在安装库),你不能让这个方法工作,试试我的其他答案,让我知道情况如何。
【解决方案3】:

如果一个目标包含每个目标CFLAGS(或类似的),automake 将创建单独的目标文件来构建该目标。尝试向mybin 添加一些无操作标志,例如:

mybin_CPPFLAGS = -I.

mybin_CPPFLAGS = -DDUMMY -UDUMMY

【讨论】:

    【解决方案4】:

    问题是公共源代码在被制作成共享对象时需要以不同的方式编译,而不是被制作成静态存档时;对于前者,例如,g++ 需要传递 -fPIC 标志。

    我建议使用两个构建目录。

    假设这个源层次结构:

    ./src/Makefile.am ./src/f1.cpp ./src/f2.cpp ./src/f3.cpp ./src/main.cpp ./configure.ac ./Makefile.am

    你会在./src/Makefile.am中使用这样的东西:

    bin_PROGRAMS = mybin lib_LTLIBRARIES = libmylib.la mybin_SOURCES = main.cpp mybin_LDADD = libmylib.la libmylib_la_SOURCES = f1.cpp f2.cpp f3.cpp

    然后在./ 中创建目录ReleaseReleaseDisableShared。在目录./Release 你运行:

    ../configure && make
    

    然后在./ReleaseDisableShared 中运行:

    ../configure --disable-shared && make
    

    在每个构建目录中构建后,您在./ReleaseDisableShared/src/mybin 使用mybin,在./Release/src/libmylib.so 使用libmylib.so

    另见:

    【讨论】:

    • 这就是我最终要做的,大致是(我需要二进制文件和 lib,所以我在 2 个不同的目录中构建)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 2012-12-06
    • 2016-09-05
    相关资源
    最近更新 更多