docs icon indicating copy to clipboard operation
docs copied to clipboard

[question] Vcpkg conflicting with Conan?

Open Simran-B opened this issue 1 year ago • 10 comments

What is your question?

While trying to build Qt 5 with Conan, I ran into an error with one of its dependencies, but only when using build_type=Debug. There were linker errors with bzip2. To isolate the problem, I cloned the conan-center-index repo and compiled bzip2 on its own with Release and Debug as the build types. The test package failed with linker errors for Debug:

conan-center-index\recipes\bzip2\all> conan test .\test_package\ bzip2/1.0.8 -s build_type=Debug
...
Profile host:
[settings]
arch=x86_64
build_type=Debug
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Debug
compiler.version=192
os=Windows

Profile build:
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=17
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=192
os=Windows
...
bzip2/1.0.8 (test package): Running CMake.build()
bzip2/1.0.8 (test package): RUN: cmake --build "C:\Daten\Olive\conan-center-index\recipes\bzip2\all\test_package\build\msvc-192-x86_64-17-debug" --config Debug
Microsoft (R)-Build-Engine, Version 16.11.2+f32259642 für .NET Framework
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.

  Checking Build System
  Building Custom Rule C:/Daten/Olive/conan-center-index/recipes/bzip2/all/test_package/CMakeLists.txt
  test_package.c
test_package.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_BZ2_bzBuffToBuffCompress" in Funktion "main". [C:\Daten\Olive\conan-center-index\recipes\bzip2\all\test_package\build\msv
c-192-x86_64-17-debug\test_package.vcxproj]
test_package.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp_BZ2_bzlibVersion" in Funktion "main". [C:\Daten\Olive\conan-center-index\recipes\bzip2\all\test_package\build\msvc-192-x8
6_64-17-debug\test_package.vcxproj]
C:\Daten\Olive\conan-center-index\recipes\bzip2\all\test_package\build\msvc-192-x86_64-17-debug\Debug\test_package.exe : fatal error LNK1120: 2 nicht aufgelöste Externe [C:\Daten\Olive\conan-center-index\reci
pes\bzip2\all\test_package\build\msvc-192-x86_64-17-debug\test_package.vcxproj]

It can't resolve symbols __imp_BZ2_bzBuffToBuffCompress and __imp_BZ2_bzlibVersion, so none of the functions included from bzlib.h.

I opened test_package.c in VSCode for which I have Microsoft's C/C++ extension installed, right-clicked #include "bzlib.h", and selected Go to Definition. To my surprise, this didn't open C:\MyFiles\conan-center-index\recipes\bzip2\all\src\bzlib.h but C:\MyFiles\vcpkg\installed\x64-windows\include\bzlib.h (from 2020).

After appending an underscore to all the bzip-related files in that vcpkg folder, I reran the conan test command and now it succeeded (actually, renaming bzlib.h seems to be sufficient). I suppose the vcpkg build of bzip2, which happens to be v1.0.8 as well, is somehow incompatible (maybe it is only a Release build). But more importantly, there seems to be a conflict between vcpkg and Conan, and vcpkg takes precedence for some reason.

I'm posting this as a question because this might have been answered elsewhere (but I couldn't find a relevant issue) or there might be a way to circumvent this problem already. If not, please turn this into a feature request.

  • Removing everything vcpkg would obviously solve the issue, but vcpkg and Conan may need to co-exist on a system
  • VirtualBuildEnv comes to mind, but I checked my environment variables and there is nothing for vcpkg. I think Visual Studio (Code) picks it up because of %LOCALAPPDATA%\vcpkg\vcpkg.path.txt, which contains C:/MyFiles/vcpkg. This has been originally created by me running vcpkg integrate install
  • There is an option in Visual Studio to disable Vcpkg for projects in the solution, which translates to an entry in build\src\<project-name>.vcxproj:
    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    ...
      <PropertyGroup Label="Vcpkg">
        <VcpkgEnabled>false</VcpkgEnabled>
      </PropertyGroup>
    
    If Vcpkg is turned off, VS no longer takes the bzip2 header from the vcpkg folder as desired. I guess Conan could make use of this option to avoid clashes? (I think setting it for the top-most project should be enough as the default setting appears to be to inherit the setting of this option from the parent project).

Have you read the CONTRIBUTING guide?

  • [X] I've read the CONTRIBUTING guide

Simran-B avatar Sep 04 '23 09:09 Simran-B

Hi @Simran-B

Thanks for your question.

But more importantly, there seems to be a conflict between vcpkg and Conan, and vcpkg takes precedence for some reason.

Yes, vcpkg can sometimes modify the environment, add things to the VS paths or to the CMake installation. For some reason C:\MyFiles\vcpkg\installed is in the build path, which is not great. As it is installed somewhere in the system, it will typically have more precedence than Conan. Conan tries to have more priority via CMakeToolchain defined paths, but it is not always possible.

If Vcpkg is turned off, VS no longer takes the bzip2 header from the vcpkg folder as desired. I guess Conan could make use of this option to avoid clashes? (I think setting it for the top-most project should be enough as the default setting appears to be to inherit the setting of this option from the parent project).

I am afraid there is very little that Conan can do here. It seems vcpkg and VS decided together to push them in the paths and give it higher priority. As long as they do that, what Conan could do? The VS projects often don't even exist for Conan, they are created with a cmake ... command after conan install has been executed. For sure Conan cannot mess with the system to disable vcpkg or anything like that.

memsharded avatar Sep 04 '23 15:09 memsharded

Thanks, @memsharded! It's not nice that Vcpkg cuts in. They should really re-consider the default setting, but there doesn't seem to be any progress in that direction based on this discussion: https://github.com/microsoft/vcpkg/discussions/19149

It seems like the only way to stop Vcpkg from interfering with a specific project is to disable it for every CMake target:

set_target_properties(targetName PROPERTIES VS_GLOBAL_VcpkgEnabled false)

I found a CMake feature CMAKE_VS_GLOBALS that might be the key to automatically setting it for all CMake targets:

set(CMAKE_VS_GLOBALS
  "VcpkgEnabled=false"
)

It even seems to be intended for cases like Conan:

This variable is meant to be set by a toolchain file

Simran-B avatar Sep 06 '23 09:09 Simran-B

Thanks for the feedback! So it means that our CMakeToolchain could always set this value, globally? I am not 100% sure that this would also be the nicest way, and if it could break some users that depend also on vcpkg for some dependencies, we would be doing something similar to what we are complaining they did 😅 ? I can also discuss this with the team.

memsharded avatar Sep 07 '23 16:09 memsharded

You're right, this may not be desired by everyone just like the Vcpkg default. For this reason but also for backward compatibility, this should be an opt-in feature (assuming there is enough interest to justify the addition to Conan). Maybe a config option a la tools.cmake.cmaketoolchain:vcpkg_enabled=false that you could add to a profile?

Or is there already a way that would let you set CMAKE_VS_GLOBALS via a toolchain file? Isn't there a Conan feature to inject custom things?

Would be great to hear the thoughts of the team and about any other approaches!

Simran-B avatar Sep 07 '23 20:09 Simran-B

Yes, there is an approach in which users can inject any arbitrary cmake file into the toolchains, as described here: https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/inject_cmake_variables.html So users via profile can definitely inhibit vcpkg with that mechanism.

memsharded avatar Sep 07 '23 21:09 memsharded

For posterity, this setup works for me:

profiles\disable_vcpkg.cmake

set(CMAKE_VS_GLOBALS
  "VcpkgEnabled=false"
)

profiles\windows

[conf]
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/disable_vcpkg.cmake

Simran-B avatar Sep 11 '23 09:09 Simran-B

Excellent, thanks for the feedback! I think that this approach is then valid for the use case, allows disabling it while playing nice with others, and doesn't require to modify any recipe at all. Maybe we can close this ticket now?

memsharded avatar Sep 11 '23 12:09 memsharded

Yeah, or should a remark be added to the docs specifically about this Conan + Vcpkg conflict? https://docs.conan.io/2/knowledge/faq.html#troubleshooting seems to lend itself for that

Simran-B avatar Sep 11 '23 17:09 Simran-B

Yeah, lets move it to the docs repo, seems a good potential entry there.

memsharded avatar Sep 11 '23 20:09 memsharded

Hi, @memsharded I was suffering from this.

I think we should make some change in conan to deny the use of vcpkg defaultly, becasue it's dangerous and difficult to detect.

TL:DR, For now, if anyone ever use vcpkg, to eliminate the influence of vcpkg, one should:

  1. remove all vcpkg packages / apply the workaround above
  2. clean all binary package in conan cache

Long time a ago I install poco via vcpkg, which brought zlib as dependents. Recently i start to use conan, then zlib was brought as well. My recipes for exe/dlls depends zlib indirectly, When running my program, an error about missing zlib1.dll was shown. Then I check my recipe again and again, everything in conan shows that zlib is shared=False,the package_folder only exist lib/zlib.lib and not any bin/zlib1.dll. I searched zlib1.dll in my whole filesystem and confirmed it was in the vcpkg's folder. After removing zlib from vcpkg, rebuilding my program (conan install & cmake --preset & cmake --build) failed because of missing zlib. The error is not gone only after i removed zlib from conan cache and rebuilt it.

X1aomu avatar Nov 23 '23 03:11 X1aomu