conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
7.95k stars 951 forks source link

[question] Determine if package is built locally or in a cache #16521

Open bkarasm opened 1 week ago

bkarasm commented 1 week ago

What is your question?

Hello,

Is there a reliable way to tell whether a package is being built within a cache (e.g. using conan create) or "locally" (e.g. using conan build)?

I ask because the structure of my project depends on the name of the folder into which a Git repository is cloned (I know it's a terrible design, but I cannot change it 🤷 ).

E.g. project structure of mylib git repo:

Have you read the CONTRIBUTING guide?

memsharded commented 1 week ago

Hi @bkarasm

Trying to understand the issue. You mean that it is 100% mandatory that the project above is always inside a mylib folder in the file system, and that somehow the build system should add the parent directory of the mylib folder as include-dir?

And if that is the case, how would you build that in the Conan cache? because in the conan cache, for sure the mylib folder will not exist, so it is basically impossible to make it conan create in the Conan cache?

bkarasm commented 1 week ago

Correct, if I clone the git repo for my development work, I'll clone into mylib but when I create a package mylib directory is not created in the conan cache. I could instruct git to clone into mylib subfolder inside conan cache. However, if I do that I would have to tell CMake that in conan build context CMakeLists.txt is in root folder and in conan create context it is in mylib subfolder.

I could probably check if the absolute path has $CONAN_HOME substring but I was hoping there is a different way.

memsharded commented 1 week ago

I could instruct git to clone into mylib subfolder inside conan cache.

I am not sure how this would be done. If the recipe contains a source() that downloads itself? Kind of a scm approach in https://docs.conan.io/2/examples/tools/scm/git/capture_scm/git_capture_scm.html?

I think it would be good to start with a recipe that can build this in the cache with conan create and try to understand from there how it could be built locally too.

bkarasm commented 1 week ago

I have created a small repo with an example that shows the problem: https://github.com/bkarasm/mylib

I can't figure out how to setup the paths in conanfile so that both conan create and conan build work.

memsharded commented 4 days ago

Thanks for the repo.

I have been playing with it, and I think the problem is that the layout is ill-formed, and it won't have any elegant solution.

I have managed to make it work with:

diff --git a/conanfile.py b/conanfile.py
index 24efb46..e0045b0 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -1,6 +1,6 @@
 from conan import ConanFile
 from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
-from conan.tools.files import update_conandata
+from conan.tools.files import update_conandata, save
 from conan.tools.scm import Git
 import os

@@ -33,12 +33,13 @@ class MyLibConan(ConanFile):
         )

     def layout(self):
-        return cmake_layout(self, src_folder="mylib")
+        cmake_layout(self)

     def source(self):
-        git = Git(self)
+        git = Git(self, folder="mylib")
         git.clone(url="git@github.com:bkarasm/mylib.git", target=".")
         git.checkout(commit=self.conan_data["sources"]["commit"])
+        save(self, "CMakeLists.txt", "add_subdirectory(mylib)")

The trick is to generate an extra CMakeLists.txt in the cache. There could be other similar tricks with the knowledge that source() will not run locally, only in the cache. Still, it is a hack, and the recommendation would be to fix the #include "mylib/..." locally without a local "mylib" folder (excluding the parent clone folder)