Xmake Version
3.0.8 (also reproducible with current dev — the code in question is unchanged)
Operating System Version and Architecture
Windows 11, x64, MSVC (VS 2026, but any MSVC version reproduces)
Describe Bug
build.ninja files generated by xmake project -k ninja do not contain build edges for Windows resource (.rc) files. The rule mrc definition is emitted, and the link edge for the target lists the .rc.obj among its inputs (it comes from target:objectfiles()), but no build <obj>: mrc <src> statement is ever generated. A clean ninja build therefore fails immediately:
ninja: error: 'build/.objs/hello/windows/x64/release/src/hello.rc.obj', needed by 'build/windows/x64/release/hello.exe', missing and no known rule to make it
The error is easy to miss if you have previously built the same tree with xmake directly: the stale .rc.obj files left in build/.objs/ satisfy ninja, and the build appears to work until the tree is cleaned.
Root cause: in xmake/plugins/project/ninja/build_ninja.lua, _sourcebatch_is_built() whitelists the sourcebatches that get object build edges:
function _sourcebatch_is_built(sourcebatch)
-- we can only use rulename to filter them because sourcekind may be bound to multiple rules
local rulename = sourcebatch.rulename
if rulename == "c.build" or rulename == "c++.build"
or rulename == "asm.build" or rulename == "cuda.build"
or rulename == "objc.build" or rulename == "objc++.build" then
return true
end
end
Resource files belong to the win.sdk.resource rule, so their batch is skipped, while the linker inputs still reference the resource object. (This looks like a regression relative to the behaviour discussed in #1118, where the mrc build edge was still being emitted.)
Suggested fix: add win.sdk.resource to the whitelist. The resource batch's sourcekind is mrc, which matches the emitted rule name, so the generic _add_build_for_objects() path then produces a correct edge:
if rulename == "c.build" or rulename == "c++.build"
or rulename == "asm.build" or rulename == "cuda.build"
or rulename == "objc.build" or rulename == "objc++.build"
or rulename == "win.sdk.resource" then
I verified locally that with this one-line change the generated build.ninja contains the mrc edge and a clean ninja build of a real project (two targets with .rc files) succeeds end to end.
Expected Behavior
ninja builds the generated project from a clean tree, compiling .rc files via the emitted mrc rule.
Project Configuration
Minimal repro:
add_rules("mode.release")
target("hello")
set_kind("binary")
add_files("src/main.cpp")
add_files("src/hello.rc")
src/main.cpp:
src/hello.rc:
1 VERSIONINFO
FILEVERSION 1,0,0,0
BEGIN
END
$ xmake config -y -p windows -a x64 -m release
$ xmake project -k ninja
$ ninja # from a VS x64 developer prompt
ninja: error: 'build/.objs/hello/windows/x64/release/src/hello.rc.obj', needed by 'build/windows/x64/release/hello.exe', missing and no known rule to make it
Additional Information and Error Logs
Generated build.ninja (excerpt) — rule mrc exists, hello.rc.obj is a link input, but no build edge references mrc:
rule mrc
command = C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\rc.exe $ARGS -Fo$out $in
deps = msvc
description = compiling.release $in
build build/windows/x64/release/hello.exe: ld build/.objs/hello/windows/x64/release/src/main.cpp.obj build/.objs/hello/windows/x64/release/src/hello.rc.obj
Xmake Version
3.0.8 (also reproducible with current
dev— the code in question is unchanged)Operating System Version and Architecture
Windows 11, x64, MSVC (VS 2026, but any MSVC version reproduces)
Describe Bug
build.ninjafiles generated byxmake project -k ninjado not contain build edges for Windows resource (.rc) files. Therule mrcdefinition is emitted, and the link edge for the target lists the.rc.objamong its inputs (it comes fromtarget:objectfiles()), but nobuild <obj>: mrc <src>statement is ever generated. A clean ninja build therefore fails immediately:The error is easy to miss if you have previously built the same tree with
xmakedirectly: the stale.rc.objfiles left inbuild/.objs/satisfy ninja, and the build appears to work until the tree is cleaned.Root cause: in
xmake/plugins/project/ninja/build_ninja.lua,_sourcebatch_is_built()whitelists the sourcebatches that get object build edges:Resource files belong to the
win.sdk.resourcerule, so their batch is skipped, while the linker inputs still reference the resource object. (This looks like a regression relative to the behaviour discussed in #1118, where themrcbuild edge was still being emitted.)Suggested fix: add
win.sdk.resourceto the whitelist. The resource batch'ssourcekindismrc, which matches the emitted rule name, so the generic_add_build_for_objects()path then produces a correct edge:I verified locally that with this one-line change the generated
build.ninjacontains themrcedge and a clean ninja build of a real project (two targets with.rcfiles) succeeds end to end.Expected Behavior
ninjabuilds the generated project from a clean tree, compiling.rcfiles via the emittedmrcrule.Project Configuration
Minimal repro:
src/main.cpp:src/hello.rc:Additional Information and Error Logs
Generated
build.ninja(excerpt) —rule mrcexists,hello.rc.objis a link input, but no build edge referencesmrc: