Broken header dependencies with CMake/Ninja/NVHPC (problem with -MT option)

Dear NVHPC experts,

I recently discovered that combining versions of CMake, Ninja and nvc++ leads to missed build dependencies. I reported this as a CMake issue:

but the CMake developers’ response suggests that a fix might be needed in nvc++ itself:

If the nvc++ compiler does not write the object file with -MT , that is a bug that prevents it from being used with Ninja and needs to be fixed by NVIDIA.

The details are all in the linked issue, but in essence the issue is that passing the -MT option to nvc++ stops the object file from being written:

$ nvc++ -MDmain-without-MT.d -o main-without-MT.o main.cpp
$ nvc++ -MDmain-with-MT.d -MT main-with-MT.o -o main-with-MT.o main.cpp
$ ls main-without-MT.o main-with-MT.o
ls: cannot access main-with-MT.o: No such file or directory
$ cat main-without-MT.d
main.o : main.cpp ...
$ cat main-with-MT.d
main-with-MT.o : main.cpp ...

The -MT option is documented in nvc++ -help, although it seems to be missing from the online help. I hope this is just a trivial bug that can be fixed easily.

Best, Olli

Hi Olli,

I took a look but believe the difference is due to the “-MD” flag, not “-MT”.

In looking at the docs for g++, Preprocessor Options (Using the GNU Compiler Collection (GCC)), “-MD” is the same as “-M -MF” but without the “-E” flag. “-E” will halt after preprocessing.

Our “-M” preprocessor flags have always implied -E so I wouldn’t call this a bug, just not consistent with what g++ does.

Though, I added an RFE, TPR #30078, to see if we can modify our behavior to match g++.


Hi Mat,

Thanks a lot for the quick reply, and for adding the RFE. Just as a quick follow up, I’m a little confused by:

Our “-M” preprocessor flags have always implied -E

As my experiment above seems to show that -MD has the same meaning (no -E) in both GCC and NVHPC, it’s the addition of -MT that makes it stop after preprocessing.

Could you clarify?

Thanks a lot, Olli

Apologies, you’re correct that it’s the combination of using -MD and -MT that’s the issue.

Note that the CMake issue has been closed; if I understand correctly they now invoke nvc++ twice to work around the implicit -E:

# Required since as of NVHPC 21.03 the `-MD` flag implicitly
# implies `-E` and therefore compilation and dependency generation
# can't occur in the same invocation

Presumably if the behaviour changes in future versions of NVHPC then they could take advantage of that on the CMake side.

Thanks for the help/information Mat!

Best, Olli