CMake LINKER_LANGUAGE with Fortran and C++

CMake target property LINKER_LANGUAGE is used by CMake to determine the language of the linker when linking a target. When this target property is not set, CMake uses a heuristic to determine the linker language based on the source files and the compiler being used. LINKER_LANGUAGE is important for mixed-language projects, such as those that use both Fortran and C++. However, CMake’s heuristic for determining the linker language can sometimes fail, especially with certain compilers like Intel oneAPI or NVHPC.

This is the general CMake script we use on our Fortran and C++ mixed projects:

set(linker_lang)
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_GENERATOR STREQUAL "Unix Makefiles")
  # otherwise failed to link since -lc++ is missing
  set(linker_lang CXX)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM|NVHPC" AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
  # IntelLLVM|NVHPC need Fortran
  set(linker_lang Fortran)
endif()
if(linker_lang)
  message(STATUS "Setting linker language to ${linker_lang} for certain targets")
endif()

Then for individual mixed Fortran and C++ targets, we set the LINKER_LANGUAGE property explicitly:

set_target_properties(mixed_target PROPERTIES LINKER_LANGUAGE ${linker_lang})