web-dev-qa-db-ja.com

CMake:自動検索機能FIND_PACKAGEなしでライブラリをリンクする方法は?

FIND_PACKAGEなしでライブラリを検索/リンクする方法を知りたいです。

Testlibという「個人用」ライブラリがあると仮定します。

_/perso/testlib/include/testlib1.h
/perso/testlib/include/testlib2.h
/perso/testlib/lib/testlib1.a
/perso/testlib/lib/testlib2.a
_

CMakeとリンクする方法は?

1)CMakeLists.txtのコードで直接リンクする関数は何ですか?

2)ユーザーがファイルの場所を選択できるようにするにはどうすればよいですか?

3)CMakeが何を解釈し、何を解釈しないのか理解するのが難しい。たとえば、変数$ {MYVARIABLE_INCLUDE_DIR}または$ {MYVARIABLE_LIBRARIES}が「INCLUDE_DIR」または「LIBRARIES」である場合、CMakeによって解釈される拡張機能です。または、この変数を$ {MYVARIABLE_INCDIR}と呼んでも違いはありませんか?

4)libディレクトリに10個以上のライブラリファイルを含むライブラリがある場合、同じ手順(「パーソナル」ライブラリを含む)を実行するにはどうすればよいですか?

5)最後に、TARGET_LINK_LIBRARIES(myexecutable gmp)と入力すると、ライブラリの名前が「gmp」であることをどのようにして知ることができますか。なぜ「Gmp」や「GMP」ではないのですか?この関数に入れるライブラリの名前は、.aファイルから「lib」と「.a」を引いたものと同じですか?たとえば、libgmp.a-> gmp? libtestlolexample.aというライブラリをリンクしたい場合、TARGET_LINK_LIBRARIES(myexecutable testlolexample)と入力する必要がありますか?

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

15
Vincent

target_link_libraries(myexecutable mylib)を使用して、ライブラリ「mylib」にリンクできます。コンパイラーは、デフォルトの方法を使用して、指定されたライブラリーを検索します(たとえば、Linuxではlibmylib.aを検索します)。コンパイラはlink_directories(directory1 directory2 ...)のみを検索するため、そのコマンドを試して、必要なディレクトリを検索パスに追加できます。

「mylib」もCMakeでコンパイルすると、これが認識され、すべてが自動的に機能するはずです。

ユーザーにディレクトリを指定してもらいたい場合は、キャッシュされたCMake変数を使用できます。 set(MYPATH "NOT-DEFINED" CACHE PATH "docstring")

より複雑なものについては、find_packageで使用できるCMake検索モジュールを作成することを強くお勧めします。良い出発点として使用できるFindALSA.cmakeをご覧になることをお勧めします。

興味深い部分は最後にあります:

if(ALSA_FOUND)
  set( ALSA_LIBRARIES ${ALSA_LIBRARY} )
  set( ALSA_INCLUDE_DIRS ${ALSA_INCLUDE_DIR} )
endif()

mark_as_advanced(ALSA_INCLUDE_DIR ALSA_LIBRARY)

ALSA_LIBRARY変数とALSA_INCLUDE_DIR変数はユーザーが構成可能で、キャッシュに保存されますが、ALSA_LIBRARIESALSA_INCLUDE_DIRSおよびALSA_FOUNDは計算され、 findモジュールのユーザーが使用することになっています。

通常、次のような検索モジュールを使用します。

find_package(ALSA REQUIRED)
include_directories(${ALSA_INCLUDE_DIRS})
target_link_libraries(myexe ${ALSA_LIBRARIES})

これをあなたの個人的な図書館に適応させることができると確信しています。

15
trenki

通常、find_packageモジュールを持たないライブラリ(たとえば、珍しいライブラリ、または独自のライブラリ)に対してリンクする場合は、基本コマンド(find_Xコマンド)を使用して、パスを使用して変数を設定できます。必要。次に、これらの変数をfind_package(_include_directories_、_target_link_libraries_)と同様に使用します。

複数のパッケージからこのライブラリを使用する場合は、find_packageモジュールを作成することをお勧めします。基本的には、特定の規則で同じコマンドを使用しています。

これらのいずれかを使用すると、(CMakeモジュールで)調べるパスを指定でき、ユーザーはパスをオーバーライドできます(変数はccmake/_cmake-gui_にオプションとして表示されます)。

これらの方法の一方または両方の例を追加できれば幸いです。探しているものをお知らせください。

迅速で汚い解決策が必要な場合は、これを行うことができますが、お勧めしません。

_include_directories(/perso/testlib/include)
add_executable(myexecutable myexecutable.cpp)
target_link_libraries(myexecutable
    /perso/testlib/lib/testlib1.a
    /perso/testlib/lib/testlib2.a)
_

_target_link_libraries_(#5)に関する質問については、いくつかの方法で行うことができます。必要に応じてフルネーム(例:target_link_libraries(myexe libfoo.a))を指定できますが、短い名前(例:_target_link_libraries(myexe foo_)を使用する方が良いと思います(より移植性が高いと思います)。リンカフラグを含めることもできます。どこで読んだかはわかりませんが、異なるリンカーの-Lフラグと-lフラグを変換する可能性があると思います。

たとえば、同じディレクトリに多数のライブラリがあり、名前がわかっている場合は、ディレクトリを見つけて変数に格納し、次のようにします。

_# First, find and set TESTLIB_LIBRARY_DIR, e.g. with find_path
# ...

# This assumes the libraries are e.g. 'libtestlib1.a' and 'libtestlib2.a'
set(TESTLIB_LIBRARIES
    -L${TESTLIB_LIBRARY_DIR)
    -l testlib1
    -l testlib2)

add_executable(myexecutable myexecutable.cpp)
target_link_libraries(myexecutable ${TESTLIB_LIBRARIES})
_

独自のfind_packageモジュールを作成したい場合(前述のtrenkiのように、_FindALSA.cmake_は良い出発点のようです)、ディレクトリを_CMAKE_MODULE_PATH_に追加することで使用できます。たとえば、モジュールを_cmake/modules/_サブディレクトリに配置した場合:

_# Look for extra CMake modules in a subdirectory of this project
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/" ${CMAKE_MODULE_PATH})
_

_FindALSA.cmake_で考えられる問題の1つ:_CMAKE_CURRENT_LIST_DIR_が機能するかどうかはわかりません。したがって、この変更を行う必要があると思います(私が作成したモジュールの2番目の作業):

_# Change this line
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)

# To this (with no path/extension it will search the CMake modules path):
include(FindPackageHandleStandardArgs)
_

また、_FIND_PACKAGE_HANDLE_STANDARD_ARGS_の使用法を取得するには、CMake Modulesディレクトリの_FindPackageHandleStandardArgs.cmake_を確認してください。

4
Sam Hartsfield

CMakeには良い ドキュメント があります。

  1. 静的リンケージ(私があなたが正しいと理解している場合)は、STATICキーワードを add_library に渡すことによってアーカイブされます
  2. 私はそれをしないことをお勧めします(私はCMakeの専門家ではありません)が、費用が高額になるようです。
  3. 違いはありません、 ${MYVARIABLE_INCLUDE_DIR}は、変数に名前を付けるだけではありません。ただし、命名規則に従うことをお勧めします。
  4. 1つのライブラリは常に1つの.lib/.aファイルであるため、 add_librarytarget_link_librariesadd_dependencies 関数を使用するだけで問題はありません。
  5. ライブラリ名は、常に add_library に渡す名前です。ただし、GmpまたはgMPは、CMakeがケースインテンシブであるのと同じです。
0
Mythli