[question] Can anyone help me migrate my project conanfile?
- [x] I've read the CONTRIBUTING guide.
Hi,
Can anyone help me migrate my project conanfile?
My try is here: https://github.com/nativium/nativium/pull/23/files
Today, im generating conanbuildinfo.cmake, because it is imported into the cmake:
https://github.com/nativium/nativium/blob/main/cmake/functions.cmake#L90-L97
Im searching a lot about how to migrate the current method to the new v2 method of using cmake.
@uilianries @ericLemanissier @SpaceIm can you help me?
Thanks for any help.
The error is:
conanfile.py (nativium/None): Calling build()
ERROR: conanfile.py (nativium/None): Error in build() method, line 66
cmake = CMake(self)
ConanException: Usage of toolchain is only supported with 'cmake_find_package' or 'cmake_find_package_multi' generators
COMMAND: conan build /Users/paulo/Developer/workspaces/cpp/nativium/conan/recipe/conanfile.py --source-folder /Users/paulo/Developer/workspaces/cpp/nativium --build-folder /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target --install-folder /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/conan
WORKING DIR: /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target
[ERROR] Command execution has failed
It fails inside conan:
def _validate_recipe(conanfile):
forbidden_generators = ["cmake", "cmake_multi"]
if any(it in conanfile.generators for it in forbidden_generators):
raise ConanException("Usage of toolchain is only supported with 'cmake_find_package'"
" or 'cmake_find_package_multi' generators")
Hi @paulocoutinhox
The first important steps:
- Drop the
generators = "cmake" - Use instead
CMakeDepsandCMakeToolchain: https://docs.conan.io/en/latest/migrating_to_2.0/recipes.html#the-generate-method - The
CMakehelper that you are using should integrate them automatically
You probably also want to drop the layout specific generator in the recipe, as long as it is defined correctly in tools.cmake.cmaketoolchain:generator the layout will work.
@memsharded How/where to define this tools.cmake.cmaketoolchain:generator?
You can define it either in your profile, but most typical on your command line as -c tools.cmake...=value, because it is the developer that wants to select a different generator than the one typically used in CI, for example. Unless you want the generator kind of hardcoded in the recipe, it depends on the use case.
@memsharded i already tried use CMakeDeps/CMakeToolchain, because i see on other recipes from CCI, but im still doing something wrong because when i use it, i get error on build:
conanfile.py (nativium/None): Calling build()
ERROR: conanfile.py (nativium/None): Error in build() method, line 59
cmake = CMake(self)
FileNotFoundError: [Errno 2] No such file or directory: '/Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target/build/generators/CMakePresets.json'
COMMAND: conan build /Users/paulo/Developer/workspaces/cpp/nativium/conan/recipe/conanfile.py --source-folder /Users/paulo/Developer/workspaces/cpp/nativium --build-folder /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target --install-folder /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/conan
WORKING DIR: /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target
[ERROR] Command execution has failed
And it don't generate the file conanbuildinfo.cmake.
I need remove the build method from my conanfile and change to generate method with code:
def generate(self):
# This generates "conan_toolchain.cmake" in self.generators_folder
tc = CMakeToolchain(self)
tc.variables["MYVAR"] = "1"
tc.preprocessor_definitions["MYDEFINE"] = "2"
tc.generate()
???
And it don't generate the file conanbuildinfo.cmake.
yes, they are not expected to generated that file. They provide "transparent" integration, your CMakeLists.txt will not have anything Conan specific. You need to add the standard find_package(...) to your CMakeLists, and the COnan generators will manage to get the dependencies.
Also the cmake.definitions in the build() still seems wrong, it has to be moved to the CMakeToolchain in generate().
Something seems wrong with the layout. Maybe trying out the conan new hello/0.1 -m=cmake_lib template can help understanding the basics of the new generators.
@memsharded I do that changes, but the error is the same:
[INFO] Nativium: Extending conan configuration with module app-core
conanfile.py (nativium/None): Calling build()
ERROR: conanfile.py (nativium/None): Error in build() method, line 103
cmake = CMake(self)
FileNotFoundError: [Errno 2] No such file or directory: '/Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target/build/generators/CMakePresets.json'
COMMAND: conan build /Users/paulo/Developer/workspaces/cpp/nativium/conan/recipe/conanfile.py --source-folder /Users/paulo/Developer/workspaces/cpp/nativium --build-folder /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target --install-folder /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/conan
WORKING DIR: /Users/paulo/Developer/workspaces/cpp/nativium/build/macos/debug/x86_64/target
I generate a new project with conan new [...] and my conanfile is equal that generated file:
https://github.com/nativium/nativium/pull/23/files
I also add the generator to profiles.
And after call install it only generate these files:
Log:
[INFO] Building for: arm64/release...
Configuration (profile_host):
[settings]
arch=armv8
arch_build=armv8
build_type=Release
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=13.1
os=Macos
os.sdk=macosx
os.version=11.0
os_build=Macos
[options]
nativium_arch=arm64
nativium_build_type=release
nativium_product_name=Nativium
nativium_project_name=nativium
nativium_target=macos
nativium_version=1.0.0
nativium_version_code=1
[build_requires]
[env]
[conf]
tools.cmake.cmaketoolchain:generator=Xcode
Configuration (profile_build):
[settings]
arch=armv8
arch_build=armv8
build_type=Release
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=13.1
os=Macos
os_build=Macos
[options]
[build_requires]
[env]
[INFO] Nativium: Extending conan configuration with module app-core
[INFO] Nativium: Extending conan requirements with module app-core
conanfile.py (nativium/None): Installing package
Requirements
Packages
Installing (downloading, building) binaries...
conanfile.py (nativium/None): Generator 'CMakeDeps' calling 'generate()'
conanfile.py (nativium/None): Generator txt created conanbuildinfo.txt
conanfile.py (nativium/None): Generator 'CMakeToolchain' calling 'generate()'
conanfile.py (nativium/None): Calling generate()
conanfile.py (nativium/None): Aggregating env generators
conanfile.py (nativium/None): Generated conaninfo.txt
conanfile.py (nativium/None): Generated graphinfo
[OK]
I am checking the PR and the code and the CI and I am missing something. The folder is D:\\a\\nativium\\nativium\\build\\tests\\debug\\x86_64\\target\\build\\generators\\CMakePresets.json, so it doesn't seem a conan create in the cache. Can you please share the steps to reproduce locally on Windows?
Hi @memsharded,
Steps:
git clone https://github.com/nativium/nativium.git
cd nativium
python3 nativium.py conan setup
python3 nativium.py target windows setup
python3 nativium.py target windows build
Hi @memsharded,
Did you found something?
Thanks.
Hi @paulocoutinhox
Not yet, first I'd need to create a virtualenv to install your requirements like from pygemstones.io import file as f, that I don't have installed.
I haven't done it yet, because I might be missing something. The code that I am checking out still contains the legacy cmake generator, no generate(), etc, so seem recipe is still not the modern one. Should I checkout a different branch?
Hi @memsharded, sorry, my mistake about git clone. You need checkout branch "recipe-conan-v2":
git clone https://github.com/nativium/nativium.git -b recipe-conan-v2
I am having a look, but struggling a bit to understand the layers on top of Conan.
I'd say that the usage of the different folders like
"--source-folder",
proj_path,
"--build-folder",
In the build command is not expected anymore. The goal of the layout() method is to get rid of those things.
Is it possible that we could have a reproducible case with Conan commands directly? Maybe starting with a simple conan create would be a good start, then we could have a look to the local flow install + build.
Ok @memsharded. I made a small project from conan new command and create a structure equal my project to make tests.
https://github.com/paulocoutinhox/conan-cmake-v2
Only left a problem with include files using Find_package. I get a sample of sqlitecpp from CCI, and it is not finding the include paths:
Error: https://github.com/paulocoutinhox/conan-cmake-v2/actions/runs/3109394367/jobs/5039569584#step:10:255
Log:
[ 50%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o
/home/runner/work/conan-cmake-v2/conan-cmake-v2/src/hello.cpp:3:10: fatal error: SQLiteCpp/SQLiteCpp.h: No such file or directory
3 | #include <SQLiteCpp/SQLiteCpp.h>
| ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
It only works when i add include dirs:
target_include_directories(${PROJECT_NAME} PUBLIC ${SQLiteCpp_INCLUDE_DIRS})
Is this correct? I need add all include paths to target?
This fixes the conan create command:
diff --git a/conan/recipe/conanfile.py b/conan/recipe/conanfile.py
index 6b8451c..1dfd944 100644
--- a/conan/recipe/conanfile.py
+++ b/conan/recipe/conanfile.py
@@ -1,7 +1,7 @@
import os
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps
-
+from conan.tools.files import copy
from conan import ConanFile
@@ -20,11 +20,13 @@ class HelloConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}
+ generators = "CMakeToolchain", "CMakeDeps"
# Sources are located in the same place as this recipe, copy them to the recipe
- exports_sources = "CMakeLists.txt", "src/*", "include/*"
-
- generators = "CMakeToolchain", "CMakeDeps"
+ def export_sources(self):
+ copy(self, "CMakeLists.txt", os.path.join(self.recipe_folder, "../.."), self.export_sources_folder)
+ copy(self, "src/*", os.path.join(self.recipe_folder, "../.."), self.export_sources_folder)
+ copy(self, "include/*", os.path.join(self.recipe_folder, "../.."), self.export_sources_folder)
The problem is that the export_sources attribute is not capable of representing correctly a layout when you have the conanfile.py in a subfolder like conan/recipe, so you need the full power of the method. In general, putting the recipe in a subfolder instead of the root of the repo makes thing more complicated, and this is why it is recommended to put the conanfile.py in the root if possible.
The local flow also works with simply:
conan install conan/recipe
conan build conan/recipe
Hi @memsharded, this is already solved. Im only with one doubt.
For all dependencies i need add its library path and include path manually? Example for sqlitecpp:
target_link_libraries(${PROJECT_NAME} PRIVATE SQLiteCpp)
target_include_directories(${PROJECT_NAME} PUBLIC ${SQLiteCpp_INCLUDE_DIRS})
Sample project with all platforms tests: https://github.com/paulocoutinhox/conan-cmake-v2
No, for dependencies, only linking with the targets is necessary, and only the direct dependencies declared, the transitive ones should be automatic. Definitely not the include dirs.
So something like:
find_package(sqlitecpp CONFIG REQUIRED)
target_link_libraries(mytarget PRIVATE sqlitecpp::sqlitecpp) # actual name of the target not tested
which is the standard modern CMake approach should work.
@memsharded strange, because without add include dirs, it don't find the headers. You can see here: https://github.com/paulocoutinhox/conan-cmake-v2/blob/main/CMakeLists.txt
And can try:
git clone https://github.com/paulocoutinhox/conan-cmake-v2.git
cd conan-cmake-v2
make desktop
But that still have the
target_link_libraries(${PROJECT_NAME} PRIVATE ${SQLite3_LIBRARIES})
You are linking with the bare libraries, not the target names. The target names should be displayed when cmake runs. You should replace it for something like:
target_link_libraries(${PROJECT_NAME} PRIVATE sqlite3::sqlite3)
@memsharded forget man, it is working, my mistake in some place, thanks.
Hi @memsharded. Everything was migrate. Thanks.
I open an issue about a bug that i get and create a simple project to check: https://github.com/conan-io/conan/issues/12195
Can you help there?