conan
conan copied to clipboard
[question] How to handle "exports" with workspaces super-project approach?
I am trying the monolithic builds with Conan 2.15.
One of the editable libraries uses its generate() method to export some files (the DearImgui implementation files, following the updated blog post), with code like that:
def generate(self):
imgui_package = os.path.join(self.dependencies["imgui"].package_folder, "res", "bindings")
destination = os.path.join(self.build_folder, "conan_imports", "imgui_bindings")
copy(self, "imgui_impl_glfw.h", src=imgui_package, dst=destination)
copy(self, "imgui_impl_glfw.cpp", src=imgui_package, dst=destination)
Sadly, it seems conan workspace install did not copy the files, as I cannot find them in the build directory.
Is this command supposed to call generate() of each editable? How should I handle this situation?
Hi @Adnn
Thanks for your question.
Yes, that would be an issue. In the conan workspace install, all the editable package in the super-build are assumed to be managed by the super-build. In fact, the conan workspace install barely has a notion of the editable packages, they are all collapsed into a single large node in the dependency graph that corresponds to the "super-build", and then a common generate() step is run for them.
If this is only those 4 lines, have you tried copying them to the generate() method of the class MyWs(ConanFile): conanfile in the conanws.py? The idea is that in a super-build, the destination directory will be different, it will not be:
destination = os.path.join(self.build_folder, "conan_imports", "imgui_bindings")
because that is the build_folder of that specific package subproject folder, but the whole super-build build folder would be different.
Hi @Adnn
If this is only those 4 lines, have you tried copying them to the generate() method of the class MyWs(ConanFile): conanfile in the conanws.py? The idea is that in a super-build, the destination directory will be different, it will not be:
Did you try this approach?
Any further comment or question? Thanks for your feedbback.
Hi @memsharded , sorry for the delay before I could try your approach.
It did work (I could not confirm the build though, because of subsequent issues).
In the actual workspace, 6 files needs to be copied, and DearImgui is used by two repositories. So in the end it amounts to 13 lines in generate():
def generate(self):
imgui_package = os.path.join(self.dependencies["imgui"].package_folder, "res", "bindings")
destination = os.path.join(self.build_folder, "_deps", "foo-build", "conan_imports", "imgui_bindings")
copy(self, "imgui_impl_glfw.h", src=imgui_package, dst=destination)
copy(self, "imgui_impl_glfw.cpp", src=imgui_package, dst=destination)
copy(self, "imgui_impl_opengl3.h", src=imgui_package, dst=destination)
copy(self, "imgui_impl_opengl3.cpp", src=imgui_package, dst=destination)
copy(self, "imgui_impl_opengl3_loader.h", src=imgui_package, dst=destination)
destination = os.path.join(self.build_folder, "_deps", "bar-build", "conan_imports", "imgui_bindings")
copy(self, "imgui_impl_glfw.h", src=imgui_package, dst=destination)
copy(self, "imgui_impl_glfw.cpp", src=imgui_package, dst=destination)
copy(self, "imgui_impl_opengl3.h", src=imgui_package, dst=destination)
copy(self, "imgui_impl_opengl3.cpp", src=imgui_package, dst=destination)
copy(self, "imgui_impl_opengl3_loader.h", src=imgui_package, dst=destination)
In our limited situation it is not too bad, but it appears that with medium or large scale projects it might become a maintenance burden.
The idea is that in a super-build, the destination directory will be different, it will not be:
As you forewarned, I had to change the destination. In the example, I hardcoded the extra _deps/packagename-build folder. Is there a cleaner way to query this subpath from the logic?
In our limited situation it is not too bad, but it appears that with medium or large scale projects it might become a maintenance burden.
It is possible that we make the conanfile-workspace.py a external independent file, if that happens, that conanfile will be able to use python-requires, so any logic that manages this can be reused and avoid the extra maintenance.
As you forewarned, I had to change the destination. In the example, I hardcoded the extra _deps/packagename-build folder. Is there a cleaner way to query this subpath from the logic?
I am trying to think of something, but I don't think so. The thing is that such a path is mostly an implementation detail of the CMake and FetchContent mechanism, not any path that Conan can define or know.
The other possible approach would be to revert it, let your CMake code do the copy or the usage of the source files, directly from its origin, so no need to copy files around in Conan, but your CMake code should only be aware of the "origin" source folder, your os.path.join(self.dependencies["imgui"].package_folder, "res", "bindings"), and then it will decide where to do the copy.