Depfile support

werk has limited support for depfiles (.d) generated by other tools, such as C/C++ compilers, shader compilers, or Cargo.

Depfiles contain Make rules which indicate the dependencies of a given source file discovered by a compiler. werk can parse these rules and apply them as implicit dependencies of its own recipes.

A dependency being "implied" means that the build logic treats the dependency normally, but the contents of the depfile are not available to the build recipe through the in variable.

Depfile support has two "modes", and werk automatically detects which one is in use (per-recipe):

  • Depfile is generated during compilation of the main source file. For example, clang and gcc support passing -MF as an argument during compilation, which will generate a depfile as an additional side-effect.
  • Depfile is generated as a separate invocation of the compiler, without producing the actual output of the compilation step (-MF without -o).

When a depfile statement exists in the body of a build recipe, werk applies the following logic:

  • If there is a build recipe to specifically generate that depfile, that file is added as an implicit dependency, and its recipe will be run before the current recipe.
  • If there is no build recipe to generate the depfile, werk assumes that the current recipe will implicitly generate the depfile.
  • If the depfile exists, it is parsed by werk, and dependencies discovered in the depfile are added as implicit dependencies of the recipe. If the depfile exists, but could not be parsed, the current recipe fails to build with a hard error.
  • If the depfile does not exist:
    • If werk believes that it should be implicitly be generated by the command, consider the current recipe outdated.
    • If werk believes that another explicit recipe should have generated the depfile, but it did not, emit a hard error.
  • If, after building the current recipe, and the depfile should have been implicitly generated by the compiler, but it still does not exist, werk emits a warning.

The parser for the depfile is a very permissive, but limited, parser of Makefile syntax to support different conventions used by different tools on different platforms. For example, some tools put prerequisites with paths containing whitespace in double-quotes, while others escape them with a backslash. Some tools escape backslashes in Windows paths, while others do not. The depfile parser cannot be used to determine if a file is valid Makefile syntax, and there is valid Makefile syntax that will be rejected by the depfile parser.

The depfile parser has been tested with the following tools:

  • clang and gcc
  • slangc
  • glslc
  • cargo