使用 Autotools 创建新的共享库

发布于 2024-09-07 17:59:57 字数 512 浏览 2 评论 0原文

我想要做的是创建一个名为 libxxx 的新共享库,它链接到另一个名为 libzzz 的共享库,这个共享库有一个独立的“pkg-config”-like工具,假设它名为“zzz-config”,它提供使用 libzzz 时编译阶段所需的 cflags。 我想做的是:

  • 使用 automake、autoconf 等自动工具创建配置/makefile 等;
  • 它必须使用上面引用的 zzz-config 脚本;
  • 它必须自动生成源的依赖关系;
  • 它必须具有用于构建调试(无优化)和发布(有优化)构建的模式;
  • 源代码是 C++ 的;
  • 它必须针对共享库;
  • 它必须读取 src 目录的源代码并将编译后的文件放在另一个目录中

我已经阅读了几乎所有可用的自动工具教程,但我无法找到一种方法来做到这一点,如果你能指出一些例子会非常友善。

谢谢 !

What I want to do is to create a new shared library called libxxx that links against another shared library called libzzz, this shared library has an independent "pkg-config"-like tool, let's say it's called "zzz-config" which gives the cflags needed by the compilation phase when using the libzzz.
What I want to do is:

  • Create configure/makefile, etc.. using autotools like automake, autoconf, etc;
  • It must use the zzz-config script cited above;
  • It must generate automatic dependencies for sources;
  • It must have a mode for building debug (with no optimization) and release (with optimizations) builds;
  • The sources are in C++;
  • It must target for a shared library;
  • It must read sources for a src directory and put compiled files in another directory

I've read almost all available tutorials for autotools but I was not able to figure a way to do that, if you can point some example would be very kindly.

Thank you !

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

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

发布评论

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

评论(3

若相惜即相离 2024-09-14 17:59:57

使用自动工具可以很容易地做到这一点。有几点需要注意:libzzz 可能会提供一个宏来为您完成大部分工作。例如,glib 提供了一个名为 AM_PATH_GLIB_2_0 的宏,它与库一起安装,因此您只需在 configure.ac 中调用它即可。 (请注意,该宏命名错误,因为它破坏了 automake 的命名空间,但这完全是另一个问题。)这是一个示例configure.ac和Makefile.am,可以执行您想要的操作(请参阅下面有关调试和发布版本的注释):

configure.ac:Makefile.am

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.66])
AC_INIT([libxxx], [0.0.0], [[email protected]])
AC_CONFIG_SRCDIR([libxxx.cc])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_PROG_CXX

# Checks for libraries.
# If libzzz has an autoconf macro use it.  Otherwise:
AC_PATH_PROG([ZZZ_CONFIG],[zzz-config],[none])
AS_IF([test x"$ZZZ_CONFIG" = xnone],[
    AC_MSG_ERROR([zzz-config not found in PATH])
])
CPPFLAGS="$CPPFLAGS $(zzz-config -cflags)"
LIBS="$(zzz-config -libs) $LIBS"  # Totally unnecessary: we're not linking
# If zzz-config is found, we can probably assume that
# libzzz is installed, but check anyway:
AC_CHECK_LIB([zzz],[main],[],[AC_MSG_ERROR([libzzz required])])

# Checks for header files.
AC_CHECK_HEADERS([zzz.h])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

在进行调试或发布构建方面,有很多方法可以使用自动工具来完成

lib_LTLIBRARIES = libxxx.la
libxxx_la_SOURCES = libxxx.cc
include_HEADERS = xxx.h
libxxx_la_LDFLAGS = -version-info 0:0:0

此操作,而根本不需要编辑构建脚本。规范的方法是在调用configure时设置CXXFLAGS(例如,将CXXFLAGS=-O2 CPPFLAGS=-DNDEBUG作为参数传递给configure以获得发​​布版本)。您还可以通过将这些分配写入 /usr/local/share/config.site 来设置系统,以便在 /usr/local 中安装的所有内容都将成为发布版本,而在 $HOME 中为安装而构建的所有内容都将成为调试版本通过将 'CXXFLAGS="-g -O0"' 写入 $HOME/share/config.site。如果你想在配置时给用户一个 --disable-assert 选项来关闭断言,你可以在 configure.ac 中调用 AC_HEADER_ASSERT (但用户将 -DNDEBUG 放入 CPPFLAGS 中实际上同样容易)。您可以做的另一件好事是利用 automake 的 VPATH 构建来配置不同的构建目录,其中每个目录都进行了适当的配置。

但是,如果您确实觉得需要将功能添加到构建脚本中,则可以尝试在configure.ac 中添加类似的内容:

AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],
    [configure a debug build]),
    [CXXFLAGS="$CXXFLAGS -g -O0"])
AC_ARG_ENABLE([release],AS_HELP_STRING([--enable-release],
    [configure a release build]),
    [CPPFLAGS="$CPPFLAGS -DNDEBUG"]
    [CXXFLAGS="$CXXFLAGS -O2"])

请注意,这是可靠的,可能会给用户带来困惑。例如,如果用户使用 config.site 将 CPPFLAGS 设置为 -DDEBUG 但调用 --enable-release,则 CPPFLAGS 将包含“-DDEBUG -DNDEBUG”。如果您尝试完全重置 CPPFLAGS 以响应 --enable-release,则 libzzz 所需的 -I 标志将丢失。您可以通过 AC_SUBST'ing LIBZZZ_CFLAGS 并对 Makefile.am 进行修改来避免最后一个问题,但教育用户在调用配置时设置 CPPFLAGS 和 CXXFLAGS 确实更容易。

在我的答案中查看更多信息:https://stackoverflow.com/a/4680578/140750

It's fairly easy to do this with the autotools. A few things to note: libzzz might provide a macro to do most of the work for you. For example, glib provides a macro named AM_PATH_GLIB_2_0 that is installed along with the library, so that you merely need to invoke it in your configure.ac. (Note that the macro is misnamed, since it stomps on automake's namespace, but that is another issue entirely.) Here's a sample configure.ac and Makefile.am that does what you want (see below for remarks on debug and release builds):

configure.ac:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.66])
AC_INIT([libxxx], [0.0.0], [[email protected]])
AC_CONFIG_SRCDIR([libxxx.cc])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_PROG_CXX

# Checks for libraries.
# If libzzz has an autoconf macro use it.  Otherwise:
AC_PATH_PROG([ZZZ_CONFIG],[zzz-config],[none])
AS_IF([test x"$ZZZ_CONFIG" = xnone],[
    AC_MSG_ERROR([zzz-config not found in PATH])
])
CPPFLAGS="$CPPFLAGS $(zzz-config -cflags)"
LIBS="$(zzz-config -libs) $LIBS"  # Totally unnecessary: we're not linking
# If zzz-config is found, we can probably assume that
# libzzz is installed, but check anyway:
AC_CHECK_LIB([zzz],[main],[],[AC_MSG_ERROR([libzzz required])])

# Checks for header files.
AC_CHECK_HEADERS([zzz.h])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Makefile.am

lib_LTLIBRARIES = libxxx.la
libxxx_la_SOURCES = libxxx.cc
include_HEADERS = xxx.h
libxxx_la_LDFLAGS = -version-info 0:0:0

In terms of doing debug or release builds, there are lots of ways to do that with the autotools that do not involve editing the build scripts at all. The canonical way to do it is to set CXXFLAGS when you invoke configure (eg pass CXXFLAGS=-O2 CPPFLAGS=-DNDEBUG as arguments to configure to get a release build). You can also set your system up so that everything you install in /usr/local will be a release build by writing those assignments into /usr/local/share/config.site while everything built for install in $HOME will be a debug build by writing 'CXXFLAGS="-g -O0"' into $HOME/share/config.site. You could invoke AC_HEADER_ASSERT in configure.ac if you want to give the user a --disable-assert option at configure time to turn off assertions (but it's really just as easy for the user to put -DNDEBUG into CPPFLAGS). Another nice thing you can do is exploit automake's VPATH builds to configure distinct build directories where each is configured appropriately.

However, if you really feel the need to add the functionality into your build scripts, you can try putting something like this in configure.ac:

AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],
    [configure a debug build]),
    [CXXFLAGS="$CXXFLAGS -g -O0"])
AC_ARG_ENABLE([release],AS_HELP_STRING([--enable-release],
    [configure a release build]),
    [CPPFLAGS="$CPPFLAGS -DNDEBUG"]
    [CXXFLAGS="$CXXFLAGS -O2"])

Note that this is not reliable and may cause confusion to the user. For example, if the user is using a config.site to set CPPFLAGS to -DDEBUG but invokes --enable-release, then CPPFLAGS will include "-DDEBUG -DNDEBUG". If you try to completely reset CPPFLAGS in response to --enable-release, then the -I flags needed for libzzz will be lost. You can avoid that last problem by AC_SUBST'ing LIBZZZ_CFLAGS and making modifications to Makefile.am, but it really is just easier to educate your user to set CPPFLAGS and CXXFLAGS when they invoke configure.

See more in my answer here: https://stackoverflow.com/a/4680578/140750

悲歌长辞 2024-09-14 17:59:57

我也会远离自动工具。

同样,我使用 Cmake 的经历也不是很出色。事情可能已经改变了,但当我不久前尝试学习它时,文档却不存在。

我倾向于使用 scons: http://www.scons.org/

这就是说我不知道它在大型项目(即数千个或更多文件)上的表现如何。对于小型或中型项目来说还是可以的。

您也可以尝试 qmake,但我只建议您使用 Qt。

I would also stay away from autotools.

As well, my experiences with Cmake have been less than stellar. Things may have changed, but the documentation was just not there when I was trying to learn it a while back.

I tend to use scons: http://www.scons.org/

That said I don't know how well it performs on large projects, (i.e. thousands or more files). For smaller or medium projects it's fine though.

You could also try qmake, but I'd only recommend that if you were using Qt.

半仙 2024-09-14 17:59:57

我的建议是使用 CMake 而不是 autotools。它更容易使用,并且还可以创建依赖于平台的项目(即基于 Makefile 的项目、Visual Studio 项目、Eclipse CDT 项目等)。

它还将创建 debugrelease 项目,具体取决于 CMAKE_BUILD_TYPE 变量值。

创建 libxxx 库非常简单:

add_library(libxxx SHARED ${LIBXXX_SOURCES})

其中 LIBXXX_SOURCES 是保存源的变量。

链接这两个库同样简单(请参阅 target_link_libraries):

target_link_libraries(libxxx libzzz)

要从 zzz-config 脚本获取编译标志,您可以使用 execute_process 命令如下:

execute_process(COMMAND ./zzz-config 
                WORKING_DIRECTORY "<your_working_directory>"
                OUTPUT_VARIABLE ZZZ_FLAGS)

然后您可以设置 CMAKE_C_FLAGSCMAKE_CXX_FLAGS 变量来设置所需的编译标志。

My suggestion is to use CMake instead of autotools. It's much easier to work with and it will also create platform-dependent projects to work with (i.e. Makefile-based projects, Visual Studio projects, Eclipse CDT projects, etc.).

It will also create debug or release projects, depending on the CMAKE_BUILD_TYPE variable value.

Creating the libxxx library is as simple as:

add_library(libxxx SHARED ${LIBXXX_SOURCES})

where LIBXXX_SOURCES is a variable that holds the sources.

Linking the two libraries is just as easy (see target_link_libraries):

target_link_libraries(libxxx libzzz)

To get the compilation flags from the zzz-config script you would use the execute_process command like so:

execute_process(COMMAND ./zzz-config 
                WORKING_DIRECTORY "<your_working_directory>"
                OUTPUT_VARIABLE ZZZ_FLAGS)

Then you can set the CMAKE_C_FLAGS or the CMAKE_CXX_FLAGS variable to setup the required compilation flags.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文