#****************************************************************************** # # MantaFlow fluid solver framework # # Copyright 2011-2015 Tobias Pfaff, Nils Thuerey # # This program is free software, distributed under the terms of the # GNU General Public License (GPL) # http://www.gnu.org/licenses # #****************************************************************************** project (MantaFlow) cmake_minimum_required(VERSION 2.8) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/source/cmake/") SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) SET(VERBOSE 1) SET(MANTAVERSION "0.10a") #****************************************************************************** # Default paths # - CMake's path finder is completely useless for Qt5 + Python on Win64 # - allow override from command line on OsX, eg use "cmake .. -DCMAKE_PREFIX_PATH=/Users/someone/qt5.2.1/5.2.1/clang_64/ IF(WIN32) SET(WIN_QT_PATH "C:/Qt/5.5/msvc2013_64_opengl") # qt5/win64 SET(WIN_PYTHON_PATH "C:/Python34") SET(WIN_PYTHON_VERSION "34") SET(CMAKE_LIBRARY_PATH "C:/Program Files (x86)/Windows Kits/8.0/Lib/win8/um/x64") SET(CMAKE_PREFIX_PATH ${WIN_QT_PATH}) ENDIF() IF(APPLE) IF(NOT CMAKE_PREFIX_PATH) SET(CMAKE_PREFIX_PATH "/usr/local/Cellar/qt5/5.5/") # mac/homebrew #SET(CMAKE_PREFIX_PATH "/home/myname/qt/5.5/clang_64") # other... ENDIF() ENDIF() #****************************************************************************** # setup default params IF(NOT CMAKE_BUILD_TYPE) SET(CMAKE_BUILD_TYPE "Release") ELSE() MESSAGE("Build-type: '${CMAKE_BUILD_TYPE}'") ENDIF() # compilation versions OPTION(DEBUG "Enable debug compilation" OFF) OPTION(GUI "Compile with GUI (requires QT)" OFF) OPTION(TBB "Use multi-thread kernels using Intels TBB" OFF) OPTION(OPENMP "Use multi-thread kernels using OpenMP" OFF) OPTION(PREPDEBUG "Debug generated files" OFF) # This will beautify generated files, and link to them for compiler errors instead of the original sources OPTION(DOUBLEPRECISION "Compile with double floating point precision" OFF) # CUDA is deprecated, and not tested - enable at own risk... (needs cmake version >2.8) #OPTION(CUDA "Compile with CUDA plugins" OFF) # special option to compile manta as library, disables python glue code (while trying to keep as much of the rest as possible) OPTION(NOPYTHON "Compile without python support (limited functionality!)" OFF) #check consistency of MT options SET(MT OFF) SET(MT_TYPE "NONE") if (TBB) SET (MT_TYPE "TBB") SET (MT ON) endif() if (OPENMP) SET (MT_TYPE "OPENMP") SET (MT ON) endif() if (TBB AND OPENMP) message(FATAL_ERROR "Cannot activate both OPENMP and TBB") endif() # make sure debug settings match... IF(NOT DEBUG) IF(${CMAKE_BUILD_TYPE} STREQUAL "Debug") SET(DEBUG 1) ENDIF() ENDIF() IF(DEBUG) SET(CMAKE_BUILD_TYPE "Debug") add_definitions ( -DDEBUG=1 ) ENDIF() MESSAGE(STATUS "") MESSAGE(STATUS "Options - " " -DDEBUG='${DEBUG}' " " -DGUI='${GUI}' " " -DTBB='${TBB}' " " -DOPENMP='${OPENMP}' " " -DPREPDEBUG='${PREPDEBUG}' " " -DDOUBLEPRECISION='${DOUBLEPRECISION}' " ) # " -DCUDA='${CUDA}' " MESSAGE(STATUS "Multithreading type : ${MT_TYPE}") MESSAGE(STATUS "") #****************************************************************************** # Pre-processor # compile prep SET(SOURCES source/preprocessor/main.cpp source/preprocessor/code.cpp source/preprocessor/tokenize.cpp source/preprocessor/parse.cpp source/preprocessor/util.cpp source/preprocessor/merge.cpp source/preprocessor/codegen_python.cpp source/preprocessor/codegen_kernel.cpp ) add_executable(prep ${SOURCES}) if (NOT WIN32) set_target_properties(prep PROPERTIES COMPILE_FLAGS "-Wall -O2") endif() #****************************************************************************** # Setup main project SET(F_LIBS "" ) SET(F_LIB_PATHS) SET(F_LINKADD "") # additional linker flags, not a list set(PP_PATH "pp") SET(SILENT_SOURCES) # need pre-processing SET(PP_SOURCES source/general.cpp source/fluidsolver.cpp source/conjugategrad.cpp source/grid.cpp source/grid4d.cpp source/levelset.cpp source/fastmarch.cpp source/shapes.cpp source/mesh.cpp source/particle.cpp source/movingobs.cpp source/fileio.cpp source/noisefield.cpp source/kernel.cpp source/vortexsheet.cpp source/vortexpart.cpp source/turbulencepart.cpp source/timing.cpp source/edgecollapse.cpp source/plugin/advection.cpp source/plugin/extforces.cpp source/plugin/flip.cpp source/plugin/fire.cpp source/plugin/kepsilon.cpp source/plugin/initplugins.cpp source/plugin/meshplugins.cpp source/plugin/optflow4d.cpp source/plugin/pressure.cpp source/plugin/vortexplugins.cpp source/plugin/waveletturbulence.cpp source/plugin/waves.cpp source/python/defines.py source/test.cpp ) SET(PP_HEADERS source/general.h source/commonkernels.h source/conjugategrad.h source/fastmarch.h source/fluidsolver.h source/grid.h source/grid4d.h source/mesh.h source/particle.h source/levelset.h source/shapes.h source/noisefield.h source/vortexsheet.h source/kernel.h source/timing.h source/movingobs.h source/fileio.h source/edgecollapse.h source/vortexpart.h source/turbulencepart.h ) # no pre-processing needed set(NOPP_SOURCES source/pwrapper/pymain.cpp source/pwrapper/pclass.cpp source/pwrapper/pvec3.cpp source/pwrapper/pconvert.cpp source/pwrapper/registry.cpp source/util/vectorbase.cpp source/util/vector4d.cpp source/util/simpleimage.cpp ) SET(NOPP_HEADERS source/pwrapper/pythonInclude.h source/pwrapper/pclass.h source/pwrapper/registry.h source/pwrapper/pconvert.h source/util/integrator.h source/util/vectorbase.h source/util/vector4d.h source/util/quaternion.h source/util/interpol.h source/util/mcubes.h source/util/randomstream.h source/util/solvana.h ) if (GUI) # need QT preprocessor set(QT_HEADERS source/gui/mainwindow.h source/gui/glwidget.h source/gui/painter.h source/gui/meshpainter.h source/gui/qtmain.h source/gui/customctrl.h source/gui/particlepainter.h ) set(QT_SOURCES source/gui/customctrl.cpp source/gui/mainwindow.cpp source/gui/glwidget.cpp source/gui/customctrl.cpp source/gui/painter.cpp source/gui/meshpainter.cpp source/gui/particlepainter.cpp source/gui/qtmain.cpp ) list(APPEND PP_SOURCES ${QT_SOURCES}) list(APPEND PP_HEADERS ${QT_HEADERS}) endif() # CUDA sources , deprectated if (CUDA) list(APPEND PP_SOURCES source/cuda/meshtools.cu source/cuda/buoyancy.cu source/cuda/particle.cu ) endif() # include dirs SET(INCLUDE_PATHS ${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/source ${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/source/util source/pwrapper source/cuda source/util ) # reduced version without python if (NOPYTHON) # replace some of the source lists set(NOPP_SOURCES source/nopython/pclass.cpp source/util/vectorbase.cpp source/util/simpleimage.cpp ) # update paths to use nopython versions SET(INCLUDE_PATHS ${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/source ${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/source/util source/nopython source/cuda source/util ) add_definitions( -DNOPYTHON=1 ) endif() # Multithreading if(MT) add_definitions( -DMT=1 ) if(TBB) # Intel TBB add_definitions( -DTBB=1 ) if (DEBUG) add_definitions( -DTBB_USE_DEBUG=1 ) list(APPEND F_LIBS tbb) else() list(APPEND F_LIBS tbb) endif() if (WIN32) find_package(TBB REQUIRED) list(APPEND INCLUDE_PATHS ${TBB_INCLUDE_DIRS}) list(APPEND F_LIB_PATHS ${TBB_LIBRARY_DIRS}) elseif(APPLE) find_package(TBB REQUIRED) list(APPEND INCLUDE_PATHS ${TBB_INCLUDE_DIRS}) list(APPEND F_LIB_PATHS ${TBB_LIBRARY_DIRS}) endif() else() # OpenMP add_definitions( -DOPENMP=1 ) if (WIN32) add_definitions( /openmp) else() add_definitions(-fopenmp) SET(F_LINKADD "${F_LINKADD} -fopenmp ") endif() endif() endif() #****************************************************************************** # add a target to generate API documentation with Doxygen find_package(Doxygen) if(DOXYGEN_FOUND) set(DX_PATH "doxy") foreach(it ${PP_SOURCES} ${PP_HEADERS} ${NOPP_SOURCES} ${NOPP_HEADERS}) get_filename_component(CURPATH ${it} PATH) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${DX_PATH}/${CURPATH}") set(CURDX "${DX_PATH}/${it}") string(REPLACE "/" "_" TGT ${CURDX}) string(REPLACE "source/" "" INFILE ${it}) add_custom_command(OUTPUT ${TGT} COMMAND prep docgen "0" ${MT_TYPE} "${CMAKE_CURRENT_SOURCE_DIR}/source/" "${INFILE}" "${CURDX}" DEPENDS prep IMPLICIT_DEPENDS CXX ${it} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) list(APPEND TGLIST ${TGT}) endforeach(it) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${TGLIST} COMMENT "Generating API documentation with Doxygen" VERBATIM ) endif(DOXYGEN_FOUND) #****************************************************************************** # Link libraries # enforce certain python version, if necessary set(PYTHON_FORCE_VERSION) # use any... #set(PYTHON_FORCE_VERSION 3.5) # uncomment to force specific one # Python set(Python_ADDITIONAL_VERSIONS 3.4) find_package(PythonLibs ${PYTHON_FORCE_VERSION} QUIET) if((NOT PYTHONLIBS_FOUND) AND WIN32) set(PYTHON_INCLUDE_DIR "${WIN_PYTHON_PATH}/include") set(PYTHON_LIBRARY "${WIN_PYTHON_PATH}/libs/python${WIN_PYTHON_VERSION}.lib") endif() find_package(PythonLibs ${PYTHON_FORCE_VERSION} REQUIRED) list(APPEND INCLUDE_PATHS ${PYTHON_INCLUDE_DIRS}) list(APPEND F_LIBS ${PYTHON_LIBRARIES}) # Z compression if (1) # default: build from own sources set(ZLIB_SRC adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c inflate.c infback.c inftrees.c inffast.c trees.c uncompr.c zutil.c) foreach(it ${ZLIB_SRC}) list(APPEND SILENT_SOURCES dependencies/zlib-1.2.8/${it}) endforeach(it) set(ZLIB_ADDFLAGS "-Dverbose=-1") if(NOT WIN32) set(ZLIB_ADDFLAGS "-Wno-implicit-function-declaration -Dverbose=-1") endif() set_source_files_properties(${SILENT_SOURCES} PROPERTIES COMPILE_FLAGS "${ZLIB_ADDFLAGS}") list(APPEND INCLUDE_PATHS dependencies/zlib-1.2.8) endif() if (0) # try to locate and use system libs include(FindZLIB) list(APPEND INCLUDE_PATHS ${ZLIB_INCLUDE_DIR}) list(APPEND F_LIBS ${ZLIB_LIBRARIES}) endif() if (0) # disable add_definitions(-DNO_ZLIB=1) endif() # CUDA if(CUDA) add_definitions( -DCUDA=1 ) find_package(CUDA QUIET REQUIRED) set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF) # ? if (USE64) set(CUDA_64_BIT_DEVICE_CODE ON) endif() if(WIN32) if(DEBUG) set(CUDA_NVCC_FLAGS -DDEBUG;--compiler-options;-Wall) else() set(CUDA_NVCC_FLAGS --use_fast_math;-DNDEBUG;--compiler-options;-Wall;-O2) endif() else() # CUDA does not support gcc > 4.5 yet if(DEBUG) set(CUDA_NVCC_FLAGS --pre-include;/usr/local/include/undef_atomics_int128.h;-g;-DDEBUG;-keep;--maxrregcount=31;--compiler-options;-Wall) else() #set(CUDA_NVCC_FLAGS -ccbin;gcc-4.5;--use_fast_math;-arch=sm_20;-DNDEBUG;--compiler-options;-Wall;-O3) set(CUDA_NVCC_FLAGS --pre-include;/usr/local/include/undef_atomics_int128.h;--use_fast_math;-DNDEBUG;--compiler-options;-Wall;-O3) endif() endif() endif() # increase FP precision? if(DOUBLEPRECISION) add_definitions(-DFLOATINGPOINT_PRECISION=2) endif() #****************************************************************************** # generate git repository info , currently only for unix systems IF(NOT WIN32) set(GITINFO "${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/source/gitinfo.h") MESSAGE(STATUS "Git info target header ${GITINFO}") add_custom_command(OUTPUT ${GITINFO} COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/getGitVersion.py" "${GITINFO}" DEPENDS ${PP_SOURCES} ${PP_HEADERS} ${NOPP_SOURCES} ${NOPP_HEADERS} ${QT_SOURCES} ${QT_HEADERS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) ENDIF() #****************************************************************************** # apply preprocessor set(SOURCES ${NOPP_SOURCES} ${SILENT_SOURCES}) set(HEADERS ${NOPP_HEADERS}) set(PP_REGCPP) set(PP_REGS) set(PP_PREPD "0") set(PREPPED_SOURCES) if (PREPDEBUG) set(PP_PREPD "1") endif() FOREACH(it ${PP_SOURCES} ${PP_HEADERS}) get_filename_component(CURPATH ${it} PATH) get_filename_component(CUREXT ${it} EXT) file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/${CURPATH}") set(CURPP "${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/${it}") string(REPLACE "source/" "" INFILE ${it}) set(OUTFILES "${CURPP}") if ("${CUREXT}" STREQUAL ".h" OR "${CUREXT}" STREQUAL ".py") IF(NOT NOPYTHON) list(APPEND PP_REGS "${CURPP}.reg") list(APPEND PP_REGCPP "${CURPP}.reg.cpp") ENDIF() set_source_files_properties("${CURPP}.reg.cpp" OBJECT_DEPENDS "${CURPP}") list(APPEND OUTFILES "${CURPP}.reg") ENDIF() # preprocessor add_custom_command(OUTPUT ${OUTFILES} COMMAND prep generate ${PP_PREPD} ${MT_TYPE} "${CMAKE_CURRENT_SOURCE_DIR}/source/" "${INFILE}" "${CURPP}" DEPENDS prep IMPLICIT_DEPENDS CXX ${it} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) set_source_files_properties(${OUTFILES} PROPERTIES GENERATED 1) list(APPEND PREPPED_SOURCES ${CURPP}) ENDFOREACH(it) list(APPEND SOURCES ${PREPPED_SOURCES}) # link reg files , for python glue code IF(NOT NOPYTHON) add_custom_command(OUTPUT ${PP_REGCPP} COMMAND prep link ${PP_REGS} DEPENDS prep ${PP_REGS} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Linking reg files") set_source_files_properties(${PP_REGCPP} PROPERTIES GENERATED 1) list(APPEND SOURCES ${PP_REGCPP}) ENDIF() #****************************************************************************** # QT for GUI if(GUI) # remap set(QT_REMAP) foreach(it ${QT_HEADERS}) list(APPEND QT_REMAP "${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/${it}") endforeach(it) add_definitions(-DGUI=1) list(APPEND INCLUDE_PATHS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${PP_PATH}/source/gui source/gui) cmake_policy(SET CMP0020 NEW) find_package(Qt5Core QUIET) if (Qt5Core_FOUND) message("Using Qt5") find_package(Qt5Widgets REQUIRED) find_package(Qt5OpenGL REQUIRED) qt5_wrap_cpp(MOC_OUTFILES ${QT_REMAP} ) qt5_add_resources(QT_RES resources/res.qrc ) add_definitions(-DGUI=1) add_definitions(${Qt5Widgets_DEFINITIONS}) list(APPEND INCLUDE_PATHS ${Qt5Widgets_INCLUDE_DIRS} ${Qt5OpenGL_INCLUDE_DIRS}) list(APPEND F_LIBS ${Qt5Widgets_LIBRARIES} ${Qt5OpenGL_LIBRARIES}) list(APPEND SOURCES ${MOC_OUTFILES} ${QT_RES}) else() message("No Qt5 found (recommended!), trying to use Qt4") find_package(Qt4 REQUIRED) set(QT_USE_QTOPENGL TRUE) qt4_wrap_cpp(MOC_OUTFILES ${QT_REMAP} ) qt4_add_resources(QT_RES resources/res.qrc ) include(${QT_USE_FILE}) add_definitions(${QT_DEFINITIONS}) list(APPEND F_LIBS ${QT_LIBRARIES}) list(APPEND SOURCES ${MOC_OUTFILES} ${QT_RES}) endif() if (APPLE) # mac opengl framework SET(F_LINKADD "${F_LINKADD} -framework OpenGL ") else() find_package(OpenGL REQUIRED) list(APPEND F_LIBS ${OPENGL_LIBRARIES}) endif() endif() #****************************************************************************** # setup executable SET(EXECCMD manta) SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${F_LINKADD} ") SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${F_LINKADD} ") include_directories( ${INCLUDE_PATHS}) link_directories( ${F_LIB_PATHS} ) IF(NOT NOPYTHON) # build regular executable if(CUDA) #cuda_include_directories(pp/source/cuda) cuda_add_executable( ${EXECCMD} ${SOURCES} ${PP_REGISTRY}) target_link_libraries( ${EXECCMD} ${F_LIBS} ) cuda_build_clean_target() else() if (WIN32) # make nice folders for Visual Studio set_source_files_properties(${PP_SOURCES} ${PP_HEADERS} ${NOPP_HEADERS} PROPERTIES HEADER_FILE_ONLY TRUE) add_executable(${EXECCMD} ${SOURCES} ${PP_REGISTRY} ${PP_SOURCES} ${PP_HEADERS}) source_group(Generated FILES ${SOURCES} ${PP_REGISTRY} ${HEADERS}) else() add_executable(${EXECCMD} ${SOURCES} ${PP_REGISTRY} ${GITINFO}) endif() target_link_libraries( ${EXECCMD} ${F_LIBS} ) endif() # fix for "el capitan" TBB and changed dynamic library env vars, lookup of TBB can cause problems without @rpath IF(APPLE) EXEC_PROGRAM(uname ARGS -v OUTPUT_VARIABLE OSX_VERSION) STRING(REGEX MATCH "[0-9]+" OSX_VERSION ${OSX_VERSION}) IF (OSX_VERSION GREATER 14) ADD_CUSTOM_COMMAND(TARGET manta POST_BUILD COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change libtbb.dylib @rpath/libtbb.dylib $ ) ENDIF() ENDIF() ELSE() # only build static library in nopython mode ADD_LIBRARY (core OBJECT ${SOURCES} ${GITINFO}) ADD_LIBRARY (${EXECCMD} STATIC $) ENDIF() # compiler flags IF(NOT WIN32) IF(DEBUG) # stricter: no optimizations and inlining, comment out if needed... #add_definitions( -O0 -fno-inline -Wall ) set_target_properties(manta PROPERTIES COMPILE_FLAGS "-O0 -fno-inline -Wall ") ELSE() # non-debug, optimized version #add_definitions( -O3 -Wall ) set_target_properties(manta PROPERTIES COMPILE_FLAGS "-O3 -Wall ") ENDIF() # use c++11 for all pre-processed c++ sources set_source_files_properties(${PREPPED_SOURCES} PROPERTIES COMPILE_FLAGS " -std=c++11 " ) ENDIF() IF(WIN32) # get rid of some MSVC warnings add_definitions( /wd4018 /wd4146 /wd4800 ) # for zlib add_definitions(-D_CRT_SECURE_NO_DEPRECATE) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) # unsigned to signed conversions add_definitions( /wd4267 ) # double <> single precision add_definitions( /wd4244 /wd4305 ) # disable warnings for unsecure functions add_definitions( /D "_CRT_SECURE_NO_WARNINGS" ) # enable when using Qt creator: #add_definitions(/FS) ENDIF() # debug summary # MESSAGE(STATUS "DEBUG Flag-Summary - Includes: '${INCLUDE_PATHS}' | Libs: '${F_LIBS}' | LibPaths: '${F_LIB_PATHS}' ")