• Masahiro Yamada's avatar
    kbuild: specify output names separately for each emission type from rustc · 295d8398
    Masahiro Yamada authored
    In Kbuild, two different rules must not write to the same file, but
    it happens when compiling rust source files.
    
    For example, set CONFIG_SAMPLE_RUST_MINIMAL=m and run the following:
    
      $ make -j$(nproc) samples/rust/rust_minimal.o samples/rust/rust_minimal.rsi \
                        samples/rust/rust_minimal.s samples/rust/rust_minimal.ll
        [snip]
        RUSTC [M] samples/rust/rust_minimal.o
        RUSTC [M] samples/rust/rust_minimal.rsi
        RUSTC [M] samples/rust/rust_minimal.s
        RUSTC [M] samples/rust/rust_minimal.ll
      mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
      make[3]: *** [scripts/Makefile.build:334: samples/rust/rust_minimal.ll] Error 1
      make[3]: *** Waiting for unfinished jobs....
      mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
      make[3]: *** [scripts/Makefile.build:309: samples/rust/rust_minimal.o] Error 1
      mv: cannot stat 'samples/rust/rust_minimal.d': No such file or directory
      make[3]: *** [scripts/Makefile.build:326: samples/rust/rust_minimal.s] Error 1
      make[2]: *** [scripts/Makefile.build:504: samples/rust] Error 2
      make[1]: *** [scripts/Makefile.build:504: samples] Error 2
      make: *** [Makefile:2008: .] Error 2
    
    The reason for the error is that 4 threads running in parallel renames
    the same file, samples/rust/rust_minimal.d.
    
    This does not happen when compiling C or assembly files because
    -Wp,-MMD,$(depfile) explicitly specifies the dependency filepath.
    $(depfile) is a unique path for each target.
    
    Currently, rustc is only given --out-dir and --emit=<list-of-types>
    So, all the rust build rules output the dep-info into the default
    <CRATE_NAME>.d, which causes the path conflict.
    
    Fortunately, the --emit option is able to specify the output path
    individually, with the form --emit=<type>=<path>.
    
    Add --emit=dep-info=$(depfile) to the common part. Also, remove the
    redundant --out-dir because the output path is specified for each type.
    
    The code gets much cleaner because we do not need to rename *.d files.
    Signed-off-by: default avatarMasahiro Yamada <masahiroy@kernel.org>
    Reviewed-by: default avatarMiguel Ojeda <ojeda@kernel.org>
    Tested-by: default avatarMiguel Ojeda <ojeda@kernel.org>
    Reviewed-by: default avatarVincenzo Palazzo <vincenzopalazzodev@gmail.com>
    295d8398
Makefile 16.2 KB