CMake always rebuilds the whole project even though I haven't made any changes when I use a specific compiler. How to diagnose?

CMake always rebuilds the whole project even though I haven’t made any changes when I use the mpiFCCpx. It is a clang-based compiler in supercomputer Fugaku. But gcc does not have this issue.

And this issue only occurs when I include some header files such as iostream. I wonder is it possible to find out the reason of rebuilding? How to diagnose it? Thank you!

Here is the minimal case.
trace.cc

#include <iostream>

int main() {
    return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

set(CMAKE_CXX_COMPILER /opt/FJSVxtclanga/tcsds-1.2.39/bin/mpiFCCpx)
set(CMAKE_C_COMPILER /opt/FJSVxtclanga/tcsds-1.2.39/bin/mpifccpx)

#set(CMAKE_CXX_COMPILER /bin/g++)
#set(CMAKE_C_COMPILER /bin/gcc)
project(op)

add_executable(trace trace.cc)

version:

cmake --version
cmake version 3.20.2

CMake suite maintained and supported by Kitware (kitware.com/cmake).

Ninja can tell you, why a rebuild is done: ninja -d explain

In gnumake this should do the same make --debug=w

Thank you! I manage to get the log of rebuilding by executing make --debug. There is a wired log:

Updating goal targets....
 File 'CMakeFiles/trace.dir/build' does not exist.
       File '/opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream' does not exist.
      Must remake target '/opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream'.

The correct location of iostream is /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream, the output above shows that the usr directory is missing.

And cmake --trace .. shows:

build/CMakeFiles/3.20.2/CMakeCXXCompiler.cmake(88):  set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8;/opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux;/opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/backward;/opt/FJSVxtclanga/tcsds-1.2.39/clang-comp/include/external;/opt/FJSVxtclanga/tcsds-1.2.39/clang-comp/lib64/clang/7.1.0/include;/opt/FJSVxos/devkit/aarch64/rfs/usr/include )

The first item of CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES is /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8, which does not exist at all. Is it the reason of rebuilding?

It would be much simpler to work with ninja!

What is true?

/opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream exist,
or
/opt/FJSVxos/devkit/aarch64/rfs/include/c++/8 , which does not exist at all

I wonder if mpifccpx is an other program than mpiFCCpx?

It seems you are cross compiling?
Do you use a Toolchain file?
How do you create the project?
What is the output while first build?

No, non-existent include directories are usually skipped by compilers.

CMake queries the compiler for its implicitly used include directories. If they’re wrong, then either the compiler was built incorrectly, or your installation is incomplete.

CMake 3.20 let the compiler write the .d files itself (for Makefile generators as it is for Ninja for a long time).
Please check the generated build.make for such a command line flag: -MF CMakeFiles/trace.dir/trace.cc.o.d

So if you have a wrong implicit dependency, the compiler itself wrote the wrong path into the .d file.
There may be some CMake post-processing for that file, but it’s unlikely to change the path.

To verify, you can call the compiler manually with all the flags, and check the .d as created by the compiler.

At the end it will be either an incorrectly created compiler. Or you should have installed it into another directory, because the paths are hardcoded or so.

Thank you! I will try it later.

Sorry I made a typo. This directory /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream does not exist at all. The correct path is /opt/FJSVxos/devkit/aarch64/rfs/usr/include/c++/8/iostream.

Yes, mpifccpx is a C compiler, and mpiFCCpx is a C++ compiler.

Yes, I am trying to build the code on a x86 node and the executable file will be running on a arm node. The compiler with suffix px is a cross compiler.

No, I just change the compiler at the top of the CMakeLists.txt.

The structure of the project is:

top directory
| - CMakeLists.txt
| - trace.cc
| - build/

I build the project by running:

# add compiler options to mpiFCCpx
export FCCpx_ENV='-Nclang -fopenmp -fPIC -Ofast'
export FCC_ENV='-Nclang -fopenmp -fPIC -Ofast'

cd build
cmake ..
make -j

Output:

$ cmake ..
-- The C compiler identification is Fujitsu
-- The CXX compiler identification is Clang 7.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/FJSVxtclanga/tcsds-1.2.39/bin/fccpx - skipped
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/FJSVxtclanga/tcsds-1.2.39/bin/FCCpx - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xxx/scratch/px/attach/build
$ make -j
[ 50%] Building CXX object CMakeFiles/trace.dir/trace.cc.o
[100%] Linking CXX executable trace
[100%] Built target trace

$ make -j # running make again without change codes
Consolidate compiler generated dependencies of target trace
[ 50%] Building CXX object CMakeFiles/trace.dir/trace.cc.o
[100%] Linking CXX executable trace
[100%] Built target trace

I notice that if I turn -Nclang in FCC_env off, CMake will not rebuild the project.

There is the output of ninja -d explain:

$ ninja -d explain
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iostream is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/c++config.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/c++config.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/os_defines.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/os_defines.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/cpu_defines.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/cpu_defines.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ostream of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ostream is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ios of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ios is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iosfwd of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/iosfwd is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stringfwd.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stringfwd.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/memoryfwd.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/memoryfwd.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/postypes.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/postypes.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cwchar of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cwchar is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/exception of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/exception is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/exception.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/exception.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/exception_ptr.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/exception_ptr.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/exception_defines.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/exception_defines.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/cxxabi_init_exception.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/cxxabi_init_exception.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/typeinfo of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/typeinfo is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/hash_bytes.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/hash_bytes.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/new of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/new is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/nested_exception.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/nested_exception.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/move.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/move.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/concept_check.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/concept_check.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/type_traits of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/type_traits is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/char_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/char_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_algobase.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_algobase.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/functexcept.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/functexcept.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/cpp_type_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/cpp_type_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/type_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/type_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/numeric_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/numeric_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_pair.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_pair.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_iterator_base_types.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_iterator_base_types.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_iterator_base_funcs.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_iterator_base_funcs.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/debug/assertions.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/debug/assertions.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_iterator.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_iterator.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ptr_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ptr_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/debug/debug.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/debug/debug.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/predefined_ops.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/predefined_ops.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cstdint of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cstdint is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/localefwd.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/localefwd.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/c++locale.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/c++locale.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/clocale of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/clocale is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cctype of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cctype is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ios_base.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ios_base.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/atomicity.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/atomicity.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/gthr.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/gthr.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/gthr-default.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/gthr-default.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/atomic_word.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/atomic_word.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_classes.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_classes.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/string of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/string is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/allocator.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/allocator.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/c++allocator.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/c++allocator.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/new_allocator.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/new_allocator.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ostream_insert.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ostream_insert.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/cxxabi_forced.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/cxxabi_forced.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_function.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/stl_function.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/backward/binders.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/backward/binders.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/range_access.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/range_access.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/initializer_list of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/initializer_list is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_string.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_string.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/alloc_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/alloc_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/alloc_traits.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/alloc_traits.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/string_conversions.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/ext/string_conversions.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cstdlib of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cstdlib is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/std_abs.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/std_abs.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cstdio of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cstdio is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cerrno of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cerrno is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/functional_hash.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/functional_hash.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_string.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_string.tcc is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_classes.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_classes.tcc is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/system_error of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/system_error is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/error_constants.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/error_constants.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/stdexcept of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/stdexcept is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/streambuf of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/streambuf is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/streambuf.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/streambuf.tcc is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_ios.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_ios.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_facets.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_facets.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cwctype of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/cwctype is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/ctype_base.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/ctype_base.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/streambuf_iterator.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/streambuf_iterator.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/ctype_inline.h of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/aarch64-redhat-linux/bits/ctype_inline.h is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_facets.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/locale_facets.tcc is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_ios.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/basic_ios.tcc is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ostream.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/ostream.tcc is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/istream of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/istream is dirty
ninja explain: output /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/istream.tcc of phony edge with no inputs doesn't exist
ninja explain: /opt/FJSVxos/devkit/aarch64/rfs/include/c++/8/bits/istream.tcc is dirty
ninja explain: CMakeFiles/trace.dir/trace.cc.o is dirty
ninja explain: trace is dirty
[2/2] Linking CXX executable trace

So you have proven, that the compiler writes the wrong header names into the .d file. But only if you use it in clang mode.

Before continuing, please upgrade your CMake first. Fujitsu compiler support was added in v3.21 MR5954.

Perhaps that helps, but the root cause might still be an incomplete/wrong installation/build of the compiler. Where the clang mode expects a different directory layout.
Please call the compiler manually outside of CMake and check the content of the .d file.
If the compiler writes the wrong path for iostream into the .d file, there’s nothing that CMake can do about it.

And do setup a toolchain file. That’s always needed for cross-compiling, otherwise there might be problems caused by wrong assumptions (e.g. finding a library for the host instead of the target).

I tried CMake 3.27.7 but it didn’t help. ninja -d explain still showed header files didn’t exist.

I don’t really understand how to call the compiler manually outside of CMake. Can you explain it more detailly?

I set the toolchain file, and it didn’t help.

Did you create a new build directory? Compiler settings are mostly cached.
I guess it won’t help on your problem, though. But discussing about problems in an unsupported combination is just a waste of time.

I mean, calling the compiler yourself directly in the shell. Like:
clang++ -MD -MT file.o -MF file.d -o file.o -c file.cpp
In your case it will be something like this:
/opt/FJSVxtclanga/tcsds-1.2.39/bin/mpiFCCpx -Nclang -fopenmp -fPIC -Ofast -MD -MT file.o -MF file.d -o file.o -c file.cpp
You can call ninja -v to let Ninja show you the command lines it calls.

By calling the compiler yourself, you can be sure, that the .d file is made directly by your compiler. (CMake may manipulate it in Ninja)
And if that .d file contains the wrong path, then it’s the fault of your compiler. And there’s nothing that CMake (or any other build tool) can do.

Solved by adding

--gcc-toolchain=/opt/FJSVxos/devkit/aarch64/rfs/usr/

to FCC.

Thank you for your help!