[英]Building a library using autotools from cmake
This is my first try with cmake and I would like to have, if possible, some feedbacks about what I did since some problems remain.这是我第一次尝试 cmake,如果可能的话,我希望得到一些关于我所做的事情的反馈,因为一些问题仍然存在。
In the CMakeLists.txt of the library folder, I created two makefile targets: configure-antlr3c
and antlr3c
.在库文件夹的 CMakeLists.txt 中,我创建了两个 makefile 目标:
configure-antlr3c
和antlr3c
。 The first target runs the autotools configuration shell script, the second one runs the make executable to build the library:第一个目标运行 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}
)
The main problem is that configure-antlr3c
target is always "out of date", so it will always be executed even if no changes happened.主要问题是
configure-antlr3c
目标始终“过时”,因此即使没有发生任何更改,它也会始终执行。 Moreover, I necessarily need to generate my cmake makefiles in a separate directory (not in the root directory of my project) to avoid overriding the autotools Makefile of the library...此外,我必须在单独的目录中生成我的 cmake 生成文件(而不是在我的项目的根目录中),以避免覆盖库的自动工具生成文件...
Has anyone had this problem (building autotools projects with cmake) ?有没有人遇到过这个问题(用 cmake 构建 autotools 项目)? And if so, what have been your solutions ?
如果是这样,您的解决方案是什么?
Thank you.谢谢你。
EDIT : Solution In the root CMakeLists.txt:编辑:解决方案在根 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
)
I think that you'd be better off using the ExternalProject feature of cmake.我认为您最好使用 cmake 的ExternalProject功能。 I guess you have your project and have libantrl in a sub directory?
我猜你有你的项目并且在子目录中有 libantrl ?
project
+- libantlr
+- mysrc
---- etc ----
If that's the case, you can do something like this in the top level CMakeLists.txt:如果是这种情况,您可以在顶级 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})
The <INSTALL_DIR>
is expanded to something like libantlr-prefix, so things are installed in your build tree rather than in /usr/local, which is what autotools would do without a prefix. <INSTALL_DIR>
被扩展为类似 libantlr-prefix 的东西,所以东西被安装在你的构建树中而不是 /usr/local 中,这是 autotools 在没有前缀的情况下所做的。
I needed to do something similar but found it surprisingly difficult to get a working solution, despite the example provided here with the accepted answer, and code snippets provided in several other blog posts, the CMake support email listserv archives, etc. For the benefit of others who come across this question, here is my solution.我需要做一些类似的事情,但发现获得一个有效的解决方案非常困难,尽管这里提供的示例提供了可接受的答案,以及其他几篇博客文章、CMake 支持电子邮件列表服务档案等中提供的代码片段。为了利益遇到这个问题的其他人,这是我的解决方案。
The external project we wanted to use is libmodbus
, though I believe my solution is general enough to work with any project configured with the standard autoconf
recipe of ./autoconf.sh && configure.sh && make && make install
.我们想要使用的外部项目是
libmodbus
,尽管我相信我的解决方案足够通用,可以与使用./autoconf.sh && configure.sh && make && make install
的标准autoconf
配方配置的任何项目一起使用。
We wanted to add libmodbus
as a submodule of our git repository.我们想添加
libmodbus
作为我们 git 存储库的子模块。 We added to our repository at the path <root>/opt/libmodbus
.我们在路径
<root>/opt/libmodbus
添加到我们的存储库。 The CMake
code to configure it is located in <root>/cmake/modbus.cmake
, which is included from our root CMakeLists.txt
using配置它的
CMake
代码位于<root>/cmake/modbus.cmake
,它包含在我们的根CMakeLists.txt
使用
# libmodbus
include(cmake/modbus.cmake)
The content of cmake/modbus.cmake
is: 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})
A component that uses libmodbus
can declare its dependency as usual:使用
libmodbus
的组件可以像往常一样声明其依赖项:
add_executable(hello_modbus main.cpp)
target_link_libraries(hello_modbus modbus)
A few notes:一些注意事项:
DOWNLOAD_COMMAND
to perform the autogen.sh
step.DOWNLOAD_COMMAND
来执行autogen.sh
步骤。 The git clean -dfX
is probably not necessary (it is a leftover from an earlier version that used the BUILD_IN_SOURCE
option. If you really want to download the code instead of using a git submodule, you'll need to modify this line appropriately. git clean -dfX
可能不是必需的(它是使用BUILD_IN_SOURCE
选项的早期版本的BUILD_IN_SOURCE
。如果你真的想下载代码而不是使用 git 子模块,你需要适当地修改这一行。configure
command line if you want shared libraries.configure
命令行。set_target_properties
command to set the IMPORTED_LOCATION
will fail without the BUILD_BYPRODUCTS ${MODBUS_STATIC_LIB}
declaration.set_target_properties
命令设置IMPORTED_LOCATION
没有将失败BUILD_BYPRODUCTS ${MODBUS_STATIC_LIB}
声明。set_target_properties
command to set the INTERFACE_INCLUDE_DIRECTORIES
will fail without the file(MAKE_DIRECTORY ${MODBUS_INCLUDES})
.INTERFACE_INCLUDE_DIRECTORIES
的set_target_properties
命令将在没有file(MAKE_DIRECTORY ${MODBUS_INCLUDES})
情况下失败。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.