diff --git a/cmake/AddPreprocessTarget.cmake b/cmake/AddPreprocessTarget.cmake new file mode 100644 index 000000000..203a8e3be --- /dev/null +++ b/cmake/AddPreprocessTarget.cmake @@ -0,0 +1,76 @@ +# AddPreprocessTarget.cmake +# CMake module to add a target for preprocessing Fortran source files + +# Function to add a preprocess target to a CMake project +# Usage: add_preprocess_target(TARGET_NAME SOURCE_FILES [EXCLUDE_PATTERN pattern]) +function(add_preprocess_target TARGET_NAME SOURCE_FILES) + # Parse additional arguments + set(options "") + set(oneValueArgs EXCLUDE_PATTERN) + set(multiValueArgs "") + cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Create a list of source files to preprocess + set(preprocess_sources ${SOURCE_FILES}) + + # If an exclude pattern is provided, filter out matching files + if(DEFINED ARG_EXCLUDE_PATTERN) + list(FILTER preprocess_sources EXCLUDE REGEX "${ARG_EXCLUDE_PATTERN}") + endif() + + # Add custom target for preprocessing + add_custom_target(${TARGET_NAME} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/preprocessed + COMMAND ${CMAKE_COMMAND} -E echo "Preprocessing Fortran sources to ${CMAKE_BINARY_DIR}/preprocessed" + COMMENT "Preprocessing Fortran source files" + ) + + # Get all compile definitions from the main target + get_target_property(TARGET_COMPILE_DEFS ${PROJECT_NAME} COMPILE_DEFINITIONS) + + # Get all compile options from the main target + get_target_property(TARGET_COMPILE_OPTIONS ${PROJECT_NAME} COMPILE_OPTIONS) + + # Add custom command for each Fortran source file + foreach(source_file ${preprocess_sources}) + get_filename_component(fname ${source_file} NAME) + + # Build the command with proper arguments based on compiler type + if(${CMAKE_Fortran_COMPILER_ID} STREQUAL "GNU") + set(preprocess_cmd ${CMAKE_Fortran_COMPILER} -cpp -E) + elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "Intel" OR ${CMAKE_Fortran_COMPILER_ID} STREQUAL "IntelLLVM") + set(preprocess_cmd ${CMAKE_Fortran_COMPILER} -fpp -E) + elseif(${CMAKE_Fortran_COMPILER_ID} STREQUAL "NVHPC" OR ${CMAKE_Fortran_COMPILER_ID} STREQUAL "PGI") + set(preprocess_cmd ${CMAKE_Fortran_COMPILER} -Mpreprocess -E) + else() + # Default to GNU syntax + set(preprocess_cmd ${CMAKE_Fortran_COMPILER} -cpp -E) + endif() + + # Add compile definitions + if(TARGET_COMPILE_DEFS) + foreach(def ${TARGET_COMPILE_DEFS}) + list(APPEND preprocess_cmd -D${def}) + endforeach() + endif() + + # Add compile options (filtering out ones that might cause issues) + if(TARGET_COMPILE_OPTIONS) + foreach(opt ${TARGET_COMPILE_OPTIONS}) + if(NOT opt MATCHES "-O[0-3]" AND NOT opt MATCHES "-g" AND NOT opt MATCHES "-march" AND NOT opt MATCHES "-mtune") + list(APPEND preprocess_cmd ${opt}) + endif() + endforeach() + endif() + + # Add source file and output file + list(APPEND preprocess_cmd ${source_file} -o ${CMAKE_BINARY_DIR}/preprocessed/${fname}) + + add_custom_command( + TARGET ${TARGET_NAME} + COMMAND ${preprocess_cmd} + DEPENDS ${source_file} + ) + endforeach() + +endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 083bab1ff..81ab80850 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -441,6 +441,17 @@ get_target_property(FLAGS ${PROJECT_NAME} COMPILE_OPTIONS) message(STATUS " --> Final Compile options for ${PROJECT_NAME}: ${FLAGS}") +# Include the AddPreprocessTarget module +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/AddPreprocessTarget.cmake) + +# Add preprocess target to output preprocessed source files +# Usage: cd build; cmake --build . --target preprocess-sources +add_preprocess_target( + preprocess-sources + "${sources_Fortran}" + EXCLUDE_PATTERN "fesom_version_info-generated.F90" +) + ### Export and installation fesom_export(TARGETS ${PROJECT_NAME} fesom.x) diff --git a/src/gen_modules_partitioning.F90 b/src/gen_modules_partitioning.F90 index 5ea2938d0..d8aebddf3 100644 --- a/src/gen_modules_partitioning.F90 +++ b/src/gen_modules_partitioning.F90 @@ -127,7 +127,7 @@ subroutine par_ex(COMM, mype, abort) ! finalizes MPI call MPI_Finalize(error) endif -#else ! +#else ! TODO logic below is convoluted, COMM that is passed should be used for MPI_ABORT ! changes are easy but need to be tested with coupled configurations ! From here on the two coupled options