原始问题作者在对问题的评论中询问了使用Automake、Libtool并将LDADD
在一个目录中编译的程序与在第二个目录中编译的共享库链接的示例。这是一个完整的、独立的、完整的示例,说明如何使用 GNU Autotools 在同一源代码树的不同目录中编译库和程序。
目录结构
我们需要建立一个目录结构如下:
├ A/
│ ├ Makefile.am
│ ├ helloworld.c
│ └ helloworld.h
├ B/
│ ├ Makefile.am
│ └ foo.c
├ configure.ac
└ Makefile.am
共享库将在目录中编译A/
,使用它的程序在目录中B/
。
编写源代码
有三个源文件。
A/helloworld.c
是库的源代码。它导出一个过程,say_hello()
,打印消息“Hello world!” 到标准输出。
#include <stdio.h>
#include "helloworld.h"
void
say_hello (void)
{
printf ("Hello world!\n");
}
A/helloworld.h
是包含say_hello()
函数声明的头文件。它只有一行:
void say_hello (void);
最后,B/foo.c
是使用共享库的程序的源代码。它包括库的头文件,并调用say_hello()
.
#include <helloworld.h>
int
main (int argc, char **argv)
{
say_hello ();
return 0;
}
编译库
我们将使用 Automake 和 Libtool 来编译共享库。这两个工具都非常强大,并且实际上非常有据可查。手册(Automake,Libtool)绝对值得一读。
该A/Makefile.am
文件用于automake
控制库的编译。
# We're going to compile one libtool library, installed to ${libdir},
# and named libhelloworld.
lib_LTLIBRARIES = libhelloworld.la
# List the source files used by libhelloworld.
libhelloworld_la_SOURCES = helloworld.c
# We install a single header file to ${includedir}
include_HEADERS = helloworld.h
编译程序
该B/Makefile.am
文件控制库的编译。我们需要使用LDADD
变量来告诉automake
链接到我们之前编译的库。
# Compile one program, called foo, and installed to ${bindir}, with a single C
# source file.
bin_PROGRAMS = foo
foo_SOURCES = foo.c
# Link against our uninstalled copy of libhelloworld.
LDADD = $(top_builddir)/A/libhelloworld.la
# Make sure we can find the uninstalled header file.
AM_CPPFLAGS = -I$(top_srcdir)/A
控制构建
最后,我们需要一个顶层Makefile.am
来告诉 Automake 如何构建项目,以及一个configure.ac
文件来告诉 Autoconf 如何找到所需的工具。
顶层Makefile.am
相当简单:
# Compile two subdirectories. We need to compile A/ first so the shared library is
# available to link against.
SUBDIRS = A B
# libtool requires some M4 scripts to be added to the source tree. Make sure that
# Autoconf knows where to find them.
ACLOCAL_AMFLAGS = -I m4
最后,该configure.ac
文件告诉 Autoconf 如何创建configure
脚本。
AC_INIT([libhelloworld], 1, peter@peter-b.co.uk)
# This is used to help configure check whether the source code is actually present, and
# that it isn't being run from some random directory.
AC_CONFIG_SRCDIR([A/helloworld.c])
# Put M4 macros in the m4/ subdirectory.
AC_CONFIG_MACRO_DIR([m4])
# We're using automake, but we want to turn off complaints about missing README files
# etc., so we need the "foreign" option.
AM_INIT_AUTOMAKE([foreign])
# We need a C compiler
AC_PROG_CC
# Find the tools etc. needed by libtool
AC_PROG_LIBTOOL
# configure needs to generate three Makefiles.
AC_CONFIG_FILES([A/Makefile
B/Makefile
Makefile])
AC_OUTPUT
测试一下
跑:
$ autoreconf -i
$ ./configure
$ make
$ B/foo
您应该会看到所需的输出:“Hello world!”