When you have a project using conan from CMake I think it would be beneficial to have a macro that can run conan from CMake so that developers just using the app just need to execute CMake and not run conan install first. The conanbuildinfo.cmake could also make sure that conan is re-run when conanfile.py is changed.
This would be a huge improvement for developers that are only interested in running the app and doesn't care about developing the dependencies.
Yeah. Good idea. I've done that in my cmake script. It requires some work with settings parameters.
I had developed something that did the job, but didn't finish the translation of all conan settings from cmake. You can find my work here: https://github.com/memsharded/cmake-conan
I think it could be a good starting point. It does the cmake re-run to ensure that the cmake files are reloaded properly.
Just one thing: I didn't continue working on it, because I felt it was not very useful, convenient in a few cases, but with problems in other cases, so I was often falling back to the command line and conan commands. Actually, the best flow I managed to achieve was with python scripts that orchestrate conan - cmake, much better than managing from cmake.
@memsharded I have the different approach: instead of creating a new target I run conan on every cmake launch:
macro(sbis_setup_conan)
find_program(conan conan)
if(NOT EXISTS ${conan})
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
message(FATAL_ERROR "Conan is required.\
Please run this command to install and setup conan:
py -3 ${CMAKE_SOURCE_DIR}\tools\cmake_builder\tools\install_conan.py")
else()
message(FATAL_ERROR "Conan is required.\
Please run this command to install and setup conan:
python3 ${CMAKE_SOURCE_DIR}/tools/cmake_builder/tools/install_conan.py")
endif()
return()
endif()
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL Darwin)
set(os Macos)
else()
set(os ${CMAKE_HOST_SYSTEM_NAME})
endif()
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
set(compiler gcc)
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang)
set(compiler apple-clang)
else()
message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif()
string(SUBSTRING ${CMAKE_CXX_COMPILER_VERSION} 0 3 compiler_version)
set(conanfile ${CMAKE_SOURCE_DIR}/conanfile.txt)
set(conanfile_cmake ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
execute_process(COMMAND ${conan} install --update --remote ${conan_remote}
-s os=${os}
-s compiler=${compiler} -s compiler.version=${compiler_version}
${CMAKE_SOURCE_DIR} RESULT_VARIABLE return_code)
if(NOT ${return_code} EQUAL 0)
message(FATAL_ERROR "conan install command failed.")
endif()
include(${conanfile_cmake})
conan_check_compiler()
link_directories(${CONAN_LIB_DIRS})
endmacro()
This thread duplicates #5
Note: please handle #448 failure to detect compiler from cmake, as reported by @traceon
Is it technically possible to generate configs before building the package? Does this make sense at all?
I am asking because of multi-config CMake generators. For example, if I generate a Visual Studio solution and during cmake-generation call conan, build the package, include conanbuildinfo.cmake, configure my source accordingly - and then, open solution in Visual Studio, and switch from Debug to Release, the configured and found conan packages may be binary incompatible with Release output.
Is there some tested approach for achieving correct behavior is such case? Like building all possible variants on cmake-generation, etc. (what would be theusage of conanbuildinfo.cmake then?)
@traceon That is a different issue, a bit complex, please read: https://github.com/conan-io/conan/issues/330. It is a long thread, but worth reading the whole story to get an idea.
A quick question, how often do you change from Debug to Release during development? I used to find myself switching branches (in the command line) more often than the build-type.
Progress:
test.py which can be automatically executed.Please check: https://github.com/conan-io/cmake-conan
Testing required. Please try it, and contribute, especially with the detection of settings from cmake variables, which is incomplete, but should be easy to contribute.
Thanks, @memsharded, sorry for not using search.
A quick question, how often do you change from Debug to Release during development?
I hear you. Not often. So I am thinking now about restricting the configuration types in cmake to one per generated build system project. But still... this will be considered as a downside of using conan + CMake automatic combo by some critics, although just on paper.
@traceon no worries! I much prefer people interacting in wrong places, that people refraining to interact due to maintainers being too strict.
Yes, we perfectly know. But when developing such a general purpose dev-tool, you can't be 100% perfect for everyone, and trade-offs have to be made. The inconvenience of falling to command-line to switch dependencies Debug<->Release is indeed an inconvenience, but the advantages are larger: smaller packages, deploy or release in production minimal artifacts, much cleaner and simpler interfaces...
Also, very important, avoiding the explosion of the conan codebase, that would lead to slowness in development. Consider that such switch from Debug and Release in the IDE is only possible in multi-configuration environments, mainly Visual Studio. Most other environments are single-configuration, in which such an approach doesn't make a lot of sense. Having the same unified approach in conan for all systems makes maintenance of the conan project easier, and allow us to develop features and bug fixes faster.
Thanks for your feedback!
@memsharded your implementation is great. But it generate a conanfile.txt and run conan every time I mention conan_cmake_run.
Is there any way to:
The inconvenience of falling to command-line to switch dependencies Debug<->Release is indeed an inconvenience
CMake has generator expression. It evaluates at build time, not generation time.
For Visual Studio conan can install debug and release configurations together.
Yes, I had implemented a custom target, with a pre build hook, in order to run only when strictly necessary, but it was a bit complicated. Due to cmake nature, it required to re-run cmake (I did it automatically), because it was necessary to load conanbuildinfo.cmake which was not generated at process time. I liked more your approach, which yes, it generates a conanfile.txt, but is generated in the CMAKE_BINARY_DIR, like many more other files, which is not a big issue. And it is not very slow.
The reasoning behind generating the conanfile.txt is that some people might want to have the conanfile.txt, so the file generation is just a cmake function, which could be skipped. But launching conan install reading the conanfile.txt is much easier. So putting everything together this seemed to me the solution with the less cmake code, which for me it is important, cmake code tends to quickly explode and become a nightmare.
So IMHO it is better to keep it simple by now, but I am open to suggestions, and especially contributions from CMake gurus.
Regarding the multi-configuration, I know about generator expressions, but please keep in mind that we would like to maintain compatibility down to cmake 2.8.12, still used by a few people. Conan might be able to install debug & release configuration, at install time, just mixing the information from both in one single cmake file (automatically) is the challenge. It is something that we want to have a look again, but I still think that it is not the biggest priority, as it can be solved by 3 keystrokes in the command line.
Labeling this feature as fixed and closing it, conversation about it can follow in its own repo: https://github.com/conan-io/cmake-conan
Most helpful comment
@memsharded I have the different approach: instead of creating a new target I run conan on every cmake launch: