[CMake] Ninja generator emits order-only dependencies for custom commands
melak47
melak47 at posteo.net
Fri Sep 27 23:24:45 EDT 2019
I'm using add_custom_command with the Ninja generator on Windows to
invoke mc.exe on an .mc file,
to generate an .rc file, to create a resource DLL.
The full example is here:
https://gist.github.com/melak47/f7d83046c6d57b338d633468d078f5b1
The problem is, changing the .mc file and rebuilding only causes mc.exe
to rerun,
anything depending on the generated .rc file is not rebuilt.
I think this happens because cmake generates some order-only
dependencies for the generated files.
Some of the relevant build statements that are generated:
#
=============================================================================
# Object build statements for MODULE_LIBRARY target example
#############################################
# Order-only phony target for example
build cmake_object_order_depends_target_example: phony || example.hpp
example.rc example_MSG00001.bin
build CMakeFiles\example.dir\example.rc.res: RC_COMPILER__example
D$:\repro\build\example.rc || cmake_object_order_depends_target_example
DEFINES = -Dexample_EXPORTS
DEP_FILE = CMakeFiles\example.dir\example.rc.res.d
FLAGS = -DWIN32 -D_DEBUG
OBJECT_DIR = CMakeFiles\example.dir
OBJECT_FILE_DIR = CMakeFiles\example.dir
TARGET_COMPILE_PDB = CMakeFiles\example.dir\
TARGET_PDB = example.pdb
#
=============================================================================
# Link build statements for MODULE_LIBRARY target example
#############################################
# Link the shared module example.dll
build example.dll: CXX_MODULE_LIBRARY_LINKER__example
CMakeFiles\example.dir\example.rc.res
LANGUAGE_COMPILE_FLAGS = /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od
/RTC1 -MDd
LINK_FLAGS = /machine:x64 /debug /INCREMENTAL /noentry
LINK_LIBRARIES = kernel32.lib user32.lib gdi32.lib winspool.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
OBJECT_DIR = CMakeFiles\example.dir
POST_BUILD = cd .
PRE_LINK = cd .
TARGET_COMPILE_PDB = CMakeFiles\example.dir\
TARGET_FILE = example.dll
TARGET_IMPLIB = example.lib
TARGET_PDB = example.pdb
#############################################
# Custom command for example.rc
build example.rc example.hpp example_MSG00001.bin: CUSTOM_COMMAND
..\example.mc
COMMAND = cmd.exe /C "cd /D D:\repro\build && "C:\Program Files
(x86)\Windows Kits\10\bin\10.0.18362.0\x64\mc.exe" -b -e hpp -h
D:/repro/build -r D:/repro/build D:/repro/example.mc"
DESC = Generating example.rc, example.hpp, example_MSG00001.bin
restat = 1
#############################################
# Assume dependencies for generated source file.
build D$:\repro\build\example.rc: CUSTOM_COMMAND ||
cmake_object_order_depends_target_example
COMMAND = cmd.exe /c
restat = 1
As you can see, CMakeFiles\example.dir\example.rc.res depends on
D$:\repro\build\example.rc,
which depends on the actual example.rc through
cmake_object_order_depends_target_example as
an **order-only** dependency.
If I read the ninja manual correctly, this means changes to example.rc
will by design not cause depndees to be rebuilt.
If instead of an empty CUSTOM_COMMAND, cmake emitted a phony like:
build D$:\repro\build\example.rc: phony example.rc
example.rc.res and example.dll would be properly rebuilt.
(Also, a phony does not appear in the build log, unlike the empty
CUSTOM_COMMAND which just shows up as 'cmd /c')
Is this a bug, or is there some intent behind emitting a CUSTOM_COMMAND
here?
More information about the CMake
mailing list