Ninja generator emits order-only dependencies for custom commands

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Ninja generator emits order-only dependencies for custom commands

melak47
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?
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Ninja generator emits order-only dependencies for custom commands

Craig Scott-3

On Sat, Sep 28, 2019 at 1:31 PM melak47 <[hidden email]> wrote:
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?


This seems like a bug to me, please add it to gitlab as a new issue here:


Please ensure you also record what version of CMake you are using. If you can test with some different CMake versions to confirm whether it is a long-standing issue or a regression in a more recent version, that would also be very helpful. I believe there have been a few changes relating to RC handling in the last few releases, so can't rule out a regression.


--
Craig Scott
Melbourne, Australia

Get the hand-book for every CMake user: Professional CMake: A Practical Guide
Consulting services (CMake, C++, build/release processes): https://crascit.com/services

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake