web-dev-qa-db-ja.com

cmakeからautotoolsを使用してライブラリを構築する

これはcmakeを使った私の最初の試みであり、いくつかの問題が残っているので、可能であれば、私がしたことについていくつかのフィードバックが欲しいです。

ライブラリフォルダーのCMakeLists.txtに、2つのmakefileターゲットを作成しました:configure-antlr3cおよびantlr3c。最初のターゲットはautotools構成のシェルスクリプトを実行し、2番目のターゲットは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 targetは常に「古い」ため、変更が発生しなくても常に実行されます。さらに、ライブラリのautotools Makefileの上書きを避けるために、(プロジェクトのルートディレクトリではなく)別のディレクトリにcmake makefileを生成する必要があります...

誰かがこの問題を抱えていましたか(cmakeを使用してautotoolsプロジェクトをビルド)。もしそうなら、あなたの解決策は何でしたか?

ありがとうございました。

EDIT:Solutionルート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
)
35
Julio Guerra

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})

<INSTALL_DIR>はlibantlr-prefixのようなものに展開されるため、物事は/ usr/localではなくビルドツリーにインストールされます。これは、autotoolsがプレフィックスなしで行うことです。

48
richq

私は同様のことをする必要がありましたが、ここで受け入れられた回答、および他のいくつかのブログ投稿、CMakeサポートメールlistservアーカイブなどで提供されているコードスニペットの例にもかかわらず、実用的なソリューションを取得することは驚くほど困難であることがわかりました。この質問に遭遇した他の人は、ここに私の解決策があります。

私が使用したい外部プロジェクトは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})なしでは失敗します。
2
4dan