10

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

4 回答 4

5

具体链接到公共资源库:

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 便利库,使用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.cpp, f2.cpp, f3.cpp,和链接到and , f4.cpp, and into 。f5.cppf6.cpplibmylib.lamain.cppf1.cppf2.cppf3.cppmybin

于 2010-09-02T01:56:21.450 回答
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

然后创建目录ReleaseReleaseDisableShared./. 在./Release您运行的目录中:

../configure && make

./ReleaseDisableShared你运行:

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

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

也可以看看:

于 2010-09-03T00:43:30.953 回答
2

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

mybin_CPPFLAGS = -I.

或者

mybin_CPPFLAGS = -DDUMMY -UDUMMY
于 2010-09-02T22:19:48.680 回答
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 $@ $<
于 2010-09-01T22:05:58.813 回答