List dependencies

How to find out the list of dependencies (Source files and headers) for a certain target (an executable/library). For example Let’s say I’ve following:

$ ls
hello.cpp  utils.cpp  utils.h

Which in it’s simplest form, I compile and link as below

$ clang++-14 -c hello.cpp -o hello.o
$ clang++-14 -c utils.cpp -o utils.o
$ clang++-14 utils.o hello.o -o greetings

OR would be achieved with a simple CMakeLists.txt file as below:

$ cat CMakeLists.txt

cmake_minimum_required(VERSION 3.2)
project(sample)
add_executable(greetings
        hello.cpp
        utils.cpp
$ ./greetings 
hello world!
sum is 5

Contents of this simple files are not much of relevance, hence skipping those for brevity purposes.
Now l was wondering, if it’s possible to find out the list of user sources and include files that are required to build this “greetings” target. In a practical project, I would have CMake based project, which would then create makefiles or ninja files or something similar, so I am guessing that the compiler would know exactly which files were used to build this target and if so, then is there clang command(s) that I can use to dump this information.

It sounds like you might want the dependency generation options. By default they’d spit out a hello.d in Makefile format.

Thank you @TNorthover It helps, however I’ve few more question:
So my sample hello.cpp is as below:

#include <iostream>
#include "utils.h"

using namespace std;

int main()
{
        cout << "hello world!" << endl;
        int result = sum(2,3);
        cout << "sum is " << result << endl;

        return 0;
}

now, Invoking clang with -MMD flag gives me the following result:

$ clang++-14 -MMD utils.d -c utils.cpp -o utils.o
clang-14: warning: utils.d: 'linker' input unused [-Wunused-command-line-argument]
$ clang++-14 -MMD hello.d -c hello.cpp -o hello.o
clang-14: warning: hello.d: 'linker' input unused [-Wunused-command-line-argument]
$ cat utils.d 
utils.o: utils.cpp utils.h

$ cat hello.d
hello.o: hello.cpp utils.h

As the Link step is not done yet, the dependency generation here does not show any information about the utils.cpp dependency for hello, however, when I finally create the executable (in my case, ‘greetings’) I was hoping I could do something like below, but it gives error

$ clang++-14 utils.o hello.o -MMD greetings.dep -o greetings 
clang-14: error: no such file or directory: 'greetings.dep'

How can I get the dependency list for the final executable.

clang -MD -c foo.cpp -o foo.o. There will be a foo.d. showing you the dependencies of foo.cpp.

Finding the dependencies of the linker for the final executable is more involved. There will be shared libraries.

Okay, then for the time being, I would like to integrate this additional flag to my cmake based build system, so I do the following:

cmake_minimum_required(VERSION 3.2)
# set(CMAKE_CXX_FLAGS "-Wall -Werror")
set(CMAKE_CXX_FLAGS "-MMD greetings.d")
project(sample)
add_executable(greetings
	hello.cpp
	utils.cpp
)

But then I get error

$ make
[ 33%] Building CXX object CMakeFiles/greetings.dir/hello.cpp.o
clang-14: error: no such file or directory: 'greetings.d'
make[2]: *** [CMakeFiles/greetings.dir/build.make:76: CMakeFiles/greetings.dir/hello.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/greetings.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

So, how should I update the CMAKE compile option flag ?

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -MD")

I am still learning CMake and I prefer the -MD flag.

1 Like

Aah, nice, it automatically creates a corresponding .d file:

$ find . -name *.d
./CMakeFiles/greetings.dir/hello.cpp.o.d
./CMakeFiles/greetings.dir/utils.cpp.o.d

Yes, and adding the extra utils.d was responsible for the warnings about unused input. The compiler decided it didn’tknow what to do with it, so you must have intended it for the linker. But there wasn’t a link step.