conan-io / cmake-conan

CMake wrapper for conan C and C++ package manager
MIT License
814 stars 247 forks source link

[feature] Add CONAN_DOWNLOAD and CONAN_ISOLATE_HOME optional features #651

Open valgur opened 2 weeks ago

valgur commented 2 weeks ago

One quite frequent complaint about Conan, especially from Windows users, is that it requires a Python installation with Conan installed, which adds friction to the build process. This PR proposes a simple fix to that: optionally download and use one of the self-contained Conan packages from https://github.com/conan-io/conan/releases/latest, if Conan is not found on the system. The config options for this feature are always, if-missing and never.

In addition to that, it also adds an option to override CONAN_HOME to a folder inside the build dir. This might be useful in other scenarios as well, but if Conan is not available on the system or it's an outdated version, then it's generally preferable if the build process does not add unexpected files to ~/.conan2. Its config options are always, if-downloaded and never.

Whether the default config options for these features should be if-missing and if-downloaded, respectively, or never and never is debatable, but I preferred and set them to the prior one.

The added tests should cover both of these features comprehensively, I believe.

I also moved all config options of conan_provider.cmake to the top of the file for better visibility.

valgur commented 2 weeks ago

One more use case that the CONAN_ISOLATE_HOME feature unlocks (at least as far as I'm concerned) is the ability to precisely control the remotes used during conan install:

set(CUSTOM_REMOTE_PATH "${CMAKE_BINARY_DIR}/cci-valgur" )
include(FetchContent)
FetchContent_Declare(
    cci_valgur
    URL "https://github.com/valgur/conan-center-index/archive/11c1fadf6f659bb6ba208e79352be24bf1077385.zip"
    SOURCE_DIR "${CUSTOM_REMOTE_PATH}"
    DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(cci_valgur)
file(WRITE "${CMAKE_BINARY_DIR}/conan_home/remotes.json" "
{
 \"remotes\": [
  {
   \"name\": \"cci-valgur\",
   \"url\": \"${CUSTOM_REMOTE_PATH}\",
   \"verify_ssl\": true,
   \"remote_type\": \"local-recipes-index\"
  }
 ]
}
")

Hopefully there are better ways to accomplish the same now or in the future, though, but I have not found any.

valgur commented 3 days ago

Hmm... that's a fair point. Would this be considered for inclusion if I refactored it into a separate .cmake module?