Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • CMake CMake
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,926
    • Issues 3,926
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 18
    • Merge requests 18
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • External wiki
    • External wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • CMake
  • CMakeCMake
  • Issues
  • #23543
Closed
Open
Created May 23, 2022 by Alex Reinking@alexreinkingContributor

`$<TARGET_RUNTIME_DLLS:...>` is inconvenient to use with cmake -E copy

The example usage of $<TARGET_RUNTIME_DLLS:...> in the documentation is bugged:

find_package(foo CONFIG REQUIRED) # package generated by install(EXPORT)

add_executable(exe main.c)
target_link_libraries(exe PRIVATE foo::foo foo::bar)
add_custom_command(TARGET exe POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:exe> $<TARGET_FILE_DIR:exe>
  COMMAND_EXPAND_LISTS
  )

When in a cross-platform setting, the COMMAND here will expand to the following on non-DLL systems:

/path/to/cmake -E copy /path/to/exe-dir

which then prints a nondescript error and usage information. The problem here is that there is a destination directory, but no source files, or perhaps the opposite.


Thus, one resolution would be to wrap the add_custom_command in an if (WIN32) conditional. But is WIN32 set for all DLL systems? I think so, but such configure-time platform logic has a tendency to be unexpectedly brittle. More robust would be to extend cmake -E copy with POSIX cp's -t flag. It specifies the destination directory first and then lets any number (including zero) of additional arguments be source files. Here's the small excerpt from the man page:

      -t, --target-directory=DIRECTORY
             copy all SOURCE arguments into DIRECTORY

If cmake -E copy had this flag, one could instead write the above custom command as:

add_custom_command(
  TARGET exe POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy -t $<TARGET_FILE_DIR:exe> $<TARGET_RUNTIME_DLLS:exe>
  COMMAND_EXPAND_LISTS
)

This approach is then correct on all systems since it decays to a NO-OP on non-DLL systems (rather than an error)

CC @ben.boeckel

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking