An error occurred while loading the file. Please try again.
-
Martin Bauer authoredc7852c3b
Forked from
waLBerla / waLBerla
1434 commits behind the upstream repository.
waLBerlaFunctions.cmake 16.64 KiB
include ( waLBerlaHelperFunctions )
include ( waLBerlaModuleDependencySystem )
set ( WALBERLA_GLOB_FILES *.cpp
*.c
*.h
*.cu
CACHE INTERNAL "File endings to glob for source files" )
#######################################################################################################################
#
# Creates a walberla module library
#
#
# Keywords:
# DEPENDS [required] list of modules, that this module depends on
# FILES [optional] list of all source and header files belonging to that module
# if this is not given, all source and header files in the directory are added.
# Careful: when file was added or deleted, cmake has to be run again
# EXCLUDE [optional] Files that should not be included in the module (but are located in module directory).
# This makes only sense if FILES was not specified, and all files have been added automatically.
# BUILD_ONLY_IF_FOUND Before building the module test if all libraries specified here are availbable.
# [optional] This is done using the ${arg}_FOUND variable.
# Example: waLBerla_add_module( DEPENDS someModule BUILD_ONLY_IF_FOUND pe)
# This module is only built if PE_FOUND is true.
#
#######################################################################################################################
function ( waLBerla_add_module )
set( options )
set( oneValueArgs )
set( multiValueArgs DEPENDS EXCLUDE FILES BUILD_ONLY_IF_FOUND )
cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# Module name is the directory relative to WALBERLA_MODULE_DIRS
get_current_module_name ( moduleName )
get_module_library_name ( moduleLibraryName ${moduleName} )
# Test if all required libraries are available
# this is detected using the _FOUND variable
foreach ( externalName ${ARG_BUILD_ONLY_IF_FOUND} )
string( TOUPPER ${externalName} externalNameUpper )
if ( NOT ${externalNameUpper}_FOUND )
message ( STATUS "Module ${moduleName} is not built, because ${externalName} not available" )
return()
endif()
endforeach()
# Take source files either from parameter or search all source files
file ( GLOB_RECURSE allFiles "*" ) # Find all files
if ( ARG_FILES )
foreach( sourceFile ${ARG_FILES} )
get_filename_component( sourceFile ${sourceFile} ABSOLUTE )
list( APPEND sourceFiles ${sourceFile} )
endforeach()
else()
file ( GLOB_RECURSE sourceFiles ${WALBERLA_GLOB_FILES} ) # Find all source files
endif()
# Remove exclude files from the sources
if ( ARG_EXCLUDE )
foreach ( fileToExclude ${ARG_EXCLUDE} )
get_filename_component( fileToExclude ${fileToExclude} ABSOLUTE )
list (REMOVE_ITEM sourceFiles ${fileToExclude} )
endforeach()
endif()
list_minus ( otherFiles LIST1 ${allFiles} LIST2 ${sourceFiles} )
set_source_files_properties( ${otherFiles} PROPERTIES HEADER_FILE_ONLY ON )
if ( WALBERLA_GROUP_FILES )
group_files( "Other Files" FILES ${otherFiles} )
group_files( "Source Files" FILES ${sourceFiles} )
endif ( )
# Dependency Check
check_dependencies( missingDeps additionalDeps FILES ${sourceFiles} EXPECTED_DEPS ${ARG_DEPENDS} ${moduleName} )
if ( missingDeps )
message ( WARNING "The module ${moduleName} depends on ${missingDeps} which are not listed as dependencies!" )
endif()
set( hasSourceFiles FALSE )
foreach ( sourceFile ${sourceFiles} )
if ( ${sourceFile} MATCHES "\\.(c|cpp|cu)" )
set( hasSourceFiles TRUE )
endif( )
endforeach( )
if ( hasSourceFiles )
set( generatedSourceFiles )
set( generatorSourceFiles )
handle_python_codegen(sourceFiles generatedSourceFiles generatorSourceFiles codeGenRequired ${sourceFiles})
if( NOT WALBERLA_BUILD_WITH_CODEGEN AND codeGenRequired)
message(STATUS "Skipping ${ARG_NAME} since pystencils code generation is not enabled")
return()
endif()
if ( CUDA_FOUND )
cuda_add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} ${otherFiles} )
else()
add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${generatedSourceFiles} ${generatorSourceFiles} ${otherFiles} )
endif( CUDA_FOUND )
set_source_files_properties( ${generatedSourceFiles} PROPERTIES GENERATED TRUE )
else( )
add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${generatedSourceFiles} ${otherFiles} ) # dummy IDE target
endif( )
waLBerla_register_dependency ( ${moduleName} ${ARG_DEPENDS} )
set_property( TARGET ${moduleName} PROPERTY CXX_STANDARD 14 )
# This property is needed for visual studio to group modules together
if( WALBERLA_GROUP_PROJECTS )
set_property( TARGET ${moduleLibraryName} PROPERTY FOLDER "SRC" )
endif()
# Install rule for library
get_target_property( module_type ${moduleLibraryName} TYPE )
if( ${module_type} MATCHES LIBRARY )
install ( TARGETS ${moduleLibraryName} RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib )
endif( )
# Install rule for header
install ( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
DESTINATION "walberla/${moduleName}"
FILES_MATCHING PATTERN "*.h"
PATTERN "*.in.h" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE )
# Install generated headers if necessary
if ( NOT ${CMAKE_CURRENT_BINARY_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR} )
install ( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/
DESTINATION "walberla/${moduleName}"
FILES_MATCHING PATTERN "*.h"
PATTERN "*.in.h" EXCLUDE
PATTERN "CMakeFiles" EXCLUDE )
endif()
# Report module statistics - which is later on written out to a json file
# This file is used in the doxygen documentation to display a module graph
#waLBerla_module_statistics ( FILES ${sourceFiles} DEPENDS ${ARG_DEPENDS} )
endfunction ( waLBerla_add_module )
#######################################################################################################################
#######################################################################################################################
#
# Compiles an application either from given source files, or otherwise globs all files in the current folder.
# The application is linked against all waLBerla modules that are listed after DEPENDS
#
#
# NAME [required] Name of application
# GROUP [optional] IDE group name (e.g. VS)
# DEPENDS [required] list of modules, that this application depends on
# FILES [optional] list of all source and header files belonging to that application
# if this is not given, all source and header files in the directory are added.
# Careful: when file was added or deleted, cmake has to be run again
#
# Example:
# waLBerla_compile_app ( NAME myApp DEPENDS core field lbm/boundary )
#######################################################################################################################
function ( waLBerla_add_executable )
set( options )
set( oneValueArgs NAME GROUP )
set( multiValueArgs FILES DEPENDS )
cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
if( NOT ARG_NAME )
message ( FATAL_ERROR "waLBerla_add_executable called without a NAME" )
endif()
# Skip this app, if it depends on modules that have not been built ( because they for example depend on PE)
foreach ( depMod ${ARG_DEPENDS} )
get_module_library_name ( depModLibraryName ${depMod} )
if( NOT TARGET ${depModLibraryName} )
message ( STATUS "Skipping ${ARG_NAME} since dependent module ${depMod} was not built" )
return()
endif()
endforeach()
# Take source files either from parameter or search all source files
set( sourceFiles )
if ( ARG_FILES )
foreach( sourceFile ${ARG_FILES} )
get_filename_component( sourceFile ${sourceFile} ABSOLUTE )
list( APPEND sourceFiles ${sourceFile} )
endforeach()
if ( WALBERLA_GROUP_FILES )
group_files( "Source Files" FILES ${sourceFiles} )
endif ( )
else()
file ( GLOB_RECURSE sourceFiles ${WALBERLA_GLOB_FILES} ) # Find all source files
if ( WALBERLA_GROUP_FILES )
file ( GLOB_RECURSE allFiles "*" ) # Find all files
list_minus ( otherFiles LIST1 ${allFiles} LIST2 ${sourceFiles} )
group_files( "Source Files" FILES ${sourceFiles} )
group_files( "Other Files" FILES ${otherFiles} )
endif ( )
endif()
set( generatedSourceFiles )
set( generatorSourceFiles )
handle_python_codegen(sourceFiles generatedSourceFiles generatorSourceFiles codeGenRequired ${sourceFiles})
if( NOT WALBERLA_BUILD_WITH_CODEGEN AND codeGenRequired)
message(STATUS "Skipping ${ARG_NAME} since pystencils code generation is not enabled")
return()
endif()
if ( WALBERLA_BUILD_WITH_CUDA )
cuda_add_executable( ${ARG_NAME} ${sourceFiles} ${generatedSourceFiles} )
else()
add_executable( ${ARG_NAME} ${sourceFiles} ${generatedSourceFiles} )
endif()
set_source_files_properties( ${generatedSourceFiles} PROPERTIES GENERATED TRUE )
target_link_modules ( ${ARG_NAME} ${ARG_DEPENDS} )
target_link_libraries( ${ARG_NAME} ${WALBERLA_LINK_LIBRARIES_KEYWORD} ${SERVICE_LIBS} )
set_property( TARGET ${ARG_NAME} PROPERTY CXX_STANDARD 14 )
if( WALBERLA_GROUP_PROJECTS )
if( NOT ARG_GROUP )
set( ARG_GROUP "APPS" )
endif()
set_property( TARGET ${ARG_NAME} PROPERTY FOLDER ${ARG_GROUP} )
endif()
endfunction ( waLBerla_add_executable )
#######################################################################################################################
#######################################################################################################################
#
# Function to tell CMake which C/C++/CUDA files are generated by a python file
#
# Example:
# waLBerla_python_file_generates(MyPythonCodeGenScript.py Sweep1.cpp Sweep1.h Sweep2.h Sweep2.cu)
#
#
#######################################################################################################################
function( waLBerla_python_file_generates pythonFile )
get_filename_component(pythonFileAbsolutePath ${pythonFile} ABSOLUTE)
set( "WALBERLA_CODEGEN_INFO_${pythonFileAbsolutePath}" ${ARGN}
CACHE INTERNAL "Files generated by python script ${pythonFile}" FORCE)
endfunction(waLBerla_python_file_generates)
#######################################################################################################################
#
# Adds a waLBerla module test executable.
#
#######################################################################################################################
function ( waLBerla_compile_test )
set( options )
set( oneValueArgs NAME )
set( multiValueArgs FILES DEPENDS )
cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# Module name is the directory relative to WALBERLA_MODULE_DIRS
get_current_module_name ( moduleName )
# Filename of first source file is used as name for testcase if no name was given
if( NOT ARG_NAME )
list( GET ARG_FILES 0 ARG_NAME )
get_filename_component( ARG_NAME ${ARG_NAME} NAME_WE )
endif()
waLBerla_add_executable ( NAME ${ARG_NAME} GROUP "TESTS/${moduleName}"
DEPENDS ${ARG_DEPENDS} ${moduleName} FILES ${ARG_FILES} )
endfunction ( waLBerla_compile_test )
#######################################################################################################################
#######################################################################################################################
#
# Links all files in current source dir matching a globbing expression to the build directory
#
# first parameter is glob expression
#
# Typical usage: link all parameter files in same folder as the binary was produced
# Assuming the parameter files end with prm, write this to your CMakeLists in the
# app or test folder:
# waLBerla_link_files_to_builddir( "*.prm" )
#
# Symlinking works only under linux, on windows the files are copied. For in-source builds this does nothing.
#
#######################################################################################################################
function ( waLBerla_link_files_to_builddir globExpression )
# don't need links for in-source builds
if( CMAKE_CURRENT_SOURCE_DIR STREQUAL "${CMAKE_CURRENT_BINARY_DIR}" )
return()
endif()
file( GLOB filesToLink RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${globExpression} )
foreach( f ${filesToLink} )
if( CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows" )
configure_file( ${f} ${f} COPYONLY )
else()
execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink
${CMAKE_CURRENT_SOURCE_DIR}/${f}
${CMAKE_CURRENT_BINARY_DIR}/${f} )
endif()
endforeach()
endfunction ( waLBerla_link_files_to_builddir )
#######################################################################################################################
#
# Adds an executable to CTest.
#
# Wrapper around add_test, that handles test labels and parallel runs
# Adds the module name as test label, plus optional user defined labels.
#
# NAME [required] Name of test
# PROCESSES [optional] Number of MPI processes, that are used to start this test.
# If walberla is built without MPI, and PROCESSES > 1, the test is not added
# Defaults to 1
# COMMAND [optional] The command that is executed. Use this to start with parameter files or other
# command line options.
# Defaults to $<TARGET_FILE:${NAME}> (for this syntax see cmake documentation of add_test )
# LABELS [optional] Additional test labels.
#
#######################################################################################################################
function ( waLBerla_execute_test )
set( options NO_MODULE_LABEL )
set( oneValueArgs NAME PROCESSES )
set( multiValueArgs COMMAND LABELS CONFIGURATIONS DEPENDS_ON_TARGETS )
cmake_parse_arguments( ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
if( NOT ARG_NAME )
message ( FATAL_ERROR "waLBerla_execute_test called without a NAME" )
endif()
if( NOT ARG_COMMAND AND NOT TARGET ${ARG_NAME} )
message ( STATUS "Skipping test ${ARG_NAME} since the corresponding target is not built" )
return()
endif()
foreach( dependency_target ${ARG_DEPENDS_ON_TARGETS} )
if( NOT TARGET ${dependency_target} )
message ( STATUS "Skipping test ${ARG_NAME} since the target ${dependency_target} is not built" )
return()
endif()
endforeach( dependency_target )
if( NOT ARG_PROCESSES )
set ( numProcesses 1 )
else()
set ( numProcesses ${ARG_PROCESSES} )
endif()
if ( NOT ARG_COMMAND )
set ( ARG_COMMAND $<TARGET_FILE:${ARG_NAME}> )
endif()
if( WALBERLA_BUILD_WITH_MPI )
if( CMAKE_VERSION VERSION_LESS 3.10.0 )
set ( MPIEXEC_EXECUTABLE ${MPIEXEC} )
endif()
list( INSERT ARG_COMMAND 0 ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${numProcesses} ${MPIEXEC_PREFLAGS} )
elseif( numProcesses GREATER 1 )
return()
endif()
if( ARG_CONFIGURATIONS )
add_test( NAME ${ARG_NAME} ${ARG_UNPARSED_ARGUMENTS} COMMAND ${ARG_COMMAND} CONFIGURATIONS ${ARG_CONFIGURATIONS} )
else()
add_test( NAME ${ARG_NAME} ${ARG_UNPARSED_ARGUMENTS} COMMAND ${ARG_COMMAND} )
endif()
if( ARG_NO_MODULE_LABEL )
set_tests_properties ( ${ARG_NAME} PROPERTIES LABELS "${ARG_LABELS}" )
else()
get_current_module_name ( moduleName )
set_tests_properties ( ${ARG_NAME} PROPERTIES LABELS "${moduleName} ${ARG_LABELS}" )
endif()
set_tests_properties ( ${ARG_NAME} PROPERTIES PROCESSORS ${numProcesses} )
endfunction ( waLBerla_execute_test )
#######################################################################################################################