2

コンパイル時にソリューションの dll をコピーする必要があるため、次のように add_custom_command を使用しています。

function(dll_dependencies TEST_CASE )
foreach(depencency ${ARGN})        
    add_custom_command(TARGET ${TEST_CASE} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
        $<DLL_FILE_NAME:${depencency}>)
endforeach()
endfunction()

cmakelist.txt で、上記の関数を次のように呼び出しています。

dll_dependencies(performance QT5::Core QT5::FileSystem)

しかし、私は次のようにエラーが発生しています:

Error evaluating generator expression:
$<DLL_FILE_NAME:QT5::Core>

Error evaluating generator expression:
$<DLL_FILE_NAME:QT5::FileSystem>

それで、qt関連のものがインストールされている場所に到達できないのか、それとも add_custom_command ジェネレーター式で間違いを犯しているのでしょうか? 関数を非常に一般的なものにして、ソリューションで取得したい dll がコンパイル中にターゲット内に配置されるようにしたいと考えています。

4

1 に答える 1

4

すべての依存関係を一般的な方法で管理することはできません。これは一般的な問題ではないためです。試すのは得策ではないと主張します。

たとえば、Qt を取り上げます (これは、質問で言及されている唯一の依存関係です)。Windows では、Qt dll の依存関係をコピーする正しい方法は、windeployqt.exe. Qt アプリを実行するには、dll をコピーするだけでなく、バ​​イナリ ディレクトリに正確にミラーリングする必要があるディレクトリ構造/依存関係があります。windeployqtがすべてを行います。他の方法で Qt dll の依存関係を管理することは、悪い考えです。ツールと戦ったり、車輪を再発明したりする理由はありません。

実行するためのカスタムビルドステップは次のwindeployqtとおりです。

# Windows specific build steps
if(WIN32)
    # Run winddeployqt if it can be found
    find_program(WINDEPLOYQT_EXECUTABLE NAMES windeployqt HINTS ${QTDIR} ENV QTDIR PATH_SUFFIXES bin)
    add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
    COMMAND ${WINDEPLOYQT_EXECUTABLE} $<TARGET_FILE:${TARGET_NAME}>)
endif()

それを見つけて、ビルド後のステップとして実行します。単純。

以下を前提としています。

  • Qt ルート パスは、QTDIRcmake または環境変数で設定されます。
  • 実行可能なターゲット名は変数に格納されますTARGET_NAME

より一般的に (Windows の場合、cmake < 3.5):

非 qt dll (この場合は qwt) の場合、次のような手順があります。

# on windows, to copy, we need to replace the pesky forward slashes with back slashes
STRING(REGEX REPLACE "/" "\\\\" copySource \"${QWT_DIR}/lib/*.dll\")
STRING(REGEX REPLACE "/" "\\\\" copyDest \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>\")

# Copy
ADD_CUSTOM_COMMAND( TARGET ${TARGET_NAME}
    POST_BUILD
    COMMAND COMMAND copy ${copySource} ${copyDest}
    COMMENT "Copying Qwt dll's...\n"
)

通常はこれでうまくいきますが、おそらく大量のゴミをコピーすることにもなります。Dll の場所 ( で指定) を知る必要があることに注意してください${QWT_DIR}。環境変数はあなたの友達かもしれません。

必要に応じて使用${CMAKE_COMMAND} -E copyすることも、dll lib の場所を取得する関数に変換することもできます。

さらに一般的に (cmake >= 3.5):

@Florian は、共有ライブラリのコピー ステップをクロスプラットフォームにするための非常に役立つ提案をいくつか行いました。file(TO_NATIVE_PATH)正規表現をに、接尾辞を cmake 変数に、copyコマンドを cmake コマンドライン コピーに置き換えると、次のようになります。

file(TO_NATIVE_PATH "${QWT_DIR}/lib/*.${CMAKE_SHARED_LIBRARY_SUFFIX}" copy_source)
set(copy_dest "$<TARGET_FILE_DIR:${TARGET_NAME}>")

# perform copy
ADD_CUSTOM_COMMAND(TARGET ${TARGET_NAME}
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy ${copySource} ${copyDest}
)

コメントで述べたように、cmake -E copy でのワイルドカード(*) の使用は、バージョン 3.5 まで機能しませんでした。古いバージョンでは、プラットフォーム固有のコピー コマンドを含む変数を使用できます。

于 2016-05-02T14:32:50.510 に答える