conan-io / cmake-conan

CMake wrapper for conan C and C++ package manager
MIT License
828 stars 251 forks source link

conan2 from cmake with visual studio #491

Open fekir opened 1 year ago

fekir commented 1 year ago

When executing cmake -B build -S . -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=conan_provider.cmake -DCMAKE_BUILD_TYPE=Release as described in https://github.com/conan-io/cmake-conan/blob/develop2/README.md I get following error:

D:\conan\cmake-conan>D:/proj/software/CMake/cmake-3.26.0-rc1-windows-x86_64/bin/cmake.exe -B build -S . -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=conan_provider.cmake -DCMAKE_BUIL
D_TYPE=Release
-- Selecting Windows SDK version 10.0.20348.0 to target Windows 10.0.19045.
-- CMake-conan: first find_package() found. Installing dependencies with Conan
-- Conan-cmake: Checking if a default profile exists
C:\Users\...\.conan2\profiles\default
-- Conan-cmake: cmake_system_name=Windows
-- Conan-cmake: CMake compiler=MSVC
-- Conan-cmake: CMake cmpiler version=19.34.31942.0
-- Conan-cmake: [settings] compiler=msvc
-- Conan-cmake: [settings] compiler.version=193
-- Conan-cmake: Creating profile D:/conan/cmake-conan/build/conan_host_profile
-- Conan-cmake: Profile:
include(default)
[settings]
os=Windows
compiler=msvc
compiler.version=193
compiler.cppstd=11
[conf]
tools.cmake.cmaketoolchain:generator=Visual Studio 17 2022

-- CMake-conan: Installing both Debug and Release
-- CMake-conan: conan install D:/conan/cmake-conan -of=D:/conan/cmake-conan/build/conan -pr;D:/conan/cmake-conan/build/conan_host_profile;-s;build_type=Release;--build=miss
ing;-g;CMakeDeps
ERROR: Invalid setting '11' is not a valid 'settings.compiler.cppstd' value.
Possible values are ['14', '17', '20', '23']
Read "http://docs.conan.io/2/knowledge/faq.html#error-invalid-setting"
CMake Error at conan_support.cmake:147 (message):
  Conan install failed='1'
Call Stack (most recent call first):
  conan_support.cmake:171 (conan_install)
  CMakeLists.txt:7 (find_package)

my ~/.conan2/profiles/default looks like

[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=14
compiler.runtime=dynamic
compiler.version=193
os=Windows

and was created with conan profile detect

AFAIK the microsoft compiler does not have a flag for c++11

memsharded commented 1 year ago

Hi @fekir

Thanks for reporting. Indeed, there is some wrong there, the c++11 flag doesn't exist for msvc, lets fix it.

memsharded commented 1 year ago

Uhm, can't reproduce it here, and checking the code I see:

function(detect_cxx_standard CXX_STANDARD)
    set(${CXX_STANDARD} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
    if (CMAKE_CXX_EXTENSIONS)
        set(${CXX_STANDARD} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
    endif()
endfunction()

It seems the only way to end with compiler.cppstd in the detected profile is somehow CMAKE_CXX_STANDARD is defined in the CMakeLists.txt. Could you please double check this?

fekir commented 1 year ago

Doh

set(CMAKE_CXX_STANDARD 11)

When not using conan, this line is not problematic in cmake.

Note that the source code is unchanged, so you should be able to reproduce it

memsharded commented 1 year ago

Ok, that would make sense.

Conan need to know what compiler.cppstd value should be used to install dependencies, and the way to obtain it when running from CMake is from the CMAKE_CXX_STANDARD. To be honest, not sure what Conan should be doing here, it feels like trying to automagically come up with a different cppstd value would be not only difficult but probably very fragile and problematic for users.

jcar87 commented 1 year ago

From what I remember, Visual C++ does not really have compiler flags for C++11 (Starts with C++14, docs here), so that's what Conan mirrors and that's why there is an error if C++11 is passed.

I suspect the behaviour is different within CMake itself, and when it encounters set(CMAKE_CXX_STANDARD 11) - CMake either does not pass any flag and relies on the compiler built-in defaults, or passes /std:c++14, I need to verify this. -

In practice I think this would mean that any value prior to C++14 may actually be equivalent to C++14 ... if that is the case, we could probably have logic in the profile detection to cover this case.

mzukovec commented 1 year ago

Talking about auto-detecting compiler.cppstd flag, I think it would be great to keep an option that would suppress the default detected C++ standard.

Most of the conan packages (at least conan-center ones) are built using the default compiler cppstd or defined by the library, which means that there's no compiler.cppstd setting. After using the conan extensively and porting all the recipes to 2.0, the usual use-case in CMakeLists.txt was that the set(CMAKE_CXX_STANDARD YY) was set prior to running conan package installation, which resulted in auto-detected compiler.cppstd, which needed to be manually discarded from the settings, since no package binaries matched the specified settings.

prince-chrismc commented 1 year ago

Most of the conan packages (at least conan-center ones) are built using the default compiler cppstd or defined by the library, which means that there's no compiler.cppstd setting.

This is actively changing for the 2.0 pipeline and we are trying to roll this feature out :)