我有一组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
的内容答案 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.cpp
,f2.cpp
,f3.cpp
,f4.cpp
,f5.cpp
和f6.cpp
关联到libmylib.la
和{{ 1}},main.cpp
,f1.cpp
和f2.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/mybin
和libmylib.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 $@ $<