【问题标题】:Building a library using autotools from cmake使用来自 cmake 的 autotools 构建库
【发布时间】:2011-08-23 17:40:05
【问题描述】:

这是我第一次尝试使用 cmake,如果可能的话,我希望收到一些关于我所做工作的反馈,因为仍然存在一些问题。

在库文件夹的 CMakeLists.txt 中,我创建了两个 makefile 目标:configure-antlr3cantlr3c。第一个目标运行 autotools 配置 shell 脚本,第二个目标运行 make 可执行文件来构建库:

# CMakeLists.txt in libantlr3c-3.1.3 
add_custom_target(
  configure-antlr3c
  ${SHELL_EXECUTABLE} configure
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(
  antlr3c
   ${MAKE}
   DEPENDS configure-antlr3c
   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

主要问题是configure-antlr3c目标总是“过时”,所以即使没有发生任何变化,它也会一直执行。此外,我必须在单独的目录(而不是我的项目的根目录)中生成我的 cmake makefile,以避免覆盖库的 autotools Makefile...

有没有人遇到过这个问题(使用 cmake 构建 autotools 项目)?如果是这样,您的解决方案是什么?

谢谢。

编辑:解决方案 在根 CMakeLists.txt 中:

include(ExternalProject)
ExternalProject_Add(
  libantlr3c
  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/libantlr3c-3.1.3
  CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lib/libantlr3c-3.1.3/configure --prefix=${CMAKE_CURRENT_SOURCE_DIR}/lib/libantlr3c-3.1.3
  PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/lib/libantlr3c-3.1.3
  BUILD_COMMAND make
  BUILD_IN_SOURCE 1
)

【问题讨论】:

  • 您应该将您的解决方案添加到答案块中;不在问题中。

标签: build-process build-automation cmake autotools antlr3


【解决方案1】:

我认为你最好使用 cmake 的ExternalProject 功能。我猜你有你的项目并且在子目录中有 libantrl?

project
      +- libantlr
      +- mysrc
  ---- etc ----

如果是这样,您可以在顶级 CMakeLists.txt 中执行类似操作:

cmake_minimum_required(VERSION 2.8)
project(test)
include(ExternalProject)
ExternalProject_Add(libantlr
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libantlr
    CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/libantlr/configure --prefix=<INSTALL_DIR>
    BUILD_COMMAND ${MAKE})

&lt;INSTALL_DIR&gt; 被扩展为类似 libantlr-prefix 的东西,所以东西安装在你的构建树中,而不是 /usr/local 中,这是 autotools 在没有前缀的情况下所做的。

【讨论】:

  • 完美!这会跟踪我刚刚编译它的事实,并且每次我有依赖项时都不需要构建它。非常感谢;)
  • 不错的答案。只需考虑到“配置”需要“--prefix”的绝对路径。
【解决方案2】:

我需要做类似的事情,但发现很难找到一个可行的解决方案,尽管此处提供的示例带有已接受的答案,并且在其他几篇博客文章、CMake 支持电子邮件列表服务档案等中提供了代码 sn-ps . 为了其他遇到此问题的人的利益,这是我的解决方案。

我们想要使用的外部项目是libmodbus,尽管我相信我的解决方案足够通用,可以与任何使用./autoconf.sh &amp;&amp; configure.sh &amp;&amp; make &amp;&amp; make install 的标准autoconf 配方配置的项目一起使用。

我们想将libmodbus 添加为我们的 git 存储库的子模块。我们在路径&lt;root&gt;/opt/libmodbus 添加到我们的存储库。配置它的CMake 代码位于&lt;root&gt;/cmake/modbus.cmake,它包含在我们的根CMakeLists.txt 中使用

# libmodbus
include(cmake/modbus.cmake)

cmake/modbus.cmake的内容是:

include(ExternalProject)

set(MODBUS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/opt/libmodbus)
set(MODBUS_BIN ${CMAKE_CURRENT_BINARY_DIR}/libmodbus)
set(MODBUS_STATIC_LIB ${MODBUS_BIN}/lib/libmodbus.a)
set(MODBUS_INCLUDES ${MODBUS_BIN}/include)

file(MAKE_DIRECTORY ${MODBUS_INCLUDES})

ExternalProject_Add(
    libmodbus
    PREFIX ${MODBUS_BIN}
    SOURCE_DIR ${MODBUS_DIR}
    DOWNLOAD_COMMAND cd ${MODBUS_DIR} && git clean -dfX && ${MODBUS_DIR}/autogen.sh
    CONFIGURE_COMMAND ${MODBUS_DIR}/configure --srcdir=${MODBUS_DIR} --prefix=${MODBUS_BIN} --enable-static=yes --disable-shared
    BUILD_COMMAND make
    INSTALL_COMMAND make install
    BUILD_BYPRODUCTS ${MODBUS_STATIC_LIB}
)

add_library(modbus STATIC IMPORTED GLOBAL)

add_dependencies(modbus libmodbus)

set_target_properties(modbus PROPERTIES IMPORTED_LOCATION ${MODBUS_STATIC_LIB})
set_target_properties(modbus PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${MODBUS_INCLUDES})

使用libmodbus的组件可以像往常一样声明它的依赖:

    add_executable(hello_modbus main.cpp)
    target_link_libraries(hello_modbus modbus)

几点说明:

  1. 这会滥用DOWNLOAD_COMMAND 来执行autogen.sh 步骤。 git clean -dfX 可能不是必需的(它是使用 BUILD_IN_SOURCE 选项的早期版本的遗留物。如果您真的想下载代码而不是使用 git 子模块,则需要适当地修改此行。
  2. 我们不厌其烦地强制只构建静态库。如果您想要共享库,请调整您的 configure 命令行。
  3. 如果没有 BUILD_BYPRODUCTS ${MODBUS_STATIC_LIB} 声明,设置 IMPORTED_LOCATIONset_target_properties 命令将失败。
  4. 同样,设置INTERFACE_INCLUDE_DIRECTORIESset_target_properties 命令将在没有file(MAKE_DIRECTORY ${MODBUS_INCLUDES}) 的情况下失败。

【讨论】:

  • 我不小心将CONFIGURE_COMMAND 后面的行用引号括起来,但它不起作用。花了一些时间才弄清楚。
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 2022-01-07
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多