Open Todiq opened 3 months ago
Hi @Todiq
I think you would be interesting in injecting CMake toolchains from profiles, this is your use case isn't it?
Please check this example: https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/inject_cmake_variables.html, it can be used to define any CMake variable from profiles.
@memsharded,
From what I read, one can only load a .cmake file containing the variables. Isn’t there any way to directly write them in the profile, avoiding to manage another file?
From what I read, one can only load a .cmake file containing the variables. Isn’t there any way to directly write them in the profile, avoiding to manage another file?
No, I am afraid there isn't. The reason is that often it is not enough to define a variable. Many times, it is necessary, specially for toolchain files to make those variables CACHE
variables. But not always. Inventing a syntax for supporting the different scenarios would be very artificial. Not to say more advanced cases where conditional logic based on CMake inputs is necessary, that is impossible from the profile. So passing the cmake
file covers all cases.
Plus something equivalent is also done for other build systems like Meson, also passing files.
There are utilities in the profiles to be able to reference the current profile_dir
folder, etc. to make easier and relocatable using the extra .cmake
files, and at the end of the day, the files are managed with conan config install
automatically, so not a big issue to have a .cmake
more.
@memsharded,
I just followed the steps from the documentation link you provided, but I am now getting an error that I had not encountered until now:
CMake Error at /opt/conan/p/cmakee300763ec076c/p/share/cmake-3.29/Modules/CMakeTestCXXCompiler.cmake:60 (message):
The C++ compiler
"/usr/bin/clang-cl-16"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: '/workspace/core/build/windows-msvc-193-x86_64/Release/CMakeFiles/CMakeScratch/TryCompile-Sq5pQn'
Run Build Command(s): /opt/conan/p/ninja6fed3c8400c5b/p/bin/ninja -v cmTC_757c9
[1/2] /usr/bin/clang-cl-16 -fcolor-diagnostics -fuse-ld=lld -target x86_64-pc-windows-msvc /winsdkdir /opt/win-sdk/sdk /vctoolsdir /opt/win-sdk/crt -flto -march=x86-64-v3 -std:c++17 -o CMakeFiles/cmTC_757c9.dir/testCXXCompiler.cxx.o -c /workspace/core/build/windows-msvc-193-x86_64/Release/CMakeFiles/CMakeScratch/TryCompile-Sq5pQn/testCXXCompiler.cxx
FAILED: CMakeFiles/cmTC_757c9.dir/testCXXCompiler.cxx.o
/usr/bin/clang-cl-16 -fcolor-diagnostics -fuse-ld=lld -target x86_64-pc-windows-msvc /winsdkdir /opt/win-sdk/sdk /vctoolsdir /opt/win-sdk/crt -flto -march=x86-64-v3 -std:c++17 -o CMakeFiles/cmTC_757c9.dir/testCXXCompiler.cxx.o -c /workspace/core/build/windows-msvc-193-x86_64/Release/CMakeFiles/CMakeScratch/TryCompile-Sq5pQn/testCXXCompiler.cxx
clang: error: no input files
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:3 (project)
-- Configuring incomplete, errors occurred!
ERROR: conanfile.py (castcore/1.1): Error in build() method, line 98
cmake.configure()
ConanException: Error 1 while executing
myvars.cmake is simply the following:
set(CMAKE_MT "llvm-mt-16")
and my host profile:
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=14
compiler.runtime=dynamic
compiler.version=193
os=Windows
cast*/*:build_type=Release
cast*/*:compiler.cppstd=17
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
tools.build:cxxflags=["-fcolor-diagnostics"]
tools.build:cxxflags+=["-fuse-ld=lld"]
tools.build:cxxflags+=["-target x86_64-pc-windows-msvc"]
tools.build:cxxflags+=["/winsdkdir /opt/win-sdk/sdk /vctoolsdir /opt/win-sdk/crt"]
tools.build:cxxflags+=["-flto -march=x86-64-v3"]
tools.build:compiler_executables={"c": "clang-cl-16", "cpp": "clang-cl-16", "rc": "llvm-rc-16"}
tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/myvars.cmake
[buildenv]
LDFLAGS=/winsdkdir:/opt/win-sdk/sdk /vctoolsdir:/opt/win-sdk/crt
Everything worked when defining CMAKE_MT
in the recipe
This sounds weird. Can you please try a couple of things:
message()
to your myvars.cmake
to double check it is being calledmessage()
in your CMakeLists.txt
printing the value of CMAKE_MT
and compare in both cases (from profile and when defined in the recipe)The message in myvars.cmake
confirms it is called.
Adding a message in the CMakeLists.txt does not do anything, since the error comes before the actual build part. It happens during the compiler checks.
Adding a message in the CMakeLists.txt does not do anything, since the error comes before the actual build part. It happens during the compiler checks.
Maybe add the message()
before the project()
call? I am not sure why there would be any difference in having it defined in the recipe and in the profile, both are defining in the same toolchain approach.
Adding a message()
before the project()
call indeed works. As well as writing set(CMAKE_MT "llvm-mt-16")
before project()
as well. It only breaks when loading myvars.cmake
file through the profile
It might be something specific about this variable? I cannot find it in the CMake docs: https://cmake.org/cmake/help/latest/search.html?q=CMAKE_MT shows no result? Maybe there is some other logic around that variable that it is not standard?
It would be good to have a reproducible case that we can try on our side.
Do you actually need MT? We often get away with /MANIFEST:NO. llvm-mt is nowhere near MT.exe anyway
Hi @Todiq
any update here? The variable CMAKE_MT doesn't seem a CMake variable, I can't find anything regarding it
Thanks for the ping @memsharded,
Indeed, CMAKE_MT
is not mentionned anywhere, even though it exists and is usable for cross-build scenarios.
However, I could clearly face the issue that the variable was not loaded through myvars.cmake
. I will try to create a minimum reproducible case. On my own project, passing /MANIFEST:NO
was enough.
Thanks for the feedback. Cleaning the staled
tag, and looking forward your minimum reproducible case, thanks!
When adding a user_toolchain from config the CMakeToolchain generator no longer sets CMake variables required for cross compiling.
See: https://docs.conan.io/2/reference/tools/cmake/cmaketoolchain.html#cross-building
Related code: https://github.com/conan-io/conan/blob/develop2/conan/tools/cmake/toolchain/blocks.py#L1033
This might be related to your issue.
Edit: Support for defining extra CMake variables though config was recently introduced in version 2.4.0: https://github.com/conan-io/conan/pull/16242
What is your suggestion?
Hello. Thank you for taking the time to read this.
https://github.com/conan-io/conan/issues/3099 could be very handy for my use case, although workarounds exist. Please note that I prefer using
conan build
rather thanconan install
+cmake ...
, making it easier to remember and apply on all operating systems.In order to cross-compile from Linux to Windows using clang https://github.com/conan-io/conan/issues/15655, I need to properly set the environment for cmake.
A prerequisite is to set CMAKE_MT to llvm-mt.
This must be done before the
build()
section of the recipe. In fact, cmake first tries to check whether the compiler and linker work before compiling the project. Thus, one cannot simply writeset(CMAKE_MT llvm-mt)
in the rootCMakeLists.txt
and expect it to work (unless I missed something). It has to be done in the recipe, in thegenerate(self)
method.I am using python:3.9.18-slim as a base docker image (debian-based). I installed all my toolchain with these packets:
clang-16 clang-tools-16 llvm-16 lld-16
. It leads to a way slimer image than installing it through LLVM's shell script.Unfortunately, it implies that all the tools are called
name_of_the_tool-16
(I am aware this could be fixed throughupdate-alternatives
).Until now, I wrote this line
tc.variables["CMAKE_MT"] = "llvm-mt-16"
in mygenerate(self)
method, which worked fine to inject the var to cmake before the start of the build.However, since I am currently transitioning compilers on Windows as well, this line breaks when trying to use msvc (clang works):
Log
```powershell Using lockfile: 'D:\core\conan.lock' ======== Input profiles ======== Profile host: [settings] arch=x86_64 build_type=Release compiler=msvc compiler.cppstd=14 compiler.runtime=dynamic compiler.runtime_type=Release compiler.version=193 os=Windows cast*/*:build_type=Release cast*/*:compiler.cppstd=17 [conf] cast*/*:tools.build:skip_test=False cast*/*:tools.cmake.cmaketoolchain:generator=Ninja Multi-Config cast*/*:tools.env.virtualenv:powershell=True cast*/*:user.cast:run_tests=False Profile build: [settings] arch=x86_64 build_type=Release compiler=msvc compiler.cppstd=14 compiler.runtime=dynamic compiler.runtime_type=Release compiler.version=193 os=Windows cast*/*:build_type=Release cast*/*:compiler.cppstd=17 [conf] cast*/*:tools.build:skip_test=False cast*/*:tools.cmake.cmaketoolchain:generator=Ninja Multi-Config cast*/*:tools.env.virtualenv:powershell=True cast*/*:user.cast:run_tests=False ======== Computing dependency graph ======== Graph root conanfile.py (castcore/1.1): D:\core\conanfile.py Requirements boost/1.81.0#753df9d4f149a5551335f47abe21de0b - Cache icu/72.1#d24b2d30acae3dcb788e139112bcd7c6 - Cache libiconv/1.17#73fefc1b696e069df90fd1d18aa63edd - Cache libxml2/2.11.6#41c14895baba105865cb22ecaf948115 - Cache libxslt/1.1.34#2bdc1f5fe5db1df40f8465e485a19ee4 - Cache pugixml/1.13#f615c1fcec55122b2e177d17061276e7 - Cache xerces-c/3.2.4#c52d1d1bb36d1377471ec1e551a6598a - Cache Test requirements gtest/1.13.0#8a0bc5b3e159ed45de97260c2bff65b5 - Cache Build requirements b2/4.10.1#a41eecb267963ddf518e3c177eae60e1 - Cache cmake/3.29.0#a055de871f63a7904aa3dcb9f3c61242 - Cache msys2/cci.latest#5a31efa2bde593541fd5ac3bcc50c01c - Cache ninja/1.11.1#77587f8c8318662ac8e5a7867eb4be21 - Cache ======== Computing necessary packages ======== Requirements boost/1.81.0#753df9d4f149a5551335f47abe21de0b:e03785e977988d57a84487e4306a26c9018cabf0#f65d418cddf6cc771a803fde82e12dd9 - Cache icu/72.1#d24b2d30acae3dcb788e139112bcd7c6:9f8165f8d74e26bf104abb2a5005a80d1101b198#3cb5da99fe9d01c55d1c5dbf13f35112 - Cache libiconv/1.17#73fefc1b696e069df90fd1d18aa63edd:7bfde258ff4f62f75668d0896dbddedaa7480a0f#9ef92719f5c05dca2f0dbb46f50d3f8d - Cache libxml2/2.11.6#41c14895baba105865cb22ecaf948115:a6cdd368afb04c4d9e5918696d661f8f5249a029#d4a7bc8cb16ca7e7411db8804a765032 - Cache libxslt/1.1.34#2bdc1f5fe5db1df40f8465e485a19ee4:4e7168dde525f5dbaf65a8b8f6b3280b6a7e87d7#a632a2a87954026a2d962070cbad7aa6 - Cache pugixml/1.13#f615c1fcec55122b2e177d17061276e7:da39a3ee5e6b4b0d3255bfef95601890afd80709#ae530054ed7ac99330514c13a5bfde3a - Cache xerces-c/3.2.4#c52d1d1bb36d1377471ec1e551a6598a:41c4e6767851fe7db56310649912b6259451a38f#0831576b3c913f5e3d1294aa2f05ee41 - Cache Test requirements gtest/1.13.0#8a0bc5b3e159ed45de97260c2bff65b5:9940e217936a0f218f90473d62bf1d4db55efaa7#f44bf478a18701d76b310497997d7b3b - Cache Build requirements cmake/3.29.0#a055de871f63a7904aa3dcb9f3c61242:522dcea5982a3f8a5b624c16477e47195da2f84f#27973db6c7b443ab1b970571b73d0818 - Cache ninja/1.11.1#77587f8c8318662ac8e5a7867eb4be21:723257509aee8a72faf021920c2874abc738e029#74ebd8f35f54015dcbf2b18a6adbd023 - Cache Skipped binaries b2/4.10.1, msys2/cci.latest ======== Installing packages ======== ======== Installing packages ======== cmake/3.29.0: Already installed! (1 of 10) cmake/3.29.0: Appending PATH environment variable: D:\conan\p\cmake8c0a252b8ebf8\p\bin gtest/1.13.0: Already installed! (2 of 10) ninja/1.11.1: Already installed! (3 of 10) pugixml/1.13: Already installed! (4 of 10) xerces-c/3.2.4: Already installed! (5 of 10) boost/1.81.0: Already installed! (6 of 10) boost/1.81.0: Disabled magic autolinking (smart and magic decisions) icu/72.1: Already installed! (7 of 10) libiconv/1.17: Already installed! (8 of 10) libxml2/2.11.6: Already installed! (9 of 10) libxml2/2.11.6: Appending PATH environment variable: D:\conan\p\libxm07501da66e843\p\bin libxslt/1.1.34: Already installed! (10 of 10) WARN: deprecated: Usage of deprecated Conan 1.X features that will be removed in Conan 2.X: WARN: deprecated: 'env_info' used in: libxslt/1.1.34, libxml2/2.11.6, libiconv/1.17, boost/1.81.0, icu/72.1, cmake/3.29.0 WARN: deprecated: 'cpp_info.names' used in: gtest/1.13.0, libxml2/2.11.6, libiconv/1.17, boost/1.81.0, icu/72.1, libxslt/1.1.34 WARN: deprecated: 'cpp_info.filenames' used in: libxml2/2.11.6, boost/1.81.0 WARN: deprecated: 'user_info' used in: boost/1.81.0 WARN: deprecated: 'cpp_info.build_modules' used in: libxml2/2.11.6 ======== Finalizing install (deploy, generators) ======== conanfile.py (castcore/1.1): Calling generate() conanfile.py (castcore/1.1): Generators folder: D:\core\build\windows-msvc-193-x86_64\generators conanfile.py (castcore/1.1): CMakeToolchain generated: conan_toolchain.cmake conanfile.py (castcore/1.1): Preset 'conan-windows-msvc-193-x86_64' added to CMakePresets.json. Invoke it manually using 'cmake --preset conan-windows-msvc-193-x86_64' if using CMake>=3.23 conanfile.py (castcore/1.1): If your CMake version is not compatible with CMakePresets (<3.23) call cmake like: 'cmakeWhile I could have a
if
condition in myconanfile.py
, I would find it way simpler to inject the variable in the host profile (targeting Windows) on my linux build machine, having no traces in the recipe. What do you think?Have you read the CONTRIBUTING guide?