46

以下を使用してファイルのリストを作成しました。

file(GLOB_RECURSE DEPLOY_FILES "${PROJECT_SOURCE_DIR}/install/*")

これらのファイルをすべてにインストールしたいのですが/usr/myproject/、インストールしたフォルダーにファイルツリーを保持したいと思います。

install/junk
install/other/junk2
install/other/junk3

私が使用する場合:

install(FILES ${DEPLOY_FILES} DESTINATION "usr/myproject")

すべてのファイルは、最終的に/ usr/myprojectに次のように配置されます。

/usr/myproject/junk
/usr/myproject/junk2
/usr/myproject/junk3

installコマンドで相対パスを追跡するにはどうすればよいですか?

私はforループで手動でそれを行うことによって問題を回避しました:

set(BASE "${PROJECT_SOURCE_DIR}/install")
foreach(ITEM ${DEPLOY_FILES})
  get_filename_component(ITEM_PATH ${ITEM} PATH)
  string(REPLACE ${BASE} "" ITEM_PATH ${ITEM_PATH})
  install(FILES ${ITEM} DESTINATION "usr/myproject${ITEM_PATH}")
endforeach()

...しかし、これは面倒です。確かにもっと簡単な方法はありますか?

(ただし、インストールドキュメントには何も表示されません...)

4

4 に答える 4

79

特定のディレクトリからすべてをインストールする最も簡単な方法は次のとおりです。

install(DIRECTORY mydir/ DESTINATION dir/newname)

末尾の「/」は重要です。 それがなければ、mydirにインストールされnewname/mydirます。

CMakeのドキュメントから:

各ディレクトリ名の最後のコンポーネントは宛先ディレクトリに追加されますが、最後のコンポーネントが空のままになるため、これを回避するために末尾のスラッシュを使用できます。

于 2014-05-20T17:25:57.167 に答える
38

私はあなたがファイルのリストを持っていると仮定しています、例えばINCLUDE_FILES。他の回答のように単一のサブディレクトリにあるすべてのものとは対照的に、ファイルの選択が複数のサブディレクトリに分散している可能性があります。たとえば、ソースツリー全体からのヘッダーファイルです。

ファイルリストをループしてget_filename_component()、ディレクトリ部分を抽出するために使用し、その後でそれを使用してサブディレクトリinstall()を設定できます。DESTINATION

foreach ( file ${INCLUDE_FILES} )
    get_filename_component( dir ${file} DIRECTORY )
    install( FILES ${file} DESTINATION include/${dir} )
endforeach()

終わり。;-)

編集:そのようにインストールしたいすべてのファイルが特定のファイルパターンに一致する場合(たとえば、「すべてのヘッダーファイル」)、brnoの答えはこれよりも優れています。

于 2014-09-19T12:29:55.683 に答える
32

使用する:

INSTALL( DIRECTORY <directory> DESTINATION usr/myproject )

(詳細については、こちらを参照してください:http ://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:install )

INSTALL( DIRECTORY ... )ディレクトリ構造を保持します。しかし、installとして使用すると<directory>、あなたがusr/myproject/install/....望むものではないことになります。

これを行うには2つの方法があります。

  1. を使用INSTALL( FILES .... DESTINATION usr/myproject)して、に直接存在するファイルをインストールしてから、 )をinstall/使用しINSTALL( DIRECTORY .... DESTINATION usr/myprojectて、インストールするディレクトリを手動で一覧表示します。

  2. 元の投稿でglobbingコマンドを使用して、どのエントリがファイルであるか、ディレクトリであるかを判断し、ディレクトリエントリを別のリストに移動し、リストをそれぞれINSTALL( FILES ...)とにフィードしますINSTALL( DIRECTORY ...)

    file(GLOB DEPLOY_FILES_AND_DIRS "${PROJECT_SOURCE_DIR}/install/*")
    foreach(ITEM ${DEPLOY_FILES_AND_DIRS})
       IF( IS_DIRECTORY "${ITEM}" )
          LIST( APPEND DIRS_TO_DEPLOY "${ITEM}" )
       ELSE()
          LIST( APPEND FILES_TO_DEPLOY "${ITEM}" )
       ENDIF()
    endforeach()
    INSTALL( FILES ${FILES_TO_DEPLOY} DESTINATION usr/myproject )
    INSTALL( DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION usr/myproject )
    

注:インストールするファイルのタイプによっては、他のINSTALL( ...)コマンドの方が適切な場合があります(たとえば、INSTALL( TARGETS .... )ライブラリ/実行可能ファイルをインストールする場合)。

于 2012-06-19T08:17:31.387 に答える
2

グロブは推奨されておらず、CMakeLists.txtファイルでループを実行するのは不格好なので、のパターンマッチングオプションDIRECTORYうまくいきました。

install(DIRECTORY src/ DESTINATION include FILES_MATCHING PATTERN "*.h")

これにより、フォルダ構造全体が内部に取り込まれ、ヘッダーファイルsrc/内でのみ再現されました。<INSTALL_DIR>/include

于 2021-06-08T07:18:33.017 に答える