microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
22.81k stars 6.3k forks source link

Add support for VCPKG_BUILD_TYPE = "debug" #38224

Open bansan85 opened 5 months ago

bansan85 commented 5 months ago

Is your feature request related to a problem? Please describe.

When VCPKG_BUILD_TYPE is unset, both release and debug is build.

When VCPKG_BUILD_TYPE is set to release, only release is build.

In my computer, I use vcpkg only to develop. I don't care about release. I would like to add support for VCPKG_BUILD_TYPE = debug. But in lots of portfile.cmake there is only if(NOT VCPKG_BUILD_TYPE) to know if debug build is supported.

Proposed solution

I suggest to replace all if(NOT VCPKG_BUILD_TYPE) by if (NOT VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")

There is some package that support it (libfreenect2, libmagic, librttopo, ...)

I also suggest to replace NOT DEFINED VCPKG_BUILD_TYPE to NOT VCPKG_BUILD_TYPE to be consistent.

Describe alternatives you've considered

Always build debug and release but some package takes age and I lose my time.

Additional context

No response

SchaichAlonso commented 5 months ago

Whether individual packages support it, in most cases, doesn't matter, and most people won't even notice. The VCPKG toolchain supports the VCPKG_BUILD_TYPE value of debug, so what you most likely want to do is to copy-paste the triplets/community/x64-windows-release.cmake to triplets/community/x64-windows-debug.cmake, then, in the copy, replace the release in this line by debug and, in your project, specify the VCPKG_TARGET_TRIPLET variable to x64-windows-debug in the cacheVariables section of your configure preset. There are also linux and osx release triplets in the community in path in case you're not using windows, and you can use vcpkg-configuration.json to specify an additional triplet path in your project / repository that persists your triplet(s), so you don't need to fork vcpkg or manually copy the file into the triplets/comunity path after checking out a vcpkg repository.

I claimed it doesn't matter whether individual ports support it or not earlier, because there are bright shining examples of ports that will either always pick the release, or always pick the debug variant. Sqlite3 for example always picks debug... which, however, implies that at runtime, the debug variants of the system libraries have to be present. They are always present on a development box because the Visual Studio installer deployed them there, however, systems w/o VS installed will not have the libraries, and the installer for the sqlite3 client either needs to bundle the debug libraries, which is "difficult" due to licensing as well as bothersome in terms of vulnerability management, or needs to manually deploy the release variant of the sqlite3.dll despite the debug variant having been used by cmake when it linked the release build.

You "should" write an installer that deploys your vcpkg provisioned dependencies anyways, and you "should" also check it deploys the right ones. A debug triplet is basically useless in the ci-cd chain, and useless to develop the ci-cd chain, too, because release builds are what gets released, hence we don't have a debug triplet upstream (like we don't have an address sanitizing triplet), but you can create your own triplet if you target an environment where debug builds are (allowed to be) deployed, or you don't deploy onto a different target environment anyways (i.e. archiving the build directory is good enough to deploy).

dg0yt commented 5 months ago

@SchaichAlonso No. VCPKG_BUILD_TYPE release is the only supported single-config mode.

The state is that VCPKG_BUILD_TYPE debug (as a global settings) is considered so broken, that port maintainers don't need to take care of it. At least most ports would be left without include dir.

The recommendation is to adjust the compiler flags for release as desired. But the details are left as an exercise to the user.

bansan85 commented 5 months ago

OK, thanks, I understand. My suggestion is good but definitely not enough. Never mind...

cenit commented 5 months ago

see #16110 if you want more info

SchaichAlonso commented 5 months ago

The recommendation is to adjust the compiler flags for release as desired. But the details are left as an exercise to the user.

Appending CFLAGS, however, will not cause a release build preset to emit a debug build. Not to mention that some ports just ignore CFLAGS anyways, or modify them silently.

For example, Release builds export the NDEBUG macro, which disables assertions. Even if debug symbol emission is then appended and optimization reduced/disabled by appending corresponding CFLAGS, NDEBUG will stay, and assertions turn into NOPs. Some ports also need port specific debug mode indicators to be passed down to enable debug specific code via macros, and the ports set those up using their build systems when those are invoked in debug mode, rather then by detecting whether CFLAGS indicate debugging intents.

SchaichAlonso commented 5 months ago

Always build debug and release but some package takes age and I lose my time.

binary caches should be able to handle that. They're enabled by default, so you're probably using them already, however, there are chances binary caching with the default filesystem backend doesn't really provide any advantage, e.g. if vcpkg is invoked inside of short-lived containers and the binary cache isn't persisted to be shared with other containers.

Another option would be the caching itself working, but the abi-hashes frequently breaking. The most likely reason why they break is because the build environment is updated to one with differently identifying versions or vcpkg being updated. If compile time is an issue, then the time it takes to update the build environment probably also is (cmake cannot reliably reuse a build directory from another cmake version, for example, so you need to cleanse the build dir after a cmake update), and for vcpkg, it's probably better to just go from one tagged release to the next one rather then trying to live on master... and if it's broken, find a master commit that works and use that until the next tag is pushed.

To diagnose why vcpkg wants to rebuild a package, you can use a backup of the vcpkg_installed/vcpkg/info path inside the build directory (or installed/vcpkg/info inside the vcpkg path in non-manifest mode) and compare it's content with the abi-hashes in vcpkg's command line output that is emitted when the --debug option is passed to vcpkg install (in manifest mode, it can be passed there by setting the VCPKG_INSTALL_OPTIONS cmake variable to "--debug"): The first port with an entry deviating will cause everything that depended on the corresponding port it to also deviate and be recompiled.

dg0yt commented 5 months ago

Appending CFLAGS, however, will not cause a release build preset to emit a debug build. Not to mention that some ports just ignore CFLAGS anyways, or modify them silently.

For example, Release builds export the NDEBUG macro, which disables assertions. Even if debug symbol emission is then appended and optimization reduced/disabled by appending corresponding CFLAGS, NDEBUG will stay, and assertions turn into NOPs. Some ports also need port specific debug mode indicators to be passed down to enable debug specific code via macros, and the ports set those up using their build systems when those are invoked in debug mode, rather then by detecting whether CFLAGS indicate debugging intents.

I wouldn't say I'm happy with the recommendation. But we shouldn't mix VCPKG_BUILD_TYPE and CMAKE_BUILD_TYPE.

WRT performance: On my Ubuntu box, I prepend /usr/lib/ccache to the PATH before doing port work which involves frequent rebuilds.

derekcyruschow-catapult commented 1 month ago

The state is that VCPKG_BUILD_TYPE debug (as a global settings) is considered so broken, that port maintainers don't need to take care of it. At least most ports would be left without include dir.

what's the view on PRs trying to fix individual ports to support it? Still not recommended? My appetite for it is to speed up debug builds (and as a bonus disk usage) for onboarding developers in my team but if we are discouraged from fixing them I will invest more time into cloud-based binary caching.

MonicaLiu0311 commented 1 month ago

Ping @BillyONeal for response.

bansan85 commented 1 month ago

This issue is about adding support for VCPKG_BUILD_TYPE = "debug"

The solution I suggested will only fix a tiny part of the problem. This is why I didn't create a PR.

Of course you can send PR to add this feature. But you will have to patch a lot of port. For example, header are remove for debug build because there always are installed in release mode. So in debug build only, you will never have header.

BillyONeal commented 1 month ago

Ping @BillyONeal for response.

I believe it is unlikely that we will ever do this; there is too much in our ecosystem that assumes release is always present.