After some experiments, I found that it is FINE with the abovementioned situations. Therefore, I have some conclusions about this topic.
Conclusions
-
$<TARGET_RUNTIME_DLLS:tgt>
will be evaluated by IMPORTED_LOCATION_<CONFIG>
, as well.
-
If there exist IMPORTED_LOCATION
and IMPORTED_LOCATION_<CONFIG>
simultaneously, then $<TARGET_RUNTIME_DLLS:tgt>
will be evaluated by IMPORTED_LOCATION_<CONFIG>
corresponding to the current configuration, priorly.
Experiments with Qt
The following is the example CMakeLists.txt
code using Qt6
.
Click to expand the example CMakeLists.txt code
cmake_minimum_required(VERSION 3.21)
get_filename_component(folder_name "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
project(${folder_name} LANGUAGES C CXX)
include(CMakePrintHelpers)
list(APPEND CMAKE_MODULE_PATH "C:/Qt/6.3.1/msvc2019_64")
list(APPEND CMAKE_PREFIX_PATH "C:/Qt/6.3.1/msvc2019_64")
find_package(Qt6 CONFIG REQUIRED
COMPONENTS Core Widgets)
cmake_print_properties(
TARGETS Qt6::Core
Qt6::Widgets
PROPERTIES IMPORTED_LOCATION
IMPORTED_LOCATION_DEBUG
IMPORTED_LOCATION_RELEASE)
add_executable(main "main.cpp")
target_link_libraries(main
PRIVATE
Qt6::Core
Qt6::Widgets)
add_custom_command(
TARGET main POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_RUNTIME_DLLS:main>"
"$<TARGET_FILE_DIR:main>"
COMMAND_EXPAND_LISTS)
add_custom_target(echo-TARGET_RUNTIME_DLLS
COMMAND ${CMAKE_COMMAND} -E echo
"$<TARGET_RUNTIME_DLLS:main>")
After configuring the projects, as we can see, BOTH IMPORTED_LOCATION
and IMPORTED_LOCATION_<CONFIG>
of IMPORTED targets are populated.
Click to expand output results of configuring projects
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=d:/cmake-find_package-qt/install -Sd:/cmake-find_package-qt -Bd:/cmake-find_package-qt/build/win32-MSVC-x64-Debug -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] -- Could NOT find WrapVulkanHeaders (missing: Vulkan_INCLUDE_DIR)
[cmake] --
[cmake] Properties for TARGET Qt6::Core:
[cmake] Qt6::Core.IMPORTED_LOCATION = "C:/Qt/6.3.1/msvc2019_64/bin/Qt6Core.dll"
[cmake] Qt6::Core.IMPORTED_LOCATION_DEBUG = "C:/Qt/6.3.1/msvc2019_64/bin/Qt6Cored.dll"
[cmake] Qt6::Core.IMPORTED_LOCATION_RELEASE = "C:/Qt/6.3.1/msvc2019_64/bin/Qt6Core.dll"
[cmake] Properties for TARGET Qt6::Widgets:
[cmake] Qt6::Widgets.IMPORTED_LOCATION = "C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgets.dll"
[cmake] Qt6::Widgets.IMPORTED_LOCATION_DEBUG = "C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgetsd.dll"
[cmake] Qt6::Widgets.IMPORTED_LOCATION_RELEASE = "C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgets.dll"
[cmake]
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: D:/cmake-find_package-qt/build/win32-MSVC-x64-Debug
After building the custom target echo-TARGET_RUNTIME_DLLS
with Debug and Release configurations respectively, I found that $<TARGET_RUNTIME_DLLS:tgt>
would be populated with its corresponding IMPORTED_LOCATION_<CONFIG>
.
Click to expand output results with Debug config
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build d:/cmake-find_package-qt/build/win32-MSVC-x64-Debug --config Debug --target echo-TARGET_RUNTIME_DLLS --
[build] [1/1 100% :: 0.038] cmd.exe /C "cd /D D:\cmake-find_package-qt\build\win32-MSVC-x64-Debug && "C:\Program Files\CMake\bin\cmake.exe" -E echo C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgetsd.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Guid.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Cored.dll"
[build] C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgetsd.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Guid.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Cored.dll
Click to expand output results with Release config
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build d:/cmake-find_package-qt/build/win32-MSVC-x64-Release --config Release --target echo-TARGET_RUNTIME_DLLS --
[build] [1/1 100% :: 0.041] cmd.exe /C "cd /D D:\cmake-find_package-qt\build\win32-MSVC-x64-Release && "C:\Program Files\CMake\bin\cmake.exe" -E echo C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgets.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Gui.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Core.dll"
[build] C:/Qt/6.3.1/msvc2019_64/bin/Qt6Widgets.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Gui.dll;C:/Qt/6.3.1/msvc2019_64/bin/Qt6Core.dll
Experiments with OpenCV
The following is the example CMakeLists.txt
code using OpenCV
.
Click to expand the example CMakeLists.txt code
cmake_minimum_required(VERSION 3.21)
get_filename_component(folder_name "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
project(${folder_name} LANGUAGES C CXX)
include(CMakePrintHelpers)
list(APPEND CMAKE_MODULE_PATH "C:/ccxxpkgs/install")
list(APPEND CMAKE_PREFIX_PATH "C:/ccxxpkgs/install")
find_package(OpenCV CONFIG REQUIRED)
cmake_print_properties(
TARGETS opencv_core
opencv_imgproc
PROPERTIES IMPORTED_LOCATION
IMPORTED_LOCATION_DEBUG
IMPORTED_LOCATION_RELEASE)
add_executable(main "main.cpp")
target_link_libraries(main
PRIVATE
opencv_core
opencv_imgproc)
add_custom_command(
TARGET main POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<TARGET_RUNTIME_DLLS:main>"
"$<TARGET_FILE_DIR:main>"
COMMAND_EXPAND_LISTS)
add_custom_target(echo-TARGET_RUNTIME_DLLS
COMMAND ${CMAKE_COMMAND} -E echo
"$<TARGET_RUNTIME_DLLS:main>")
After configuring the projects, as we can see, ONLY IMPORTED_LOCATION_<CONFIG>
of IMPORTED targets are populated. While IMPORTED_LOCATION
is empty.
Click to expand output results of configuring projects
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_INSTALL_PREFIX:STRING=d:/cmake-find_package-opencv/install -Sd:/cmake-find_package-opencv -Bd:/cmake-find_package-opencv/build/win32-MSVC-x64-Debug -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] -- OpenCV ARCH: x64
[cmake] -- OpenCV RUNTIME: vc16
[cmake] -- OpenCV STATIC: OFF
[cmake] -- Found OpenCV 4.5.5 in C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/lib
[cmake] -- You might need to add C:\ccxxpkgs\install\opencv-4.5.5\x64\vc16\bin to your PATH to be able to run your applications.
[cmake] --
[cmake] Properties for TARGET opencv_core:
[cmake] opencv_core.IMPORTED_LOCATION = <NOTFOUND>
[cmake] opencv_core.IMPORTED_LOCATION_DEBUG = "C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_core455d.dll"
[cmake] opencv_core.IMPORTED_LOCATION_RELEASE = "C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_core455.dll"
[cmake] Properties for TARGET opencv_imgproc:
[cmake] opencv_imgproc.IMPORTED_LOCATION = <NOTFOUND>
[cmake] opencv_imgproc.IMPORTED_LOCATION_DEBUG = "C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_imgproc455d.dll"
[cmake] opencv_imgproc.IMPORTED_LOCATION_RELEASE = "C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_imgproc455.dll"
[cmake]
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: D:/cmake-find_package-opencv/build/win32-MSVC-x64-Debug
After building the custom target echo-TARGET_RUNTIME_DLLS
with Debug and Release configurations respectively, I found that $<TARGET_RUNTIME_DLLS:tgt>
would be populated with its corresponding IMPORTED_LOCATION_<CONFIG>
.
Click to expand output results with Debug config
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build d:/cmake-find_package-opencv/build/win32-MSVC-x64-Debug --config Debug --target echo-TARGET_RUNTIME_DLLS --
[build] [1/1 100% :: 0.039] cmd.exe /C "cd /D D:\cmake-find_package-opencv\build\win32-MSVC-x64-Debug && "C:\Program Files\CMake\bin\cmake.exe" -E echo C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_imgproc455d.dll;C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_core455d.dll"
[build] C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_imgproc455d.dll;C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_core455d.dll
Click to expand output results with Release config
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build d:/cmake-find_package-opencv/build/win32-MSVC-x64-Release --config Release --target echo-TARGET_RUNTIME_DLLS --
[build] [1/1 100% :: 0.042] cmd.exe /C "cd /D D:\cmake-find_package-opencv\build\win32-MSVC-x64-Release && "C:\Program Files\CMake\bin\cmake.exe" -E echo C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_imgproc455.dll;C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_core455.dll"
[build] C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_imgproc455.dll;C:/ccxxpkgs/install/opencv-4.5.5/x64/vc16/bin/opencv_core455.dll
Suggestions
Because $<TARGET_RUNTIME_DLLS:tgt>
doesn’t mention IMPORTED_LOCATION_<CONFIG>
in its documentation, I suggest that CMake add some NOTES to describe this mechanism.