我试图在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'变为小写
如果我们将示例更改为
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问题。否则,你的代码就有问题了。