Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Using layout and -of together Conan 2 #647

Open
1 task
forry opened this issue Jun 21, 2024 · 4 comments
Open
1 task

[question] Using layout and -of together Conan 2 #647

forry opened this issue Jun 21, 2024 · 4 comments
Assignees

Comments

@forry
Copy link

forry commented Jun 21, 2024

Hi,
while using conan 2.4.1 on Windows 10 I want to make a conan 2 recipe for an application using cmake. I want to use the conan-cmake deps provider (supplied as a top-level include via our cmake preset through the GUI) and make it possible to drive the build process either from cmake or conan. The problem I'm encountering is when the layout is defined in some way but the conan dependency provider (or user) runs conan install with the -of argument.

I like to use out-of-source builds so I define my layout like this:

    def layout(self):
        cmake_layout(self, build_folder='../build')
        print(f"generator folder {self.folders.generators}")

But the user building it will start the cmake-gui with the binary dir of his choosing.
When called the conan install . it creates a folder build with subfolder generators with the files, which is great.
When called conan install . -of ../build the result is the same - build/generators.
But when called like conan install . -of ../build/conan which is what deps provider does when doing cmake configure the result is build\build\generators - one subfolder more than I would like to and no conan subfolder why?
When I comment out the layout(self) method and call conan install . -of ../build/conan the result is just build/conan.

If I would like to consistently generate the generator files by conan, let's say in a <build folder>\conan, where the <build folder> is either selected by the user through CMAKE_BINARY_DIR var or by typing conan install. in a source folder, what should I do?

Have you read the CONTRIBUTING guide?

  • I've read the CONTRIBUTING guide
@memsharded memsharded self-assigned this Jun 21, 2024
@memsharded
Copy link
Member

Hi @forry

Thanks for your question.

It seems the conan_provider.cmake of the cmake-conan integration and the regular Conan-driven are not very intended to be used simulatenously, because the conan_provider.cmake is doing some hard assumptions to guarantee a reasonable behavior in most cases (irrespective/safe of the recipe layout()), forcing a --output-folder.

There might be a couple of possible approaches to this:

  • The recommendation for the conan_provider.cmake is to copy it in the repo, to make everything easy and self-contained. So it would be relatively doable to change the --output-folder, remove it if necessary, to align with the expected layout.
  • Conan provides tools.cmake.cmake_layout:build_folder conf that can change the root cmake_layout(..., build_folder=xxx) value from the profile/cli

I am moving this ticket to the cmake-conan, because I understand that it could make sense to check there if something can be improved or investigated regarding the forced --output-folder argument.

@memsharded memsharded transferred this issue from conan-io/conan Jun 21, 2024
@forry
Copy link
Author

forry commented Jun 21, 2024

Thanks for your response.

  • The recommendation for the conan_provider.cmake is to copy it in the repo, to make everything easy and self-contained. So it would be relatively doable to change the --output-folder, and remove it if necessary, to align with the expected layout.

That is what I'm experimenting with. But trying to understand the process - does it work that it concatenates the --output-folder with the layout build_folder? Meaning fromconan install . -of ${CMAKE_BINARY_DIR}/conan and layout cmake_layout(self, build_folder='../build') it just concatenates those two into ${CMAKE_BINARY_DIR}/conan/../build/generators giving me ${CMAKE_BINARY_DIR}/build/generators? Is that how it works? I don't quite get it from the conan install doc. I thought that the -of will overwrite it.

  • Conan provides tools.cmake.cmake_layout:build_folder conf that can change the root cmake_layout(..., build_folder=xxx) value from the profile/cli

Ok, assuming the above, I have removed the -of from deps provider/conan install and added the tools.cmake.cmake_layout:build_folder=${CMAKE_BINARY_DIR} into the profile. It went alright - ${CMAKE_BINARY_DIR}/generators.
Then without the layout in conanfile it fails (and it messed up my source folder).
And if I add the -of ${CMAKE_BINARY_DIR}/conan back without the layout the result is now ${CMAKE_BINARY_DIR}/conan.

So my assumption: to make the conan_provider.cmake more general I need -of for when the recipe doesn't explicitly define layout but then if it does and it is a cmake layout I can override it with the tools.cmake.cmake_layout:build_folder and put into either command line with -c or the profile (preferably build one). But since I now found out that tools.cmake.cmake_layout:generators_folder does not exist I can't make it be a ${CMAKE_BINARY_DIR}/conan like with -of just ${CMAKE_BINARY_DIR}/generators (with the config approach).

@memsharded
Copy link
Member

That is what I'm experimenting with. But trying to understand the process - does it work that it concatenates the --output-folder with the layout build_folder? Meaning fromconan install . -of ${CMAKE_BINARY_DIR}/conan and layout cmake_layout(self, build_folder='../build') it just concatenates those two into ${CMAKE_BINARY_DIR}/conan/../build/generators giving me ${CMAKE_BINARY_DIR}/build/generators? Is that how it works? I don't quite get it from the conan install doc. I thought that the -of will overwrite it.

No, it doesn't overwrite. The -of is that "base" output folder. From that base output folder, all the layout defined in layout() is nested under that base folder.

So my assumption: to make the conan_provider.cmake more general I need -of for when the recipe doesn't explicitly define layout but then if it does and it is a cmake layout I can override it with the tools.cmake.cmake_layout:build_folder and put into either command line with -c or the profile (preferably build one). But since I now found out that tools.cmake.cmake_layout:generators_folder does not exist I can't make it be a ${CMAKE_BINARY_DIR}/conan like with -of just ${CMAKE_BINARY_DIR}/generators (with the config approach).

Yes, I think this is more or less how it was designed. Using the -of always in the provider, to absorb recipes that wouldn't have layout() and would be a mess if all the files are generated in the root. But with recipes with layout() the -of wouldn't be necessary in most cases and could be dropped.

The improvement I was thinking of when I moved the ticket to this repo is try to drop the -of when detecting (if possible) that the consumer recipe had a layout() defined, or something in that line.

@forry
Copy link
Author

forry commented Jun 21, 2024

The improvement I was thinking of when I moved the ticket to this repo is to try to drop the -of when detecting (if possible) that the consumer recipe had a layout() defined or something in that line.

Maybe it could be handled by the same thing as finding a CMakeDeps in the conanfile: if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") in conan_provide_dependency macro. But it seems rather brute force and not robust if found in a comment for example.

But I think that the approach of using the tools.cmake.cmake_layout:build_folder is ok. I suspect that since it is an absolute path (${CMAKE_BINARY_DIR}) it instead of nesting itself under the -of really overrides it. If then we could the same way override the self.folders.generators which is missing in the config ( Is there a reason why it is not there?) by ${CMAKE_BINARY_DIR}/conan the behavior could be the same as when there is no layout defined and the -of ${CMAKE_BINARY_DIR}/conan takes over. And when I want to use the recipe-defined layout I just don't use the profile with the config i.e. run the conan install manually.

So thinking next when I would drive the configuration and build by conan. The conan build would be one to run the cmake but it would need to give it the conan_provider.cmake anyway, which then would try to run the install again (at least for the first time) but then I'm unable to see what would happen :). Hopefully, the outcome would be that the deps provider when generating the profile would write the same values to the tools.cmake.cmake_layout:build_folder since the ${CMAKE_BINARY_DIR} would be set by the conan build I guess. But I wouldn't know how to handle the different eventual tools.cmake.cmake_layout:generators_folder for it to be super robust. Now I kind of don't mind, I can change the deps provider to have -of ${CMAKE_BINARY_DIR}/generators so it is the same as cmake_layout defaults and I don't care. All I wanted was to explore the intricacies of having both options for driving the build (either by conan or by cmake/cmake-gui) while having the CMakeLists not have a clue, so I can later change how it is done on CI when there would be a need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants