-
Notifications
You must be signed in to change notification settings - Fork 6.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CMake: provide option to deploy DLLs on install() like VCPKG_APPLOCAL_DEPS #1653
Comments
You know what's funny, I made an issue exactly like this but then closed it. When you CMake install something, it's ideally going to be in the users Basically, your user should've already had all dependent DLLs/ |
@LeonineKing1199 I seen your issue and even thought to mention it, but after decide that don't make any sense. Basically what you talking about is deployment on Linux. It's my primary platform and on Linux you just prepare your binaries for package manager to come and pack them for you or install them appropriately. Also there are solutions for standalone apps such as snap or flatpack that do everything on their own and not require changes in CMakeLists. Still when you need to deploy your application for Mac and Windows this is not the case. Mac expect all dependencies to be bundled inside DMG and Windows users expect installer and both can be created with CPack. This is why on these platforms PS: Yeah to be fair it's not that different on Linux except for the dependencies management. CPack even have deb and rpm generators, but I never seen anyone actually using them and there no reason since each distribution have own way to delivery the software and packages not designed to be standalone anyway. |
I'm awful with CMake, but here's a workaround I came up with. This my situation:
I just copied the add_executable macro from vcpkg.cmake. To get the environment right you can use a custom target. To run after installation you use install(CODE ...).
Edit:
|
Any updates on this? I'd really love to see this feature. |
For Windows, my workaround is to have a template CopyDeps.bat which leverages the existing
Which is used in this macro to generate a specialized CopyDeps.bat for any given target:
And then invoke the macro after the target The only requirement then is that you detect and specify the:
Hope this helps anyone having a similar problem. |
I was really confused to see that this functionality is not included with vcpkg and I think this makes using vcpkg to create Windows installers more difficult than it should be. I would really appreciate if this functionality came with vcpkg. |
…rride. Inspired by the work on microsoft#1653
Thanks for the inspiration on all of this. I think I have found a way to solve this by overloading the install command when VCPKG_APPINSTALL_DEPS is set to on (new feature flag) Happy to hear your thoughts on this as I might have missed some edge cases. |
Thanks! But I can't get it work.
|
If I replace |
It also not works with CPack. To make it work you should replace the following line in
with this:
|
Good catch. I've been testing it only with a custom install function as only then would this be transparent. So I have this inside my own function(install)
_install(${ARGV})
if(COMMAND x_vcpkg_install_local_dependencies)
if(${ARGV0} STREQUAL "TARGETS")
# Will contain the list of targets
set(PARSED_TARGETS "")
# Destination - [RUNTIME] DESTINATION argument overrides this
set(DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
# Parse arguments given to the install function to find targets and (runtime) destination
set(MODIFIER "") # Modifier for the command in the argument
set(LAST_COMMAND "") # Last command we found to process
foreach(ARG ${ARGN})
if(${ARG} MATCHES "ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE")
set(MODIFIER ${ARG})
continue()
endif()
if("${ARG}" MATCHES "TARGETS|DESTINATION|PERMISSIONS|CONFIGURATIONS|COMPONENT|NAMELINK_COMPONENT|OPTIONAL|EXCLUDE_FROM_ALL|NAMELINK_ONLY|NAMELINK_SKIP")
set(LAST_COMMAND ${ARG})
continue()
endif()
if("${LAST_COMMAND}" STREQUAL "TARGETS")
list(APPEND PARSED_TARGETS "${ARG}")
endif()
if("${LAST_COMMAND}" STREQUAL "DESTINATION" AND ("${MODIFIER}" STREQUAL "" OR "${MODIFIER}" STREQUAL "RUNTIME"))
set(DESTINATION "${CMAKE_INSTALL_PREFIX}/${ARG}")
endif()
endforeach()
x_vcpkg_install_local_dependencies(TARGETS ${PARSED_TARGETS} DESTINATION ${DESTINATION})
endif()
endif()
endfunction() Unfortunately this part of the patch wasn't accepted by the VCPKG team.
Awesome. Glad you could test that as I have no experience with that part of cmake myself. I'll make a new pull request with these fixes. |
Last time was the problem with CPack, but now it works correctly. Maybe they accept a new version with an option to override install command as you did? |
After the new PR #14129 the custom install command should change to: function(install)
_install(${ARGV})
if(COMMAND x_vcpkg_install_local_dependencies)
if(${ARGV0} STREQUAL "TARGETS")
# Will contain the list of targets
set(PARSED_TARGETS "")
# Destination - [RUNTIME] DESTINATION argument overrides this
set(DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
# Parse arguments given to the install function to find targets and (runtime) destination
set(MODIFIER "") # Modifier for the command in the argument
set(LAST_COMMAND "") # Last command we found to process
foreach(ARG ${ARGN})
if(${ARG} MATCHES "ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE")
set(MODIFIER ${ARG})
continue()
endif()
if("${ARG}" MATCHES "TARGETS|DESTINATION|PERMISSIONS|CONFIGURATIONS|COMPONENT|NAMELINK_COMPONENT|OPTIONAL|EXCLUDE_FROM_ALL|NAMELINK_ONLY|NAMELINK_SKIP")
set(LAST_COMMAND ${ARG})
continue()
endif()
if("${LAST_COMMAND}" STREQUAL "TARGETS")
list(APPEND PARSED_TARGETS "${ARG}")
endif()
if("${LAST_COMMAND}" STREQUAL "DESTINATION" AND ("${MODIFIER}" STREQUAL "" OR "${MODIFIER}" STREQUAL "RUNTIME"))
set(DESTINATION "${ARG}")
endif()
endforeach()
x_vcpkg_install_local_dependencies(TARGETS ${PARSED_TARGETS} DESTINATION ${DESTINATION})
endif()
endif()
endfunction() Changing: set(DESTINATION "${CMAKE_INSTALL_PREFIX}/${ARG}") to: set(DESTINATION "${ARG}") |
Thanks! CPack just not works correctly if |
I also noticed that Qt translations (.qm files) are not copied. But I think that this is a vcpkg issue. |
@sandercox, could you open the PR with |
Here you go. Initially I was a bit biased on your request as I was also providing some extra changes on my install command that do not make sense to be part of vcpkg, but I found a way to only optionally perform this override, meaning I can still copy this code as a base for my private projects and add whatever I need. So now you can use it with: set(VCPKG_APPLOCAL_DEPS_INSTALL ON)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file") Enabling the option before including the toolchain, like you can also do for overlay ports and triplets. Quite happy with this result - hoping this will also be accepted by the maintainers. |
Close this issue via #14243 merged. |
For anyone reading this: the first line needs to be Can confirm this works - git-for-windows/git#2971 🎉 Thanks @sandercox! |
X_VCPKG_APPLOCAL_DEPS_INSTALL depends on CMake policy CMP0087: #15874
|
Not sure if anything has changed since @Be-ing 's post but I now see:
I wonder if the policy number changed since then. I eventually made the warning go away as follows: set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
set(X_VCPKG_APPLOCAL_DEPS_INSTALL ON) |
@mcraveiro Can you please make a PR to fix that? Thanks. |
While Vcpkg copy all dependency DLLs include one for Qt properly it's there is no option to do that for install. Such option would be very useful for most of projects using CMake that create their installers using CPack+NSIS.
Of course I can simply copy DLLs and Qt plugins from output directory to install directory, but this would be very ugly hack that will likely to break at any moment. Another alternative is using BundleUtilities, but it's not handle Qt plugins and winqtdeploy is pretty broken in Vcpkg.
The text was updated successfully, but these errors were encountered: