【问题标题】:fortran defined macro ignored with cmakecmake 忽略了 fortran 定义的宏
【发布时间】:2021-09-23 04:33:07
【问题描述】:

我正在尝试在 Fortran 文件中创建一个新宏。这样的文件是一个更大的项目中的许多文件之一。它是通过 CMake 文件和 gfortran 编译的。

为了简单起见,我只是举了一个简单的例子:

#define hello call

module SIO_ncDimBounds_mod

  use SIO_ncParams_mod, only: MAX_DIMLEN_NAME
  ...
  logical, parameter :: ISDEBUG = .false.

  hello  -> not recognized as Macro

编译时会被忽略,因此会引发错误:

../soulio/src/ncDimBounds_mod.F90:34:2:

   34 |   hello
      |  1
Error: Unclassifiable statement at (1)

据我了解,大写文件扩展名应该足以执行预处理器。我还检查了“-cpp”标志是否已启用。我仔细检查了详细模式以确保它已启用:

[ 22%] Building Fortran object src/CMakeFiles/soulio_lib.dir/ncDimBounds_mod.F90.o
cd ../soulio/build/src && /usr/bin/gfortran -DENABLE_MPI -I../projects/soulio/src/soulshared_lib -I../soulio/extern/Library/include -I/usr/lib/x86_64-linux-gnu/openmpi/include -I/usr/lib/x86_64-linux-gnu/openmpi/lib  -ffree-form -std=f2008 -fimplicit-none -cpp -g -fbounds-check -pedantic -ffpe-trap=zero,invalid,overflow,underflow -O0 -Wall -fcheck=all -fbacktrace -Wextra --coverage -fprofile-arcs -ftest-coverage -J../../lib   -c ../soulio/src/ncDimBounds_mod.F90 -o CMakeFiles/soulio_lib.dir/ncDimBounds_mod.F90.o

我还包括 CMakeFile:

cmake_minimum_required(VERSION 3.9)

project(soulio)
enable_language(Fortran)

find_program(FYPP fypp)
if(NOT FYPP)
  message(FATAL_ERROR "Preprocessor fypp could not be found")
endif()


# custom compiler flags
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
    set(dialect "-ffree-form -std=f2008 -fimplicit-none -cpp")
    set(debugMode "-fbounds-check -pedantic -ffpe-trap=zero,invalid,overflow,underflow -O0 -Wall -fcheck=all -fbacktrace -Wextra")
    set(optimizedMode "-ftree-vectorize" ) 
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
    set(dialect "-stand f08 -free -implicitnone")
    set(debugMode "-check bounds")
    set(optimizedMode "-O3 -xHost")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES "PGI")
    set(dialect "-Mfreeform -Mdclchk -Mstandard -Mallocatable=03")
    set(debugMode "-C")
    set(optimizedMode "")
endif()

set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} ${optimizedMode}")
set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${debugMode}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${dialect}")

# Place lib and binary files
# dynamic libraries
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)

# static library
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) 

# target files
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

# Have the .mod files placed in the lib folder
SET(LIB ${CMAKE_SOURCE_DIR}/lib)
SET(CMAKE_Fortran_MODULE_DIRECTORY ${LIB})

# include cmake modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
include(soulioUtils)

message(status ${CMAKE_SOURCE_DIR})

# call for netcdf library
if (NOT HAS_SOULSM)
  set (NETCDF_C "YES")
  set (NETCDF_F90 "YES")
  set (NETCDF_INCLUDES ${CMAKE_SOURCE_DIR}/extern/Library/include)
  set (NETCDF_INCLUDES_C ${CMAKE_SOURCE_DIR}/extern/Library/include)
  set (NETCDF_INCLUDES_F77 ${CMAKE_SOURCE_DIR}/extern/Library/include)
  set (NETCDF_INCLUDES_F90 ${CMAKE_SOURCE_DIR}/extern/Library/include)
  set (NETCDF_INCLUDES_CXX ${CMAKE_SOURCE_DIR}/extern/Library/include)
  set (NETCDF_LIBRARIES_F77 ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdff.so)
  set (NETCDF_LIBRARIES_F90 ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdff.so)
  set (NETCDF_LIBRARIES_C ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdf.so)
  set (NETCDF_LIBRARIES ${CMAKE_SOURCE_DIR}/extern/Library/lib/libnetcdf.so)

  find_package (NetCDF REQUIRED)
endif()


if (ENABLE_MPI)
  find_package (MPI REQUIRED)
  add_definitions(-DENABLE_MPI)
endif()

message(STATUS "Run: ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS")

if(BUILD_TESTING)
  enable_testing()
  SET( CMAKE_BUILD_TYPE Debug )

  include( cmake/CodeCoverage.cmake )
  SET(coverageMode "--coverage -fprofile-arcs -ftest-coverage")
  set(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} ${coverageMode}")

  add_subdirectory(tests)
endif()

if (NOT HAS_SOULSM)
  add_subdirectory(soulshared)
endif()
add_subdirectory(src)

我对一个带有大写扩展名的 fortran 文件进行了一个简单而独立的测试,正如预期的那样,它可以工作。

为什么宏没有被 CMake 替换?在我看来,它没有被调用的预处理器。

编辑: 'hello' 改为小写

【问题讨论】:

  • 在你的例子中,定义是小写的,而用法是大写的,当两者有相同的大小写时会发生什么?
  • 我将问题编辑为“你好”小写。还是一样的问题
  • 检查link 中的答案是否有帮助。
  • @NalinRanjan 我试过了,效果和详述一样。
  • 如果 hello 被定义为 call,而你只是在一行中单独使用 hello,那么这将转换为 call 自己,这是一个错误。

标签: cmake fortran


【解决方案1】:

如果我们把例子改为

subroutine silly()
    print *, 'It works'
    return
end subroutine silly

#define hello call

program main
    hello silly
    stop
end program main

并使用构建

gfortran -cpp macro.f90

这构建没有任何问题。如果我自己只有hello,那么我会收到语法错误。

首先,确保您的程序有效。 call 本身会产生错误。你需要call 一些东西。

您可以尝试在没有 cmake 的情况下进行构建吗?如果它在没有 cmake 的情况下工作并且不能与 cmake 一起工作,那么这是一个 cmake 问题。否则,您的代码就有问题。

【讨论】:

    猜你喜欢
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多