Search code examples
cmakefortran

Add a compilation option right before the filename of the source with cmake


I have received a code written in Fortran with files named using extension .f95. I know that this extension is not recommended, one should only use .f for fixed form Fortran and .f90 for free form Fortran, but this is the way I received the code.

I have prepared some cmake files in order to compile it. It works well when I use gfortran but it does not when I use Intel Fortran 2021. It seems that Intel Fortran does not accept .f95 extensions by default.

For example, the following does not work:

ifort mySrc.f95 -c

But one can force ifort to accept this .f95 extension by typing:

ifort -free -Tf mySrc.f95 -c

This is a simplified CMakeLists.txt I have prepared for the project:

cmake_minimum_required(VERSION 3.12)

project (Test VERSION 1.0 
        DESCRIPTION "CMAKE files to compile test"
        LANGUAGES Fortran)

if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
  if(CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "20")
      message(FATAL_ERROR "Intel Fortran Compiler 20 or newer required")
  endif()
  set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all")
  set (CMAKE_Fortran_FLAGS_RELEASE "-O2")
  set (CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g")
  set (CMAKE_Fortran_FLAGS_DEBUG "-g")
endif()

file(GLOB FILES_SRC CONFIGURE_DEPENDS "*.f95")

set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod/)

add_executable(MYCODE ${FILES_SRC})

set_target_properties(MYCODE
        PROPERTIES Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR})

set_property(TARGET MYCODE PROPERTY LINKER_LANGUAGE Fortran)

install(TARGETS MYCODE
        RUNTIME DESTINATION bin 
        ARCHIVE DESTINATION lib 
        LIBRARY DESTINATION lib 
        )   

install(DIRECTORY ${LIB_MOD_DIR} DESTINATION include)

I am trying to add these -free and -Tf options to my cmake scripts, but these options must go right before the filename of the file to compile. I have found this link where they mention that this can be achieved my modifying file /Modules/Platform/Linux-Intel-Fortran.cmake. However, I do not have privileges to modify that file. I have tried adding the following to my CMakeLists.txt right after the endif():

SET(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> -o <OBJECT> <DEFINES> <FLAGS> -c -Tf <SOURCE>")

but I keep getting errors. Is it possible to implement this using the CMakeLists.txt file? Thanks in advance.


Solution

  • When I was adding the following option in the CMakeLists.txt file:

    SET(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> -o <OBJECT> <DEFINES> <FLAGS> -c -Tf <SOURCE>")

    I forgot to add -free to indicate that the files are in free form format. By default -Tf will treat files as fixed-form Fortran. That was why compilation was failing. So using CMAKE_Fortran_COMPILE_OBJECT was the proper way to go to make ifort accept f95 files.

    So now I am able to use cmake with ifort and f95 files. The CMakeLists.txt section for Intel Fortran is the following:

    if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
      if(CMAKE_Fortran_COMPILER_VERSION VERSION_LESS "20")
          message(FATAL_ERROR "Intel Fortran Compiler 20 or newer required")
      endif()
      set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all")
      set (CMAKE_Fortran_FLAGS_RELEASE "-O2")
      set (CMAKE_Fortran_FLAGS_RELWITHDEBINFO "-O2 -g")
      set (CMAKE_Fortran_FLAGS_DEBUG "-g")
      set (CMAKE_Fortran_COMPILE_OBJECT     "<CMAKE_Fortran_COMPILER> -o <OBJECT> <DEFINES> <FLAGS> -c -free -Tf <SOURCE>")
    endif()
    

    Thank you both for your suggestions.