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

发布于 2024-09-16 07:03:23 字数 631 浏览 10 评论 0原文

我有一组 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 的主要内容

I have a set of cpp files that I want to compile directly into a binary and also to compile into a shared library.

I have

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)

When I run this the cpp files are compiled twice, once with libtool and once without and sometimes libtool/automake complains

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

I tried putting COMMON_SOURCES into a .a file but then libtool complains when I link a .a with a .la (saying its not portable).

What I need is something like

bin_LTPROGRAMS=mybin

but that doesnt exist

edit: clarification - I am using automake/autoconf. What I have shown above is the meat of my automake Makefile.am

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

野侃 2024-09-23 07:03:23

具体链接到公共源库:

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 .cppf2.cppf3.cppf4.cppf5.cppf6.cpplibmylib.lamain.cppf1.cppf2。 cppf3.cppmybin 中。

Link against the library of common sources specifically:

bin_PROGRAMS = mybin
lib_LTLIBRARIES = libmylib.la

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

If libmylib.la ends up using files that shouldn't be linked into mybin, create a libtool convenience library, using a Makefile.am something like this:

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

This will link f1.cpp, f2.cpp, f3.cpp, f4.cpp, f5.cpp and f6.cpp into libmylib.la and main.cpp, f1.cpp, f2.cpp and f3.cpp into mybin.

甩你一脸翔 2024-09-23 07:03:23

问题在于,将公共源制作成共享对象时与制作成静态档案时需要进行不同的编译;例如,在前者的情况下,需要向 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

然后您在 ./src/Makefile.am 中创建目录 ReleaseReleaseDisableShared代码>./。在目录 ./Release 中运行:

../configure && make

./ReleaseDisableShared 中运行:

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

在每个构建目录中构建后,在 ./ReleaseDisableShared 中使用 mybin code>./ReleaseDisableShared/src/mybin 和 ./Release/src/libmylib.so 处的 libmylib.so

另请参阅:

The issue is that the common sources need to be compiled differently when they are being made into a shared object than when they are being made into a static archive; in the case of the former, for example, g++ needs to be passed the -fPIC flag.

What I suggest is using two build directories.

Assuming this source hierarchy:

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

you would use something like this in ./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

Then you create directories Release and ReleaseDisableShared in ./. In directory ./Release you run:

../configure && make

and in ./ReleaseDisableShared you run:

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

After building in each build directory, you use the mybin at ./ReleaseDisableShared/src/mybin and the libmylib.so at ./Release/src/libmylib.so.

See also:

情丝乱 2024-09-23 07:03:23

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

mybin_CPPFLAGS = -I.

mybin_CPPFLAGS = -DDUMMY -UDUMMY

If a target contains per-target CFLAGS (or similar), automake will make separate object files for building that target. Try adding some no-op flags to mybin, something like:

mybin_CPPFLAGS = -I.

or

mybin_CPPFLAGS = -DDUMMY -UDUMMY
老子叫无熙 2024-09-23 07:03:23

您必须为使用 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 $@ 
lt; $(LDLIBS)

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

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

You have to give object files created with libtool a different extension so they do not conflict. In fact, those files are text files containing meta information for both object files with relocatable and non-relocatable code (this is controlled with -fPIC gcc command line argument). The real files created by libtool are usually stored in ".libs" subdirectory. The basic makefile will look like this:

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 $@ 
lt; $(LDLIBS)

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

%.lo: %.cpp
    $(LIBTOOL) --mode=compile --tag=CXX $(COMPILE.cc) -o $@ 
lt;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文