如何使用libtool创建二进制文件和.so

时间:2010-08-30 21:15:54

标签: c++ gcc autoconf automake libtool

我有一组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

的内容

4 个答案:

答案 0 :(得分:4)

特别是针对共同来源库的链接:

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相关联,请使用Makefile.am这样的内容创建libtool convenience library

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.la和{{ 1}},main.cppf1.cppf2.cpp加入f3.cpp

答案 1 :(得分:3)

问题在于,当将公共资源创建为共享对象时,需要对它们进行不同的编译,而不是将它们编入静态存档中。例如,在前者的情况下,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

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

../configure && make

并在./ReleaseDisableShared中运行:

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

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

另见:

答案 2 :(得分:2)

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

mybin_CPPFLAGS = -I.

mybin_CPPFLAGS = -DDUMMY -UDUMMY

答案 3 :(得分:0)

您必须为使用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 $@ $<