conan-io / conan

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

[question] CMAKE_INSTALL_PREFIX in toolchain - local/cache build difference [conan 2] #16567

Closed forry closed 4 months ago

forry commented 4 months ago

What is your question?

Hello, when working with a simple package like one created with the conan new cmake_lib ... I've noticed that when calling conan create the generated cmake_toolchain contains CMAKE_INSTALL_PREFIX while when building locally by conan build it does not have it.

Is there a way around it? E.g. having the same recipe be able to conan create on CI/CD while when the user wants just locally to develop the library and check the output of the cmake install (to some local dir e.g. under build or next to it). Can I get the information about whether the package is being built locally or inside a cache in the conanfile.py? I've tried to use something along the lines of:

    def generate(self):
        tc = CMakeToolchain(self)
        if tc.blocks["output_dirs"].values["package_folder"] == None:
            tc.blocks["output_dirs"].values["package_folder"] = os.path.join(self.folders.source_folder,"install").replace("\\","\\\\")
        tc.generate()

    def package(self):
        copy(self, "*", "./install/", self.package_folder)

But that seems that I'm doing something wrong. Also in the example, there is:

    def package(self):
        cmake = CMake(self)
        cmake.install()

But when the recipe is called locally with just conan build . then the cmake install installs everything directly to the repository folder which is messy. It is a valid answer if the conan is not supposed to be used like this. :)

Thanks

Have you read the CONTRIBUTING guide?

memsharded commented 4 months ago

Hi @forry

Thanks for your question

the generated cmake_toolchain contains CMAKE_INSTALL_PREFIX while when building locally by conan build it does not have it.

Is there a way around it?

This is expected and by design. When doing local development a CMAKE_INSTALL_PREFIX cannot be defined, because there isn't any default folder, and also trying to define it could interfere with some user definitions.

But this shouldn't be an issue, as it is possible to pass it when developing, the idea is that the "canonical" flow is conan install + cmake ... so the user is always in control of which arguments to provide to cmake invocation.

If you still want to force the definition of the variable for conan build you might be able to do so with the tools.cmake.cmaketoolchain:extra_variables conf, that allows to define arbitrary CMake variables.

forry commented 4 months ago

Thanks for the answer! I'm just caught off guard by the function call with the same arguments doing different things depending on the global context :(. I'll stick with the conan install and then cmake after it.

memsharded commented 4 months ago

I'm just caught off guard by the function call with the same arguments doing different things depending on the global context :(.

Yes, the idea is that the build is identical both in the cache (conan create) and locally (both with conan build and with conan install + cmake ...), except the only thing that cannot be defined in the same way which is the final package destination folder, that doesn't exist and cannot be defaulted in the local flow case.