Due to a key rollover of our WebSSO provider there might be a short downtime of this Gitlab server on Friday 2.

waLBerlaFunctions.cmake 14.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

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} ) 
Martin Bauer's avatar
Martin Bauer committed
87
 	   if ( ${sourceFile} MATCHES "\\.(c|cpp|cu)" )
88 89 90 91
 	      set( hasSourceFiles TRUE ) 
 	   endif( ) 
 	endforeach( ) 

Martin Bauer's avatar
Martin Bauer committed
92 93 94 95 96 97
 	if ( hasSourceFiles )
 	    if ( CUDA_FOUND )
            cuda_add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${otherFiles} )
        else()
            add_library( ${moduleLibraryName} STATIC ${sourceFiles} ${otherFiles} )
        endif( CUDA_FOUND )
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
 	else( ) 
 	   add_custom_target( ${moduleLibraryName} SOURCES ${sourceFiles} ${otherFiles} )  # dummy IDE target 
 	endif( ) 

    waLBerla_register_dependency ( ${moduleName} ${ARG_DEPENDS} )

    # 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()

Martin Bauer's avatar
Martin Bauer committed
201 202 203 204 205 206 207
    if ( CUDA_FOUND )
        cuda_add_executable( ${ARG_NAME} ${sourceFiles} )
    else()
        add_executable( ${ARG_NAME} ${sourceFiles} )
    endif()

    #add_executable( ${ARG_NAME} ${sourceFiles} )
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    target_link_modules  ( ${ARG_NAME} ${ARG_DEPENDS}  )    
    target_link_libraries( ${ARG_NAME} ${SERVICE_LIBS} )

    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 )

#######################################################################################################################




#######################################################################################################################
#
# 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" )
#
267
# Symlinking works only under linux, on windows the files are copied. For in-source builds this does nothing.
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
#
#######################################################################################################################

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 )
   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 ${ARG_NAME} since the corresponding test was not built" )
      return()
   endif()  
   
   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 )
      list( INSERT  ARG_COMMAND  0  ${MPIEXEC} ${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 )
#######################################################################################################################