ecmwf / ecbuild

A CMake-based build system, consisting of a collection of CMake macros and functions that ease the managing of software build systems
https://ecbuild.readthedocs.io
Apache License 2.0
26 stars 25 forks source link

ecbuild_print_summary reports options according to last project only #65

Open reuterbal opened 1 month ago

reuterbal commented 1 month ago

What happened?

When a build is composed of multiple projects, e.g., as is the case with ecbundle, and more than one project uses an ecbuild_add_option with the same feature name, then the option can be toggled individually by setting <PROJ>_ENABLE_<FEATURE>. However, ecbuild_print_summary will report the status of these options according to the value of the last project, even if it is different for other projects.

What are the steps to reproduce the bug?

Reproducer CMakeLists.txt:

cmake_minimum_required( VERSION 3.20 FATAL_ERROR )
find_package( ecbuild 3.4 REQUIRED )

project( proja LANGUAGES NONE VERSION 0.2 )
ecbuild_add_option(
    FEATURE MYFEATURE
    DEFAULT ON
)

project( projb LANGUAGES NONE VERSION 0.1 )
ecbuild_add_option(
    FEATURE MYFEATURE
    DEFAULT OFF
)

ecbuild_print_summary()

Dependent on setting the value of the variables ENABLE_MYFEATURE, PROJA_ENABLE_MYFEATURE or PROJB_ENABLE_MYFEATURE we would expect the option to be enabled for one or the other or both.

The output is correct if both options have the same value, e.g.:

$ cmake <...> -DENABLE_MYFEATURE=ON
[...]
-- ---------------------------------------------------------
-- [proja] (0.2)
-- Feature TESTS enabled
-- Feature PKGCONFIG enabled
-- Feature MYFEATURE enabled
-- ---------------------------------------------------------
-- [projb] (0.1)
-- Feature TESTS enabled
-- Feature PKGCONFIG enabled
-- Feature MYFEATURE enabled
-- ---------------------------------------------------------
-- Build summary
-- ---------------------------------------------------------
[...]
-- The following features have been enabled:

 * TESTS, proja: Enable the unit tests, projb: Enable the unit tests
 * PKGCONFIG, proja: Enable ecbuild_pkgconfig, projb: Enable ecbuild_pkgconfig
 * MYFEATURE, proja: , projb:

But is wrong when they have a different value, e.g., in the following example proja has the option disabled:

$ cmake .. -DENABLE_MYFEATURE=OFF -DPROJB_ENABLE_MYFEATURE=ON
[...]
-- ---------------------------------------------------------
-- [proja] (0.2)
-- Feature TESTS enabled
-- Feature PKGCONFIG enabled
-- ---------------------------------------------------------
-- [projb] (0.1)
-- Feature TESTS enabled
-- Feature PKGCONFIG enabled
CMake Warning at /usr/local/apps/ecbuild/3.8.3/share/ecbuild/cmake/ecbuild_log.cmake:162 (message):
  WARN - Both ENABLE_MYFEATURE and PROJB_ENABLE_MYFEATURE are set for
  feature MYFEATURE.  Using PROJB_ENABLE_MYFEATURE=ON
Call Stack (most recent call first):
  /usr/local/apps/ecbuild/3.8.3/share/ecbuild/cmake/ecbuild_add_option.cmake:172 (ecbuild_warn)
  CMakeLists.txt:13 (ecbuild_add_option)

-- Feature MYFEATURE enabled
-- ---------------------------------------------------------
-- Build summary
-- ---------------------------------------------------------
[...]
-- The following features have been enabled:

 * TESTS, proja: Enable the unit tests, projb: Enable the unit tests
 * PKGCONFIG, proja: Enable ecbuild_pkgconfig, projb: Enable ecbuild_pkgconfig
 * MYFEATURE, proja: , projb:

Or the other way round:

$ cmake .. -DENABLE_MYFEATURE=ON -DPROJB_ENABLE_MYFEATURE=OFF
[...]
-- ---------------------------------------------------------
-- [proja] (0.2)
-- Feature TESTS enabled
-- Feature PKGCONFIG enabled
-- Feature MYFEATURE enabled
-- ---------------------------------------------------------
-- [projb] (0.1)
-- Feature TESTS enabled
-- Feature PKGCONFIG enabled
CMake Warning at /usr/local/apps/ecbuild/3.8.3/share/ecbuild/cmake/ecbuild_log.cmake:162 (message):
  WARN - Both ENABLE_MYFEATURE and PROJB_ENABLE_MYFEATURE are set for
  feature MYFEATURE.  Using PROJB_ENABLE_MYFEATURE=OFF
Call Stack (most recent call first):
  /usr/local/apps/ecbuild/3.8.3/share/ecbuild/cmake/ecbuild_add_option.cmake:172 (ecbuild_warn)
  CMakeLists.txt:13 (ecbuild_add_option)

-- ---------------------------------------------------------
-- Build summary
-- ---------------------------------------------------------
[...]
-- The following features have been disabled:

 * MYFEATURE, proja: , projb:

Version

3.8.3

Platform (OS and architecture)

Atos AC

Relevant log output

No response

Accompanying data

No response

Organisation

ECMWF

marcosbento commented 1 week ago

After a brief investigation, this is apparently one of the shortcomings of CMake feature_summary(): any particular feature is always assigned to either enabled or disabled, independently if it is used otherwise in more that one CMake project. As mentioned in the description of the issue, this is determined by the last value taken by the feature during Project configuration.

ecBuild builds the summary information incrementally, and cannot a priori determine to which group (enabled or disabled) the feature will the assigned.

One viable solution could be to let CMake do the usual grouping, while simply including a "marker" to identify if for some projects the feature has been used differently. This would result is having summaries like follows.

...snip...

-- The following features have been disabled:

...snip...


 - for `cmake .. -DENABLE_MYFEATURE=OFF -DPROJB_ENABLE_MYFEATURE=ON`

...snip...


-- Feature summary


-- The following features have been enabled:

...snip...



A more radical approach would be to force a feature to be grouped as `enabled` if it has been enabled in any project. We would still require a marker to identify projects where it was disabled.

@wdeconinck , @tlmquintino , what do you think would be the approach to follow here?