VS: CMP0147 always triggers custom steps rebuild for CMake 3.27+

Hello

I have a big closed-source project, that uses CMake as a main build system.

After upgrading from CMake 3.26 to CMake 3.27 I see, that my custom generators are always rebuild.

I just run 5 sequential builds and all of the time my custom generators were executed again.

When I add next lines, all was fixed & works as before.

if(POLICY CMP0147)
    # This CMake 3.27 policy breaks incremental builds for IDL files
    cmake_policy(SET CMP0147 OLD)
endif()

My code for custom files generation:

    add_custom_command(
        OUTPUT ${generatedSources}
        COMMAND_EXPAND_LISTS
        COMMAND
            # Shell launcher, that passes another args next
            "${idlScriptPath}"
            # Command to call IDL compiler
            "${IDL_COMPILER}"
                "${additionalFlags}"
        MAIN_DEPENDENCY "${filePath}"
        DEPENDS "${idlScriptPath}"
        DEPFILE "${depFile}"
        WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
        COMMENT "Processing IDL [${filePath}]"
    )

    # add sources and include paths
    target_sources(
        ${TARGET}
        PRIVATE ${generatedSources}
    )

All of the generatedSources have no spaces inside the names.

For Linux I’m using the Ninja generator & don’t see any problem with concurrency (with CMake 3.25 & 3.27.9).

My Windows environment

  • Visual Studio Professional 2022 (17.9.5)
  • CMake 3.27.9, 3.28.4, 3.29.0 (reproduced on all CMake 3.27+ versions)

P.S. Every CMake was reconfigured for dedicated clean directory

I united IDL add_custom_command results to the single add_custom_target, as described here, and works nice on Windows without policies updating.

Just to clarify, you no longer need to set the policy to OLD?

Note that the policy should have been OLD unless you updated your minimum CMake version. If you did that, adapting to new policy behaviors is part of bumping the version. In that case, it seems you found the solution (tie the custom commands together with a single custom target).

Yes, you are right.

But it looks like unexpected part of adding the CMake 3.27 part support.

The main reason I need to add the the CMake 3.27 as a supported one, because CMP0144 generates lots of warnings while CMake 3.26 don’t.
That was not nice, because CMake 3.27 doesn’t fully mimic to the CMake 3.26 behavior if the CMake 3.27 support is not enabled.

Can you please make a small test case that shows this?