conan icon indicating copy to clipboard operation
conan copied to clipboard

[bug] CMAKE_OSX_DEPLOYMENT_TARGET may be overridden by CMake projects which set it as cache variable before the first project command

Open jwillikers opened this issue 2 years ago • 7 comments

What is your suggestion?

The CMakeToolchain currently defines CMAKE_OSX_DEPLOYMENT_TARGET as a cache variable. This seems the correct approach according to Professional CMake:

Furthermore, CMAKE_OSX_DEPLOYMENT_TARGET needs to be a cache variable if it is being set directly in the top level CMakeLists.txt file, otherwise it will be overwritten by the compiler checks performed by the project() command

Qt also sets this variable as a cache variable in Qt 6.6.0, but before the first call to the project command which overrides Conan's definition of the variable as a cache variable in the toolchain file. Refer to issue conan-io/conan-center-index#20589.

Have you read the CONTRIBUTING guide?

  • [X] I've read the CONTRIBUTING guide

jwillikers avatar Oct 20 '23 13:10 jwillikers

[EDIT: this comment is now obsolete, it's referring to the original title "CMakeToolchain does not set CMAKE_OSX_DEPLOYMENT_TARGET as a cache variable"]

The Conan CMake toolchain file does set CMAKE_OSX_DEPLOYMENT_TARGET as a cache variable, at least with Conan 1.61.0. Excerpt from a conan_toolchain.cmake:

# Setting CMAKE_OSX_DEPLOYMENT_TARGET if "os.version" is defined by the used conan profile
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "")

In https://github.com/conan-io/conan-center-index/issues/20589 it does not help because Qt also sets it as a cache variable and the second set(... CACHE...) has no effect (unless it's a FORCE).

On the contrary, if conan_toolchain.cmake set it as a normal variable, then it would override the existing cache variable. But I don't know if that's the correct solution.

tamaskenezlego avatar Oct 20 '23 14:10 tamaskenezlego

@tamaskenezlego Thanks, I was incorrect there. I've updated the issue to reflect the actual behavior now.

jwillikers avatar Oct 20 '23 14:10 jwillikers

Thank you, @jwillikers , I added a note to my comment, it's obsolete now.

tamaskenezlego avatar Oct 20 '23 14:10 tamaskenezlego

Also, about my earlier suggestion:

On the contrary, if conan_toolchain.cmake set it as a normal variable, then it would override the existing cache variable. But I don't know if that's the correct solution.

It's probably not the correct solution since setting the same variable, first as cache, then as normal, is ambiguous in CMake: the behavior is different pre and post CMake 3.21.

tamaskenezlego avatar Oct 20 '23 14:10 tamaskenezlego

Yes, using a normal variable doesn't seem like the best approach, although the CMake documentation on CMAKE_OSX_DEPLOYMENT_TARGET describes that is possible by setting a CMake policy.

It's kind of an awkward position for Conan, since projects are supposed to set CMAKE_OSX_DEPLOYMENT_TARGET before the first project command. There's probably four potential solutions, though I'm not sure if they work. The first two seem best.

  1. Set CMAKE_OSX_DEPLOYMENT_TARGET as a normal variable and set the CMake policy CMP0126 to new.
  2. Force the value of CMAKE_OSX_DEPLOYMENT_TARGET in the cache using the FORCE keyword argument when setting it.
  3. Set the variable via the CMake preset file, but this would only work when using CMake presets.
  4. Set CMAKE_OSX_DEPLOYMENT_TARGET using a command-line flag instead of the setting it in the toolchain file. This would then rely on using conan build to actually set the correct flag, which reintroduces the problem CMakeToolchain solves.

jwillikers avatar Oct 20 '23 14:10 jwillikers

I do sort-of hope this can be solved, as this leads to warnings in our build, such as:

ld: warning: object file (/Users/gitlab/.conan2/p/b/opens7056c2fe7a25c/p/lib/libssl.a[3](libssl-lib-d1_lib.o)) was built for newer 'macOS' version (13.3) than being linked (12.0)

(we set os.version=13.3)

I noticed them while investigating another error, which is unrelated. For now, it seems like it doesn't cause actually problems yet, at least.

  1. Set CMAKE_OSX_DEPLOYMENT_TARGET using a command-line flag instead of the setting it in the toolchain file. This would then rely on using conan build to actually set the correct flag, which reintroduces the problem CMakeToolchain solves.

With my current knowledge, solution (4) seems like the most logical option. I encountered a problem with the same nature of using of the toolchain for CMake variables when I tried to set CMAKE_POLICY_VERSION_MINIMUM=3.5 using tools.cmake.cmaketoolchain:extra_variables for some dependency, which doesn't work. I feel like a toolchain may not be the right location for a number of CMake variables.

stevenwdv avatar Jul 10 '25 13:07 stevenwdv

Update: CMake says that CMAKE_OSX_DEPLOYMENT_TARGET should be set before project()/enable_language(). If it's not set explicitly, it will be set from the MACOSX_DEPLOYMENT_TARGET envvar. But: this only happens during the project() call. I think this actually means that packages like Qt that are providing a default for CMAKE_OSX_DEPLOYMENT_TARGET are doing something not intended by CMake, as a user-provided MACOSX_DEPLOYMENT_TARGET envvar will be ignored because CMAKE_OSX_DEPLOYMENT_TARGET was already set by their cmake code before the project() call (as it needs to be). The CMake docs also say that "[CMAKE_OSX_DEPLOYMENT_TARGET] is intended to be set locally by the user creating a build tree." (so not by the package itself).

stevenwdv avatar Sep 11 '25 14:09 stevenwdv