How does IMPLICIT_DEPENDS work?

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

How does IMPLICIT_DEPENDS work?

Paul Smith
We're trying to implement precompiled headers (yes, I've seen all the
various github projects around this).  As part of this we need to make
sure the precompiled header is rebuilt whenever any of the headers that
it includes changes: this seems like exactly the job for
add_custom_command's IMPLICIT_DEPENDS.

But, it doesn't seem to be doing anything at all for me so I wonder
what I'm doing wrong.

I'm using CMake 3.13.4 on GNU/Linux with GCC C++ and Makefile
generators (we also will have support for MSVC but I'm not worried
about that here).

I have a function to deal with PCH generation:

  function(add_precompiled_header _target _header)
    ...
      # This is the actual command that does the precompiling
      add_custom_command(
          OUTPUT "${_pch_file}"
          COMMAND "${CMAKE_COMMAND}" -E make_directory "${_pch_dir}"
          COMMAND "${CMAKE_CXX_COMPILER}" "${_flags}" -x c++-header -o
"${_pch_file}" "${_header}"
          COMMAND_EXPAND_LISTS
          IMPLICIT_DEPENDS CXX "${_header}"
          COMMENT "Precompiling ${_header} for ${_target} (C++)")
    ...
      get_property(_sources TARGET ${_target} PROPERTY SOURCES)
      foreach(_source ${_sources})
    ...
          set_property(SOURCE ${_source} APPEND PROPERTY
              OBJECT_DEPENDS "${_pch_file}")
    ...
      endforeach()

Obviously there're a lot of other things here I'm leaving out, but
basically there's a custom command that compiles the header into a PCH
and lists the header as an IMPLICIT_DEPENDS, and adds that PCH as an
OBJECT_DEPENDS to the source files.

When I change the PCH file, the source files are rebuilt so that works.

If I change the header the PCH file is rebuilt so that works too.

But if I change a header file that the PCH includes, the PCH is NOT
rebuilt.  Not only that but if I use "make -d" I can see that the PCH
target never even considers any of the included files when determining
out-of-date-ness of the PCH file.

It seems like IMPLICIT_DEPENDS is behaving identically to DEPENDS here:
only listing the header as a dependency but not trying to determine
what it, itself, depends on.

What am I doing wrong?  Is there some subtlety to IMPLICIT_DEPENDS that
I'm missing?

--

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: How does IMPLICIT_DEPENDS work?

Paul Smith
On Fri, 2019-04-26 at 17:26 -0400, Paul Smith wrote:
> We're trying to implement precompiled headers (yes, I've seen all the
> various github projects around this).  As part of this we need to make
> sure the precompiled header is rebuilt whenever any of the headers that
> it includes changes: this seems like exactly the job for
> add_custom_command's IMPLICIT_DEPENDS.
>
> But, it doesn't seem to be doing anything at all for me so I wonder
> what I'm doing wrong.

OK, I figured out the issue.  The problem is a combination of the way I
was testing and a sort of bizarre "feature" of the CMake Makefile
generator:

The Makefile generator only generates prerequisite information when a
CMake target is completely built.  It doesn't generate the information
when an individual object file is built.

I was testing (to allow faster turnaround) by simply running:

  cmake ...
  make foo.cpp.o
  touch header.h
  make foo.cpp.o

and the PCH file was not being rebuilt even though it included
header.h.  After MUCH tearing of hair and groping around in the
generated makefiles, I realized that unless I built the full target and
not just the individual object file, no prerequisite information was
created.  I had to run:

  cmake ...
  make footarget
  touch header.h
  make foo.cpp.o

The first make would build foo.cpp.o and also generate all the
prerequisite information as a side-effect of creating footarget.  Then
the second make would correctly update the PCH file in addition to
rebuilding the object file.

Note this is not related to PCH at all: you can reproduce this with the
simplest of CMake configurations.

That is definitely a subtlety of the makefile generator that was
unexpected: maybe it will help someone else trying to do similar
testing.

--

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: How does IMPLICIT_DEPENDS work?

Paul Smith
On Sat, 2019-04-27 at 13:49 -0400, Paul Smith wrote:

> On Fri, 2019-04-26 at 17:26 -0400, Paul Smith wrote:
> > We're trying to implement precompiled headers (yes, I've seen all the
> > various github projects around this).  As part of this we need to make
> > sure the precompiled header is rebuilt whenever any of the headers that
> > it includes changes: this seems like exactly the job for
> > add_custom_command's IMPLICIT_DEPENDS.
> >
> > But, it doesn't seem to be doing anything at all for me so I wonder
> > what I'm doing wrong.
>
> OK, I figured out the issue.  The problem is a combination of the way I
> was testing and a sort of bizarre "feature" of the CMake Makefile
> generator

I re-confirmed the documented restriction that IMPLICIT_DEPENDS is not
available for non-Makefile generators (e.g., Ninja).

Without this facility it seems impossible to support precompiled
headers in CMake, so I've had to disable PCH for non-Makefile (and non-
MSVC of course) generators.

Is there any chance of getting IMPLICIT_DEPENDS support for Ninja?  Is
the reason that it's not supported because Ninja does its own
dependency management or something like that?  Does anyone know how
it's done?  Is it done by using the compiler flags like -MMD/-MP etc.
or does it have its own built-in facility?

--

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