How to force cmake to use the new version of CMP0077 (allow options to be set from variables)

Viewed 3003

I'm trying to add Howard Hinnant's date library as a subdirectory of my build. Here's the simple setup:

$ git clone https://github.com/HowardHinnant/date.git
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(date_test)

set(BUILD_TZ_LIB ON)
set(USE_SYSTEM_TZ_DB ON)
set(ENABLE_DATE_TESTING OFF)
add_subdirectory(date)

Not much going on here. When I try to configure this build as-is, using cmake 3.18.3, I get a bunch of output like:

CMake Warning (dev) at date/CMakeLists.txt:30 (option):
  Policy CMP0077 is not set: option() honors normal variables.  Run "cmake
  --help-policy CMP0077" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  For compatibility with older versions of CMake, option is clearing the
  normal variable 'USE_SYSTEM_TZ_DB'.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at date/CMakeLists.txt:34 (option):
  Policy CMP0077 is not set: option() honors normal variables.  Run "cmake
  --help-policy CMP0077" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  For compatibility with older versions of CMake, option is clearing the
  normal variable 'ENABLE_DATE_TESTING'.
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at date/CMakeLists.txt:37 (option):
  Policy CMP0077 is not set: option() honors normal variables.  Run "cmake
  --help-policy CMP0077" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  For compatibility with older versions of CMake, option is clearing the
  normal variable 'BUILD_TZ_LIB'.
This warning is for project developers.  Use -Wno-dev to suppress it.

# date: USE_SYSTEM_TZ_DB OFF
# date: MANUAL_TZ_DB OFF
# date: USE_TZ_DB_IN_DOT OFF
# date: BUILD_SHARED_LIBS OFF
# date: ENABLE_DATE_TESTING OFF
# date: DISABLE_STRING_VIEW OFF

Notably, my variables got ignored (USE_SYSTEM_TZ_DB is OFF when I want it to be ON).

If I do what the error says, and add cmake_policy(SET CMP0077 NEW), then... I get the exact same thing. Same warning messages about the policy. Same ignoring of the variables I have set.

Is there a way to set these variables and have them propagate into the date build, or do I have to declare these as CACHE INTERNAL variables?

1 Answers

Setting the default value of that policy via set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) before the call to add_subdirectory that adds the date library to your project fixes the problem.

According to the documentation,

Commands cmake_minimum_required(VERSION) and cmake_policy(VERSION) by default leave policies introduced after the given version unset. Set CMAKE_POLICY_DEFAULT_CMP to OLD or NEW to specify the default for policy CMP, where is the policy number.

When CMAKE_POLICY_DEFAULT_CMP0077 is not set, the cmake_minimum_required(VERSION 3.7) call in the CMakeLists.txt of the date-library resets the value of that policy to the OLD behavior. If CMake didn't do that the build of a sub-project included via FetchContent or git submodules could easily break if the parent project updates their CMakeLists.txt to require a newer version.

Related