conan icon indicating copy to clipboard operation
conan copied to clipboard

[question] unclear how build directory is set in package() (conan 1.x)

Open tclarke opened this issue 3 months ago • 5 comments

What is your question?

I'm trying to create a package which works properly when built with conan create and conan install/build/export-package. The later using "-bf" and without "-bf".

setting self.folders.build="build" works when specifying -bf build but not when running conan create. This is using self.copy("*.so", src=self.folders.build+"/lib") in package()

Changing package() to use src=self.build_folder works with conan create and the src= is the full path to the cache build folder. When using the dev workflow with -bf build it does not work. In that case the src= filed seems correct (build folder in the package directory) but it's actually build in build/build. Removing the self.folders.build line in layout() also fails as self.build_folder is the package directory (pwd when running commands) and not the build folder specified with -bf build.

I'm not sure how build_folder is being set in def package() as it seems to be ignoring the -bf option?

UPDATE: adding -of build to the conan export-pkg seems to have set self.build_folder to that value. I'm even more confused now.

Have you read the CONTRIBUTING guide?

  • [x] I've read the CONTRIBUTING guide

tclarke avatar Nov 12 '25 16:11 tclarke

Hi @tclarke

Thanks for your question.

Please note that Conan 1.X is no longer supported. Conan 2 is more than 2.5 years old, and development and maintenance has fully stopped in Conan 1 both for the tool and ConanCenter packages, no more releases or fixes will happen.

setting self.folders.build="build" works when specifying -bf build but not when running conan create. This is using self.copy("*.so", src=self.folders.build+"/lib") in package()

It would be necessary to have a reproducible example to be able to understand and see the full issue. A couple of quick notes:

  • Even in Conan 1, do not longer use self.copy(), but move to the copy(self, ...) function
  • Do not use --build-folder argument, no longer necessary if using and defining a layout() method, it might be completely ignored.
  • The --output-folder/-of is the Conan2 compatible way to specify a general output folder (including the build folder). But in general it shouldn't be necessary, so better try to avoid its usage if possible.

Thanks for the feedback.

memsharded avatar Nov 12 '25 17:11 memsharded

@memsharded I understand conan 1.x is no longer supported but I've got a project with 90+ packages and a few 100k LOC using it so converting to conan 2.x is a huge undertaking as is something as simple as converting self.copy to copy() (mostly because root_package isn't supported in copy() and we make extensive use of that). It's a dev environment completely disconnected from the Internet so the lack of ConanCenter support doesn't affect the project.

As for an example: (some extraneous stuff like imports removed for brevity). build() uses AutoToolsBuildEnvironment but I don't think that is affecting anything.

class MyLib(ConanFile):
  def layout(self):
    self.folders.source = "lib-source"
    self.cpp.package.libs = ["mylib"]
    self.cpp.package.libdirs = ["lib"]
    self.cpp.package.includedirs = ["include"]
    self.cpp.source.includedirs = ["."]
    self.cpp.build.libdirs = ["."]

  def package(self):
    libdir = os.path.join(self.build_folder, self.cpp.build.libdirs[0])
    self.copy("*.so*", src=libdir, dst="lib", keep_path=False, symlinks=True)
    self.copy("*.a", src=libdir, dst="lib", keep_path=False)
    self.copy("*.h", src=self.cpp.source.includedirs[0], dst="include", keep_path=False)

tclarke avatar Nov 12 '25 17:11 tclarke

Thanks for the feedback.

It seems what you are missing there is a definition of the build folder in layout, something like:

def layout(self):
    self.folders.source = "lib-source"
    self.folders.build = "lib-build"  # Or just "build"
    self.cpp.package.libs = ["mylib"]
    ...

This approach has many advantages, like a clear, fixed and well defined build folder that can be easily .gitignore ignored, simplified command line with less arguments, easier to understand other methods like package(), in which self.build_folder will already use it.

For multi-configuration cases, you can see for example that the cmake_layout() is able to configure a build folder different for different inputs, for example a different build folder for different compilers or architectures or build types. While cmake_layout() can do this automatically and use some other inputs like self.folders.build_folder_vars or the equivalent external conf, doing it for custom layouts is relatively straightforward:

def layout(self):
    self.folders.source = "lib-source"
    self.folders.build = f"lib-build-{self.settings.arch}-{self.settings.build_type}"  # Or just "build"

That way devs will still get different local folders when developing for different settings, without collisions, and the further possible package() logic for flows like conan export-pkg can work way more consistently and robustly.

memsharded avatar Nov 13 '25 11:11 memsharded

Hi @tclarke

Did the last comment help? Any further question or comment? Thanks for the feedback.

memsharded avatar Nov 19 '25 22:11 memsharded

Marking the question as answered, if there is no more activity, it will be closed soon. Thanks!

memsharded avatar Dec 01 '25 10:12 memsharded