使用cmake的autotools构建库

Jul*_*rra 33 build-automation build-process autotools cmake antlr3

这是我对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}
)
Run Code Online (Sandbox Code Playgroud)

主要问题是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
)
Run Code Online (Sandbox Code Playgroud)

ric*_*chq 46

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

project
      +- libantlr
      +- mysrc
  ---- etc ----
Run Code Online (Sandbox Code Playgroud)

如果是这种情况,您可以在顶级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})
Run Code Online (Sandbox Code Playgroud)

<INSTALL_DIR>被扩展为类似libantlr-prefix的东西,所以事情安装在构建树而不是/ usr/local中,这就是autotools在没有前缀的情况下会做的事情.

  • 很好的答案。只需考虑到“配置”需要“--prefix”的绝对路径。 (2认同)

4da*_*dan 10

我需要做一些类似的事情,但发现获得一个有效的解决方案非常困难,尽管这里提供的示例提供了可接受的答案,以及其他几篇博客文章、CMake 支持电子邮件列表服务档案等中提供的代码片段。遇到这个问题的其他人,这是我的解决方案。

我们想要使用的外部项目是libmodbus,但我相信我的解决方案足够通用,可以与任何配置autoconf./autoconf.sh && configure.sh && make && make install.

我们想添加libmodbus为我们 git 存储库的子模块。我们在 path 处添加到我们的存储库<root>/opt/libmodbusCMake配置它的代码位于 中<root>/cmake/modbus.cmake,它包含在我们的根目录中,CMakeLists.txt使用

# libmodbus
include(cmake/modbus.cmake)
Run Code Online (Sandbox Code Playgroud)

内容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})
Run Code Online (Sandbox Code Playgroud)

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

    add_executable(hello_modbus main.cpp)
    target_link_libraries(hello_modbus modbus)
Run Code Online (Sandbox Code Playgroud)

一些注意事项:

  1. 这滥用了DOWNLOAD_COMMAND执行autogen.sh步骤。这git clean -dfX可能不是必需的(它是使用该BUILD_IN_SOURCE选项的早期版本的剩余部分。如果您真的想下载代码而不是使用 git 子模块,您需要适当地修改这一行。
  2. 我们不厌其烦地强制对库进行仅静态构建。configure如果需要共享库,请调整命令行。
  3. 如果没有声明set_target_properties,设置 的命令IMPORTED_LOCATION将失败 BUILD_BYPRODUCTS ${MODBUS_STATIC_LIB}
  4. 同样,set_target_properties设置命令INTERFACE_INCLUDE_DIRECTORIES将失败没有file(MAKE_DIRECTORY ${MODBUS_INCLUDES})