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] Settings CMake option for consumed package in conanfile.py #17541

Closed
1 task done
rickyjames35 opened this issue Dec 30, 2024 · 4 comments
Closed
1 task done
Assignees

Comments

@rickyjames35
Copy link

What is your question?

I would like to set a CMake option for a package that I'm consuming in my conanfile.py. To be specific I need to set GDAL_ENABLE_DRIVER_PDS=OFF for GDAL. The Conan recipe supports many options but not the ability to disable this specific option. Here is an example of what I'm trying to do...

from conan import ConanFile

class SgcmConanFile(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeDeps"

    def requirements(self):
        self.requires("gdal/3.8.3")

    def configure(self):
        self.options["gdal"].with_arrow = False # This works
        self.options["gdal"].cmake_definitions = {"GDAL_ENABLE_DRIVER_PDS": "OFF"} # This does not work

Is this possible to do with Conan or do I need to manually build this library to have control of this CMake option?

Have you read the CONTRIBUTING guide?

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

Hi @rickyjames35

It is not possible to directly inject a CMake variable from a consumer recipe into a dependency. The recommended way to implement this is having the dependency recipe to properly define an option that can define the value.

What you can do instead is defining it in the profile file. This is the recommended way, configuration of dependencies is typically better in profile files, even options values are recommended to be defined in profiles and not in recipes.

For injecting a CMake variable, you can use the:

$ conan config list variables
tools.cmake.cmaketoolchain:extra_variables: Dictionary with variables to be injected in CMakeToolchain (potential override of CMakeToolchain defined variables)

So defining it in your [conf] section in your profile will allow to define that into your dependency. You can scope it to a given package name like mypkg/*:tools.cmake.cmaketoolchain:extra_variables=...

You might also inject a full toolchain file with user_toolchain conf, but probably for this case a variable is enough

Please let me know if this helps.

@rickyjames35
Copy link
Author

I'm using conan_provider.cmake to integrate Conan with my repo. In the root of my repo I have my conanfile.py and I'm using "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "cmake/conan_provider.cmake" in my CMakePresets.json kick off Conan during the configuration phase of CMake and pull in my dependencies. I'm not a Conan expert but I imagine you wouldn't want to require users to modify their Conan profile in order to apply this CMake options since your profile is not checked into the repo correct? I did test out what you were suggesting. Here is my profile...

~/.conan2/profiles$ cat default 
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux

[conf]
gdal/*:tools.cmake.cmaketoolchain:extra_variables={"GDAL_USE_ARROW": "OFF"}

I can see it picked it up in my CMake output when running CMake configure here:

[cmake] ======== Input profiles ========
[cmake] Profile host:
[cmake] [settings]
[cmake] arch=armv8
[cmake] build_type=Release
[cmake] compiler=clang
[cmake] compiler.cppstd=20
[cmake] compiler.libcxx=c++_static
[cmake] compiler.version=18
[cmake] os=Android
[cmake] os.api_level=32
[cmake] [conf]
[cmake] gdal/*:tools.cmake.cmaketoolchain:extra_variables={'GDAL_USE_ARROW': 'OFF'}
[cmake] tools.android:ndk_path=/opt/android_sdk/ndk/27.1.12297006
[cmake] tools.build:compiler_executables={'c': '/opt/android_sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang', 'cpp': '/opt/android_sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++'}
[cmake] tools.cmake.cmaketoolchain:generator=Ninja Multi-Config
[cmake] 
[cmake] Profile build:
[cmake] [settings]
[cmake] arch=x86_64
[cmake] build_type=Release
[cmake] compiler=gcc
[cmake] compiler.cppstd=gnu17
[cmake] compiler.libcxx=libstdc++11
[cmake] compiler.version=11
[cmake] os=Linux
[cmake] [conf]
[cmake] gdal/*:tools.cmake.cmaketoolchain:extra_variables={'GDAL_USE_ARROW': 'OFF'}

However GDAL_USE_ARROW is being ignored when GDAL is being built.

@memsharded
Copy link
Member

I'm not a Conan expert but I imagine you wouldn't want to require users to modify their Conan profile in order to apply this CMake options since your profile is not checked into the repo correct? I did test out what you were suggesting.

Yes, this is the way to go. They don't need to modify their default profiles, users don't have do do much. cmake-conan allows to inject custom profiles, which can be included in the project if desired too. And profiles can compose, so a profile with just the [conf] is perfectly valid too.

However GDAL_USE_ARROW is being ignored when GDAL is being built.

That would be a different thing to check, and it would need some extra details:

  • A minimum reproducible example, like conan install --requires=gdal/version --build=gdal/version -c gdal/*:tools.cmake.cmake_toolchain_extra_variables=...
  • The full output of that command.

@rickyjames35
Copy link
Author

Woot! Got it working, thanks for your help @memsharded. The issue I was seeing with:

However GDAL_USE_ARROW is being ignored when GDAL is being built.

Was likely due to the fact that I was setting it using....

[conf]
gdal/*:tools.cmake.cmaketoolchain:extra_variables={"GDAL_USE_ARROW": "OFF"}

... but then it was being overwritten by the default Conan options for the GDAL recipe. I was just testing out the ability to directly set CMake variables from a host profile. Unfortunately I picked a bad variable to test with and confused myself.

This is what I ended up using for my host profile with success:

[conf]
tools.cmake.cmaketoolchain:extra_variables={'GDAL_BUILD_OPTIONAL_DRIVERS': 'OFF', 'OGR_BUILD_OPTIONAL_DRIVERS': 'OFF'}

To load the profile when using conan_provider.cmake I set the cache variable: "CONAN_HOST_PROFILE": "${sourceDir}/cmake/conan_host_profile;auto-cmake" in my CMakePresets.json.

This gets me by for now.

The recommended way to implement this is having the dependency recipe to properly define an option that can define the value.

I'll create a ticket to get GDAL_BUILD_OPTIONAL_DRIVERS and OGR_BUILD_OPTIONAL_DRIVERS added as options for the GDAL recipe.

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

No branches or pull requests

2 participants