@@ -491,7 +491,32 @@ function(MFC_SETUP_TARGET)
491491 # Here we need to split into "library" and "executable" to perform IPO on the NVIDIA compiler.
492492 # A little hacky, but it *is* an edge-case for *one* compiler.
493493 if (NVHPC_USE_TWO_PASS_IPO AND NOT (MFC_OpenMP AND ARGS_OpenMP))
494+ # nvfortran -Mextract does not produce .o files, only inline library
495+ # data. An OBJECT library with -Mextract causes CMake to rebuild
496+ # everything on every build because the expected .o outputs never
497+ # exist. We use a wrapper script as RULE_LAUNCH_COMPILE that runs
498+ # the compiler and then touches the expected .o output file.
499+ set (_ipo_wrapper "${CMAKE_BINARY_DIR } /${ARGS_TARGET} _extract_wrapper.sh" )
500+ file (WRITE "${_ipo_wrapper} " [=[ #!/bin/sh
501+ # Find the -o argument (the object file CMake expects)
502+ out=
503+ prev=
504+ for arg do
505+ if [ "$prev" = "-o" ]; then out="$arg"; break; fi
506+ prev="$arg"
507+ done
508+ # Run the compiler; propagate its exit status on failure
509+ "$@"
510+ status=$?
511+ [ "$status" -eq 0 ] || exit "$status"
512+ # Touch the .o so CMake's dependency tracking sees it
513+ [ -n "$out" ] && touch "$out"
514+ exit 0
515+ ]=] )
516+ file (CHMOD "${_ipo_wrapper} " PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE )
494517 add_library (${ARGS_TARGET} _lib OBJECT ${ARGS_SOURCES} )
518+ set_target_properties (${ARGS_TARGET} _lib PROPERTIES
519+ RULE_LAUNCH_COMPILE "${_ipo_wrapper} " )
495520 target_compile_options (${ARGS_TARGET} _lib PRIVATE
496521 $<$<COMPILE_LANGUAGE :Fortran >:-Mextract =lib :${ARGS_TARGET} _lib >
497522 $<$<COMPILE_LANGUAGE :Fortran >:-Minline >
0 commit comments