Сборка библиотеки с использованием автоинструментов из cmake

Это моя первая попытка с cmake, и я хотел бы, если возможно, получить отзывы о том, что я сделал, поскольку некоторые проблемы остаются.

В CMakeLists.txt папки библиотеки я создал два целевых файла makefile: configure-antlr3c и antlr3c. Первая цель запускает сценарий оболочки конфигурации autotools, вторая - исполняемый файл 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 всегда «устарела», поэтому она всегда будет выполняться, даже если не произошло никаких изменений. Более того, мне обязательно нужно сгенерировать мои make-файлы cmake в отдельном каталоге (не в корневом каталоге моего проекта), чтобы избежать переопределения Makefile autotools библиотеки ...

У кого-нибудь была эта проблема (создание проектов автоинструментов с помощью cmake)? И если да, то каковы были ваши решения?

Спасибо.

РЕДАКТИРОВАТЬ: Решение В корневом файле 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
)

person Julio Guerra    schedule 12.05.2011    source источник
comment
Вы должны добавить свое решение в блок ответов; не в этом вопрос.   -  person jww    schedule 27.10.2017


Ответы (2)


Я думаю, вам лучше использовать ExternalProject особенность cmake. Полагаю, у вас есть проект, а в подкаталоге есть 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})

<INSTALL_DIR> расширяется до чего-то вроде libantlr-prefix, поэтому вещи устанавливаются в вашем дереве сборки, а не в / usr / local, что autotools делало бы без префикса.

person richq    schedule 12.05.2011
comment
Идеально ! И это отслеживает тот факт, что я только что скомпилировал его, и мне не нужно строить его каждый раз, когда у меня есть зависимость. Большое спасибо ;) - person Julio Guerra; 12.05.2011
comment
Хороший ответ. Просто примите во внимание, что configure нуждается в абсолютном пути для --prefix. - person Raúl Salinas-Monteagudo; 19.11.2013

Мне нужно было сделать что-то подобное, но оказалось на удивление трудным получить рабочее решение, несмотря на приведенный здесь пример с принятым ответом и фрагменты кода, представленные в нескольких других сообщениях в блогах, в архивах рассылки электронной почты поддержки CMake и т. Д. другие, кто сталкивается с этим вопросом, вот мое решение.

Мы хотели использовать внешний проект libmodbus, хотя я считаю, что мое решение достаточно общее, чтобы работать с любым проектом, настроенным по стандартному autoconf рецепту ./autoconf.sh && configure.sh && make && make install.

Мы хотели добавить libmodbus в качестве подмодуля нашего репозитория git. Добавляем в наш репозиторий по пути <root>/opt/libmodbus. CMake код для его настройки находится в <root>/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. Команда set_target_properties для установки IMPORTED_LOCATION не удастся без объявления BUILD_BYPRODUCTS ${MODBUS_STATIC_LIB}.
  4. Точно так же команда set_target_properties для установки INTERFACE_INCLUDE_DIRECTORIES не удастся без file(MAKE_DIRECTORY ${MODBUS_INCLUDES}).
person 4dan    schedule 25.11.2019
comment
Я случайно заключил строку после CONFIGURE_COMMAND в кавычки, и это не сработало. Потребовалось время, чтобы понять это. - person stackprotector; 19.09.2020