<p dir="ltr">On Sun, Nov 29, 2015, 10:47 Dan Liew <<a href="mailto:dan@su-root.co.uk">dan@su-root.co.uk</a>> wrote:</p>
<blockquote><p dir="ltr">Hi,</p>
<p dir="ltr"># TL;DR</p>
<p dir="ltr">I need a way of determining the header file dependencies of a source<br>
file and inform CMake about them. CMake doesn't do this automatically<br>
because I'm using custom commands for the compilation step so CMake<br>
doesn't do it's usual magic of automatically inferring source file<br>
header dependencies. This is because this part of the compilation step<br>
requires a separate C++ compiler (completely independent from the one<br>
that CMake detects at configure time).</p>
<p dir="ltr">Is there a way of doing this that will also regenerate the<br>
dependencies if the source file changes?</p>
<p dir="ltr"># Long version</p>
<p dir="ltr">A C++ project that I work on [1] is (amongst other things) a compiler.<br>
In order to compile applications it needs to link in a supporting<br>
runtime that is compiled to LLVM bitcode which is linked into the<br>
applications it compiles.</p>
<p dir="ltr">The supporting runtime is written in C++ and compiled with Clang. The<br>
compilation of the runtime is currently achieved using<br>
``add_custom_command()`` and so I am not using CMake's in built<br>
support for detecting header file dependencies. The reason for doing<br>
it this way is because the LLVM bitcode compiler (i.e. Clang) **is<br>
not** the same compiler as the host C++ compiler for the project. For<br>
example the host code might be built with MSVC but the supporting<br>
runtime is **always** built with Clang.</p>
<p dir="ltr">To see this concretely take a look at [2].</p>
<p dir="ltr">The build works correctly if you build from a clean build directory.<br>
It does not work correctly if you perform a rebuild and change one of<br>
the header files that the supporting runtime depends on. This is<br>
because CMake doesn't know that the runtime source files depend on the<br>
header files and so doesn't rebuild the relevant source files.</p>
<p dir="ltr">I can obviously tell CMake about these manually (adding more entries<br>
under ``DEPENDS`` in the ``add_custom_command()`` invocation) but this<br>
is very cumbersome.</p>
<p dir="ltr">What I really need is a way to</p>
<p dir="ltr">* Automatically infer the dependencies of a source file and tell CMake<br>
about them<br>
* Have the dependencies automatically regenerated if the source file<br>
changes (someone could add or remove a header file include).</p>
<p dir="ltr">In a simple Makefile build system this typically achieved by doing<br>
something like this:</p>
<p dir="ltr">```<br>
all:: $(SRCS:.cpp:.o)</p>
<p dir="ltr">SRCS := foo.cpp bar.cpp</p>
<p dir="ltr"># Include SRC file dependencies generated by the compiler if they exist<br>
-include $(SRCs:.cpp=.d)</p>
<p dir="ltr">%.o : %.cpp<br>
  $(CXX) -c $< -o $@ -MP -MMD -MF $*.d<br>
```</p>
<p dir="ltr">Note the ``-M*`` flags get the compiler when it runs to generate<br>
additional makefile rules that will get included next time a build<br>
happens.</p>
<p dir="ltr">I don't really know how to do the same thing with CMake. One idea is<br>
at configure time invoke Clang with the ``-MP -MMD -MF`` flags on each<br>
runtime source file, extract the dependencies then pass them to<br>
``DEPENDS`` in ``add_custom_command()``. If I wanted the dependencies<br>
regenerated if the runtime source file changes then I would need to<br>
somehow get CMake to reconfigure every time this happens.</p>
<p dir="ltr">I don't like this idea very much due to</p>
<p dir="ltr">* Having to invoke Clang manually to determine the dependencies. CMake<br>
already knows how to determine source file dependencies, but this<br>
functionality (AFAIK) isn't exposed to me.</p>
<p dir="ltr">* Reconfiguring every time one of the runtime source file changes is<br>
annoying (configuring can be slow sometimes).</p>
<p dir="ltr">Does anyone have any other ideas? CMake obviously knows how to do all<br>
this stuff already for source files being compiled for the detected<br>
host C++ compiler, I just don't know how to get at this logic for<br>
source files that need to be built with a second independent C++<br>
compiler.</p>
<p dir="ltr">[1] <a href="https://github.com/halide/Halide">https://github.com/halide/Halide</a><br>
[2] <a href="https://github.com/halide/Halide/blob/master/src/CMakeLists.txt#L140">https://github.com/halide/Halide/blob/master/src/CMakeLists.txt#L140</a></p>
<p dir="ltr">Thanks,<br>
Dan.</p>
</blockquote>
<blockquote><p dir="ltr"><br>
</p>
</blockquote>
<p dir="ltr"><br>
</p>
<p dir="ltr">Hi Dan,</p>
<p dir="ltr">Not going into detail as I'm typing on the phone, but this really sounds like a case where a "SuperBuild" (<a href="http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html">http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html</a>) can help you to simplify things a lot.</p>
<p dir="ltr">Michael</p>