Setting CMAKE_<LANG>_ARCHITECTURE_ID/CMAKE_CL_SHOWINCLUDES_PREFIX to get RC files working?

We have a custom MSVC toolchain. However, we were getting an issue related to RC files. That only manifested on Ninja dirty builds.

        # Here is the bug will manifest itself:
        # "ninja: error: FindFirstFileExA(note: including file: d:/foobar/ms_sdk/n20246/10/include/10.0.20246.0/shared): The filename, directory name, or volume label syntax is incorrect."

An engineer at our company was able to workaround this bug by putting the following code in our custom toolchain:

        # This is neccessary to ensure RC files compile with our custom toolchain
        # Otherwise dirty builds will break. This code basically patches a cmake bug.
        if (CMAKE_GENERATOR MATCHES "Ninja")
            # Compiling RC files needs to set this. The Ninja generator calls cmcldeps.exe to extract dependencies for RC
            # files. But it configurates DepType to "gcc" so cmake cannot filter show includes prefix and the dependencies
            # are stored in .ninja_deps with the prefix and cause next run of ninja to fail. The DepType cannot be forced
            # to "msvc" otherwise the dependency changes won't trigger recompilation of RC files.
            # The workaround is to set CMAKE_CL_SHOWINCLUDES_PREFIX to the exact English string "Note: including file: ".
            # function CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX may be used if any locale issue occurs.
            set(CMAKE_CL_SHOWINCLUDES_PREFIX "Note: including file: " CACHE INTERNAL "AMD WORKAROUND")

            # The Ninja generator relies on the following variables to determine MSVC style PDB names. But these variables
            # stored in cmake are only initialized to "" when it is first time run on a project before CMake${lang}Compiler
            # .cmake are generated. The next run doesn't initilazed them because CMake${lang}Compiler.cmake are there. So
            # they are null and SetMsvcTargetPdbVariable() returns false so ".dbg" suffix is used for PDBs.
            # The workaround is to set them to either x64 or x86 (actually "" is enough).
            #
            # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.html?highlight=architecture_id
            set(CMAKE_CXX_ARCHITECTURE_ID "x64" CACHE INTERNAL "AMD WORKAROUND")
            set(CMAKE_C_ARCHITECTURE_ID "x64" CACHE INTERNAL "AMD WORKAROUND")
        endif()

This issue with resource files only shows up with our custom toolchains using Ninja.

It works fine when we aren’t using a custom toolchain. And this bug only manifests itself on Ninja.

I’d like to not have this code in the future because it requires deeper knowledge of CMake then is desirable for us.

I think an issue with this information would be warranted. I don’t know where the ultimate fix would be, but I’d guess that the custom toolchains are either missing some detail (in which case docs could be improved) or are missing hooks to set these kinds of things (in which case docs and code could be improved).

How can I help you all get the information you need?

The toolchain file you’re using, platform details, and the error/workaround should be sufficient. You can submit it here.

1 Like

I’ve create an issue and provided the toolchain.

Thanks. For reference, the issue is here. I see that it is marked as confidential. If there isn’t any non-public information, please make it public so others can see it and add input (if they’ve seen the same problem). I’ll leave that up to you in case something is sensitive.

I triple checked everything. For the third time. I did a good job sanitizing it. I just don’t know how to unmark it as confidential.

Thanks to opening up the issue I was able to fix the problem for the Ninja builds.

I was specifying too much information in the toolchain like @brad.king said.

“At least CMAKE_LANG_COMPILER_ID, CMAKE_LANG_COMPILER_VERSION, CMAKE_LANG_ARCHITECTURE_ID, and CMAKE_LANG_STANDARD_COMPUTED_DEFAULT should all be computed by CMake automatically. By setting them in the toolchain file you may be messing with CMake’s internal logic and break other things.”

He was exactly right. Specifying too much stuff was causing problems leading me to specify even more stuff.

Currently here is all I need to specify for my ninja toolchain:

  • CMAKE_SYSTEM_NAME (If host doesn’t match target)
  • CMAKE_SYSTEM_VERSION
  • CMAKE_SYSTEM_PROCESSOR
  • CMAKE_C_COMPILER
  • CMAKE_CXX_COMPILER
  • CMAKE_RC_COMPILER
  • CMAKE_MT
  • CMAKE_*_LINKER_FLAGS_INIT
    • EXE SHARED STATIC MODULE
  • CMAKE_LANG_STANDARD_INCLUDE_DIRECTORIES