[CMake] CMake and Preprocessing
Michael Wild
themiwi at gmail.com
Tue Nov 17 15:55:39 EST 2009
On 17. Nov, 2009, at 19:13 , Anastasia Shchupak wrote:
> Hello,
> I'm porting multiplatform fortran project build system to CMake. Due
> to OpenMP code, I need to use FPP preprocessor always (before
> compiling by any compiler, because some fortran compilers use just
> CPP as preprocessor, that does not support OpenMP).
> Is there a common solution using CMake to split preprocessing from
> compiling and set up a preprocessor that differs from that is
> incorporated into a compiler?
> Thanks.
> Anastasia.
Hi
Not that I'd know of. However, what you can do is define custom
function which takes a list of files and generate rules to feed them
through FPP and write them to the binary tree. The resulting files are
returned in a list which you can then pass to ADD_LIBRARY or
ADD_EXECUTABLE.
As an example, the library function might look something like this (I
don't have FPP, so you might need to adjust the ADD_CUSTOM_COMMAND):
# find FPP
find_program(FPP_EXECUTABLE fpp)
if(NOT FPP_EXECUTABLE)
message(SEND_ERROR "Could not find the Fortran Preprocessor FPP")
endif()
# - Function to pass Fortran files through FPP
# PREPROCESS_FORTRAN(outputfiles inputfile ...)
# The function determines if the file is a Fortran file based on
# its extension. This implementation feeds .f, .F, .f90, .F90, .f95
and .F95
# through the preprocessor.
function(preprocess_fortran outvar)
# determine include directories
get_directory_property(incdirs INCLUDE_DIRECTORIES)
set(incflags)
foreach(i ${incdirs})
set(incflags "${incflags} -I${i}")
endforeach()
# set up defines (not configuration specific)
get_directory_property(defines COMPILE_DEFINITIONS)
set(defflags)
foreach(d ${defines})
set(defflags "${defflags} -D$d")
endforeach()
# loop over all arguments
set(srcs)
foreach(f ${ARGN})
# is it a Fortran file?
if(f MATCHES "\\.[Ff](9[05])?")
message(STATUS "Got fortran file: ${f}")
# construct output filename
if(NOT IS_ABSOLUTE "${f}")
get_filename_component(f "${f}" ABSOLUTE)
endif()
file(RELATIVE_PATH r "${CMAKE_CURRENT_SOURCE_DIR}" "${f}")
get_filename_component(e "${r}" EXT)
get_filename_component(n "${r}" NAME_WE)
get_filename_component(p "${r}" PATH)
set(of "${CMAKE_CURRENT_BINARY_DIR}/${p}${n}_fpp${e}")
message(STATUS "Output name: ${of}")
# preprocess the thing
add_custom_command(OUTPUT "${of}"
COMMAND ${FPP_EXECUTABLE} ${incflags} "${defflags}" "${f}" "$
{of}"
IMPLICIT_DEPENDS Fortran "${f}"
COMMENT "Preprocessing ${f}"
VERBATIM
)
list(APPEND srcs "${of}")
else()
list(APPEND srcs "${f}")
endif()
endforeach()
# return the (preprocessed) sources
set(${outvar} "${srcs}" PARENT_SCOPE)
endfunction()
All of this is, of course, untested but should give you an idea.
HTH
Michael
More information about the CMake
mailing list