initial sandbox version

This commit is contained in:
Radovan Bast 2015-05-22 14:14:15 +02:00
parent 2622b118a8
commit 1cd4dc1eef
34 changed files with 1425 additions and 4 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2015, scisoft Copyright (c) 2015, Scisoft
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -11,7 +11,7 @@ modification, are permitted provided that the following conditions are met:
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name of autocmake nor the names of its * Neither the name of Autocmake nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.

View File

@ -1,2 +1,60 @@
# autocmake # Autocmake
CMake plugin composer.
A CMake plugin composer.
## Bootstrapping a new project
Bootstrap a CFrame infrastructure out of "nothing":
mkdir cmake # does not have to be called "cmake" - take the name you prefer
cd cmake
wget https://github.com/scisoft/autocmake/raw/master/bootstrap.py
python bootstrap.py --init
This downloads and creates the following files:
cmake/
├── bootstrap.py # no need to edit
├── cframe.cfg # edit this file
└── lib/
├── config.py # no need to edit
└── docopt.py # no need to edit
If you use version control, then now is a good moment to status/diff/add
the newly created files.
## Creating the CMake infrastructure
Then edit ``cframe.cfg`` and run the ``bootstrap.py`` script which
creates ``CMakeLists.txt`` and ``setup.py`` in the path specified (here ".."):
python bootstrap.py ..
The script also copies or downloads CMake modules specified in ``cframe.cfg`` to a directory
called ``modules/``:
cmake/
├── bootstrap.py
├── cframe.cfg
└── lib/
├── config.py
└── docopt.py
└── modules/ # CMakeLists.txt includes CMake modules from this directory
Now you have ``CMakeLists.txt`` and ``setup.py`` in the project root and you can build
the project:
cd ..
python setup.py [-h]
cd build
make
## Customizing the CMake modules
The CMake modules can be customized directly inside ``modules/`` but this is
not very convenient as the customizations may be overwritten by the
``boostrap.py`` script.
A better solution is to download the CMake modules that you wish you customize
to a separate directory and source the customized CMake modules in
``cframe.cfg``.

314
bootstrap.py Executable file
View File

@ -0,0 +1,314 @@
#!/usr/bin/env python
import os
import sys
import urllib
import shutil
import tempfile
from collections import OrderedDict
from ConfigParser import ConfigParser
CFRAME_GITHUB_URL = 'https://github.com/scisoft/autocmake'
class URLopener(urllib.FancyURLopener):
def http_error_default(self, url, fp, errcode, errmsg, headers):
sys.stderr.write("ERROR: could not fetch %s\n" % url)
sys.exit(-1)
def fetch_url(src, dst, fail_if_dst_exists=False):
"""
Fetch file from URL src and save it to dst.
"""
dirname = os.path.dirname(dst)
if dirname != '':
if not os.path.isdir(dirname):
os.makedirs(dirname)
if os.path.isfile(dst):
if fail_if_dst_exists:
sys.stderr.write("ERROR: %s already exists - aborting\n" % dst)
sys.exit(-1)
opener = URLopener()
opener.retrieve(src, dst)
def print_progress_bar(text, done, total, width):
"""
Print progress bar.
"""
n = int(float(width)*float(done)/float(total))
sys.stdout.write("\r%s [%s%s] (%i/%i)" % (text, '#'*n,
' '*(width-n), done, total))
sys.stdout.flush()
def align_options(options):
"""
Indendts flags and aligns help texts.
"""
l = 0
for opt in options:
if len(opt[0]) > l:
l = len(opt[0])
s = []
for opt in options:
s.append(' %s%s %s' % (opt[0], ' '*(l - len(opt[0])), opt[1]))
return '\n'.join(s)
def gen_cmake_command(config):
"""
Generate CMake command.
"""
s = []
s.append("\n\ndef gen_cmake_command(options, arguments):")
s.append(' """')
s.append(" Generate CMake command based on options and arguments.")
s.append(' """')
s.append(" command = []")
# take care of environment variables
for section in config.sections():
if config.has_option(section, 'export'):
for env in config.get(section, 'export').split('\n'):
s.append(' command.append(%s)' % env)
s.append(" command.append('cmake')")
# take care of cmake definitions
for section in config.sections():
if config.has_option(section, 'define'):
for definition in config.get(section, 'define').split('\n'):
s.append(' command.append(%s)' % definition)
s.append("\n return ' '.join(command)")
return '\n'.join(s)
def gen_setup(config, relative_path):
"""
Generate setup.py script.
"""
s = []
s.append('#!/usr/bin/env python')
s.append('\nimport os')
s.append('import sys')
s.append("\nsys.path.append('%s')" % os.path.join(relative_path, 'lib'))
s.append('from config import configure')
s.append('from docopt import docopt')
s.append('\n\noptions = """')
s.append('Usage:')
s.append(' ./setup.py [options] [<builddir>]')
s.append(' ./setup.py (-h | --help)')
s.append('\nOptions:')
options = []
for section in config.sections():
if config.has_option(section, 'docopt'):
for opt in config.get(section, 'docopt').split('\n'):
first = opt.split()[0].strip()
rest = ' '.join(opt.split()[1:]).strip()
options.append([first, rest])
options.append(['--show', 'Show CMake command and exit.'])
options.append(['<builddir>', 'Build directory.'])
options.append(['-h --help', 'Show this screen.'])
s.append(align_options(options))
s.append('"""')
s.append(gen_cmake_command(config))
s.append("\n\narguments = docopt(options, argv=None)")
s.append("\nroot_directory = os.path.dirname(os.path.realpath(__file__))")
s.append("build_path = arguments['<builddir>']")
s.append("cmake_command = '%s %s' % (gen_cmake_command(options, arguments), root_directory)")
s.append("configure(root_directory, build_path, cmake_command, arguments['--show'])")
return s
def gen_cmakelists(config, relative_path, list_of_modules):
"""
Generate CMakeLists.txt.
"""
if not config.has_option('project', 'name'):
sys.stderr.write("ERROR: you have to specify the project name\n")
sys.stderr.write(" in cframe.cfg under [project]\n")
sys.exit(-1)
project_name = config.get('project', 'name')
s = []
s.append('# set minimum cmake version')
s.append('cmake_minimum_required(VERSION 2.8 FATAL_ERROR)')
s.append('\n')
s.append('project(%s)' % project_name)
s.append('\n')
s.append('# do not rebuild if rules (compiler flags) change')
s.append('set(CMAKE_SKIP_RULE_DEPENDENCY TRUE)')
s.append('\n')
s.append('# directory which holds enabled cmake modules')
s.append('set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}')
s.append(' ${PROJECT_SOURCE_DIR}/%s)' % os.path.join(relative_path, 'modules'))
s.append('\n')
s.append('# guards against in-source builds and bad build types')
s.append('if(NOT CMAKE_BUILD_TYPE)')
s.append(' set(CMAKE_BUILD_TYPE "Debug")')
s.append('endif()')
s.append('\n')
s.append('# python interpreter is required at many')
s.append('# places during configuration and build')
s.append('find_package(PythonInterp REQUIRED)')
s.append('\n')
s.append('# determine program version from file, example: "14.1"')
s.append('# the reason why this information is stored')
s.append('# in a file and not as cmake variable')
s.append('# is that cmake-unaware programs can')
s.append('# parse and use it (e.g. Sphinx)')
s.append('file(READ "${PROJECT_SOURCE_DIR}/VERSION" PROGRAM_VERSION)')
s.append('string(STRIP "${PROGRAM_VERSION}" PROGRAM_VERSION)')
s.append('\n')
s.append('# generated cmake files will be written to this path')
s.append('# only build info is generated')
s.append('# everything else is static for the user')
s.append('file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/generated_by_cmake)')
s.append('set(CMAKE_MODULE_PATH')
s.append(' ${CMAKE_MODULE_PATH}')
s.append(' ${PROJECT_BINARY_DIR}/generated_by_cmake')
s.append(' )')
s.append('\n')
s.append('# included cmake modules')
for m in list_of_modules:
s.append('include(%s)' % os.path.splitext(m)[0])
return s
def fetch_modules(config, module_directory):
"""
Fetch modules either from remote URLs or from relative paths
and save them to module_directory from which they will
be included in CMakeLists.txt.
"""
if not os.path.exists(module_directory):
os.makedirs(module_directory)
n = len(filter(lambda x: config.has_option(x, 'source'),
config.sections()))
i = 0
print_progress_bar(text='- fetching modules:', done=0, total=n, width=30)
list_of_modules = []
for section in config.sections():
if config.has_option(section, 'source'):
for src in config.get(section, 'source').split('\n'):
module_name = os.path.basename(src)
list_of_modules.append(module_name)
dst = os.path.join(module_directory, module_name)
if 'http' in src:
fetch_url(src, dst)
else:
if os.path.exists(src):
shutil.copyfile(src, dst)
else:
sys.stderr.write("ERROR: %s does not exist\n" % src)
sys.exit(-1)
i += 1
print_progress_bar(
text='- fetching modules:',
done=i,
total=n,
width=30
)
print('')
return list_of_modules
def main(argv):
"""
Main function.
"""
if len(argv) != 2:
sys.stderr.write("\nYou can bootstrap a project in two steps.\n")
sys.stderr.write("First step is typically done only once.\n")
sys.stderr.write("Second step can be repeated many time without re-running the first step.\n\n")
sys.stderr.write("Step 1:\n")
sys.stderr.write("Create an example cframe.cfg and other infrastructure files\n")
sys.stderr.write("which will be needed to configure and build the project:\n")
sys.stderr.write("$ %s --init\n\n" % argv[0])
sys.stderr.write("Step 2:\n")
sys.stderr.write("Create CMakeLists.txt and setup.py in PROJECT_ROOT:\n")
sys.stderr.write("$ %s PROJECT_ROOT\n" % argv[0])
sys.stderr.write("example:\n")
sys.stderr.write("$ %s ..\n" % argv[0])
sys.exit(-1)
if argv[1] == '--init':
# empty project, create infrastructure files
print('- fetching example cframe.cfg')
fetch_url(
src='%s/raw/master/example/cframe.cfg' % CFRAME_GITHUB_URL,
dst='cframe.cfg',
fail_if_dst_exists=True
)
print('- fetching lib/config.py')
fetch_url(
src='%s/raw/master/lib/config.py' % CFRAME_GITHUB_URL,
dst='lib/config.py'
)
print('- fetching lib/docopt.py')
fetch_url(
src='https://github.com/docopt/docopt/raw/master/docopt.py',
dst='lib/docopt.py'
)
sys.exit(0)
project_root = argv[1]
if not os.path.isdir(project_root):
sys.stderr.write("ERROR: %s is not a directory\n" % project_root)
sys.exit(-1)
# read config file
print('- parsing cframe.cfg')
config = ConfigParser(dict_type=OrderedDict)
config.read('cframe.cfg')
# fetch modules from the web or from relative paths
list_of_modules = fetch_modules(config, module_directory='modules')
# get relative path from setup.py script to this directory
relative_path = os.path.relpath(os.path.abspath('.'), project_root)
# create CMakeLists.txt
print('- generating CMakeLists.txt')
s = gen_cmakelists(config, relative_path, list_of_modules)
with open(os.path.join(project_root, 'CMakeLists.txt'), 'w') as f:
f.write('%s\n' % '\n'.join(s))
# create setup.py
print('- generating setup.py')
s = gen_setup(config, relative_path)
with open(os.path.join(project_root, 'setup.py'), 'w') as f:
f.write('%s\n' % '\n'.join(s))
if __name__ == '__main__':
main(sys.argv)

View File

@ -0,0 +1,5 @@
if(CMAKE_C_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
set(CMAKE_C_FLAGS_RELEASE "-O2 -Wno-unused")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wno-unknown-pragmas -Wno-sign-compare -Woverloaded-virtual -Wwrite-strings -Wno-unused")
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -march=native -DNDEBUG -Wno-unused")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_C_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
set(CMAKE_C_FLAGS_RELEASE "-O2 -Wno-unused")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wno-unknown-pragmas -Wno-sign-compare -Woverloaded-virtual -Wwrite-strings -Wno-unused")
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -march=native -DNDEBUG -Wno-unused")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -fbacktrace")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -funroll-all-loops -w")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_C_COMPILER_ID MATCHES Intel)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_CXX_COMPILER_ID MATCHES Intel)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -debug -DDEBUG")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -w -assume byterecl -g -traceback")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3 -ip")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_C_COMPILER_ID MATCHES PGI)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_CXX_COMPILER_ID MATCHES PGI)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_Fortran_COMPILER_ID MATCHES PGI)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
set(CMAKE_Fortran_FLAGS_DEBUG "-g")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_C_COMPILER_ID MATCHES XL)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -qcpluscmt")
set(CMAKE_C_FLAGS_RELEASE "-O3")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_CXX_COMPILER_ID MATCHES XL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
endif()

View File

@ -0,0 +1,5 @@
if(CMAKE_Fortran_COMPILER_ID MATCHES XL)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qzerosize -qextname -qsuppress=cmpmsg")
set(CMAKE_Fortran_FLAGS_RELEASE "-O3")
set(CMAKE_Fortran_FLAGS_DEBUG "-g")
endif()

6
doc/doc.rst Normal file
View File

@ -0,0 +1,6 @@
Title
-----
Write me ...

3
example/cframe.cfg Normal file
View File

@ -0,0 +1,3 @@
# uncomment and set project name
# [project]
# name: myproject

122
lib/config.py Normal file
View File

@ -0,0 +1,122 @@
# Copyright (c) 2015 by Radovan Bast and Jonas Juselius
# see https://github.com/scisoft/cframe/blob/master/LICENSE
import subprocess
import os
import sys
import shutil
def check_cmake_exists(cmake_command):
"""
Check whether CMake is installed. If not, print
informative error message and quits.
"""
p = subprocess.Popen('%s --version' % cmake_command,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
if not ('cmake version' in p.communicate()[0]):
sys.stderr.write(' This code is built using CMake\n\n')
sys.stderr.write(' CMake is not found\n')
sys.stderr.write(' get CMake at http://www.cmake.org/\n')
sys.stderr.write(' on many clusters CMake is installed\n')
sys.stderr.write(' but you have to load it first:\n')
sys.stderr.write(' $ module load cmake\n')
sys.exit(1)
def setup_build_path(build_path):
"""
Create build directory. If this already exists, print informative
error message and quit.
"""
if os.path.isdir(build_path):
fname = os.path.join(build_path, 'CMakeCache.txt')
if os.path.exists(fname):
sys.stderr.write('aborting setup\n')
sys.stderr.write('build directory %s which contains CMakeCache.txt already exists\n' % build_path)
sys.stderr.write('remove the build directory and then rerun setup\n')
sys.exit(1)
else:
os.makedirs(build_path, 0755)
def run_cmake(command, build_path, default_build_path):
"""
Execute CMake command.
"""
topdir = os.getcwd()
os.chdir(build_path)
p = subprocess.Popen(
command,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE
)
s = p.communicate()[0]
# print cmake output to screen
print(s)
# write cmake output to file
f = open('cmake_output', 'w')
f.write(s)
f.close()
# change directory and return
os.chdir(topdir)
if 'Configuring incomplete' in s:
# configuration was not successful
if (build_path == default_build_path):
# remove build_path iff not set by the user
# otherwise removal can be dangerous
shutil.rmtree(default_build_path)
else:
# configuration was successful
save_configure_command(sys.argv, build_path)
print_build_help(build_path, default_build_path)
def print_build_help(build_path, default_build_path):
"""
Print help text after configuration step is done.
"""
print(' configure step is done')
print(' now you need to compile the sources:')
if (build_path == default_build_path):
print(' $ cd build')
else:
print(' $ cd ' + build_path)
print(' $ make')
def save_configure_command(argv, build_path):
"""
Save configure command to a file.
"""
file_name = os.path.join(build_path, 'configure_command')
f = open(file_name, 'w')
f.write(' '.join(argv[:]) + '\n')
f.close()
def configure(root_directory, build_path, cmake_command, only_show):
"""
Main configure function.
"""
default_build_path = os.path.join(root_directory, 'build')
# check that CMake is available, if not stop
check_cmake_exists('cmake')
# deal with build path
if build_path is None:
build_path = default_build_path
if not only_show:
setup_build_path(build_path)
print('%s\n' % cmake_command)
if only_show:
sys.exit(0)
run_cmake(cmake_command, build_path, default_build_path)

View File

@ -0,0 +1,111 @@
#.rst:
# CheckFortranSourceCompiles
# --------------------------
#
# Check if given Fortran source compiles and links into an executable::
#
# CHECK_Fortran_SOURCE_COMPILES(<code> <var> [FAIL_REGEX <fail-regex>])
#
# The arguments are:
#
# ``<code>``
# Source code to try to compile. It must define a PROGRAM entry point.
# ``<var>``
# Variable to store whether the source code compiled.
# Will be created as an internal cache variable.
# ``<fail-regex>``
# Fail if test output matches this regex.
#
# The following variables may be set before calling this macro to modify
# the way the check is run::
#
# CMAKE_REQUIRED_FLAGS = string of compile command line flags
# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
# CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link
# CMAKE_REQUIRED_QUIET = execute quietly without messages
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
if(NOT DEFINED "${VAR}")
set(_FAIL_REGEX)
set(_key)
foreach(arg ${ARGN})
if("${arg}" MATCHES "^(FAIL_REGEX)$")
set(_key "${arg}")
elseif(_key)
list(APPEND _${_key} "${arg}")
else()
message(FATAL_ERROR "Unknown argument:\n ${arg}\n")
endif()
endforeach()
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES
LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
else()
set(CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES)
endif()
if(CMAKE_REQUIRED_INCLUDES)
set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES
"-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
else()
set(CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES)
endif()
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.F90"
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.F90
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
foreach(_regex ${_FAIL_REGEX})
if("${OUTPUT}" MATCHES "${_regex}")
set(${VAR} 0)
endif()
endforeach()
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VAR} - Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Fortran SOURCE FILE Test ${VAR} succeded with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
message(STATUS "Performing Test ${VAR} - Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
"${OUTPUT}\n"
"Source file was:\n${SOURCE}\n")
endif()
endif()
endmacro()

137
modules/UseBuildInfo.cmake Normal file
View File

@ -0,0 +1,137 @@
# Copyright (c) 2015 by Radovan Bast and Jonas Juselius
# see https://github.com/scisoft/cframe/blob/master/LICENSE
#-------------------------------------------------------------------------------
function(get_git_info
in_python_executable
out_git_last_commit_hash
out_git_last_commit_author
out_git_last_commit_date
out_git_branch
out_git_status_at_build)
find_package(Git)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-list --max-count=1 --abbrev-commit HEAD
OUTPUT_VARIABLE _git_last_commit_hash
ERROR_QUIET
)
if(_git_last_commit_hash)
string(STRIP ${_git_last_commit_hash} _git_last_commit_hash)
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} log --max-count=1 HEAD
OUTPUT_VARIABLE _git_last_commit
ERROR_QUIET
)
if(_git_last_commit)
string(REGEX MATCH "Author:[ ]*(.+)<" temp "${_git_last_commit}")
set(_git_last_commit_author ${CMAKE_MATCH_1})
string(REGEX MATCH "Date:[ ]*(.+(\\+|-)[0-9][0-9][0-9][0-9])" temp "${_git_last_commit}")
set(_git_last_commit_date ${CMAKE_MATCH_1})
endif()
execute_process(
COMMAND ${in_python_executable} -c "import subprocess; import re; print(re.search(r'\\*.*', subprocess.Popen(['${GIT_EXECUTABLE}', 'branch'], stdout=subprocess.PIPE).communicate()[0], re.MULTILINE).group())"
OUTPUT_VARIABLE _git_branch
ERROR_QUIET
)
if(_git_branch)
string(REPLACE "*" "" _git_branch ${_git_branch})
string(STRIP ${_git_branch} _git_branch)
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} status -uno
OUTPUT_VARIABLE _git_status_at_build
ERROR_QUIET
)
set(${out_git_last_commit_hash} ${_git_last_commit_hash} PARENT_SCOPE)
set(${out_git_last_commit_author} ${_git_last_commit_author} PARENT_SCOPE)
set(${out_git_last_commit_date} ${_git_last_commit_date} PARENT_SCOPE)
set(${out_git_branch} ${_git_branch} PARENT_SCOPE)
set(${out_git_status_at_build} ${_git_status_at_build} PARENT_SCOPE)
else()
set(${out_git_last_commit_hash} "" PARENT_SCOPE)
set(${out_git_last_commit_author} "" PARENT_SCOPE)
set(${out_git_last_commit_date} "" PARENT_SCOPE)
set(${out_git_branch} "" PARENT_SCOPE)
set(${out_git_status_at_build} "" PARENT_SCOPE)
endif()
endfunction()
get_git_info(${PYTHON_EXECUTABLE}
GIT_COMMIT_HASH
GIT_COMMIT_AUTHOR
GIT_COMMIT_DATE
GIT_BRANCH
GIT_STATUS_AT_BUILD)
# get configuration time in UTC
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import datetime; print(datetime.datetime.utcnow())"
OUTPUT_VARIABLE _configuration_time
)
string(STRIP ${_configuration_time} _configuration_time) # delete newline
execute_process(
COMMAND whoami
TIMEOUT 1
OUTPUT_VARIABLE _user_name
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND hostname
TIMEOUT 1
OUTPUT_VARIABLE _host_name
OUTPUT_STRIP_TRAILING_WHITESPACE
)
get_directory_property(_list_of_definitions DIRECTORY ${PROJECT_SOURCE_DIR} COMPILE_DEFINITIONS)
# set python version variable when it is not defined automatically
# this can happen when cmake version is equal or less than 2.8.5
if(NOT _python_version)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -V
OUTPUT_VARIABLE _python_version
ERROR_VARIABLE _python_version
)
string(REGEX MATCH "Python ([0-9].[0-9].[0-9])" temp "${_python_version}")
set(_python_version ${CMAKE_MATCH_1})
endif()
configure_file(
${PROJECT_SOURCE_DIR}/cmake/lib/config_info.in.py
${PROJECT_BINARY_DIR}/config_info.py
)
unset(_configuration_time)
unset(_user_name)
unset(_host_name)
unset(_list_of_definitions)
unset(_python_version)
exec_program(
${PYTHON_EXECUTABLE}
${PROJECT_BINARY_DIR}
ARGS config_info.py Fortran > ${PROJECT_BINARY_DIR}/config_info.F90
OUTPUT_VARIABLE _discard # we don't care about the output
)
exec_program(
${PYTHON_EXECUTABLE}
${PROJECT_BINARY_DIR}
ARGS config_info.py CMake > ${PROJECT_BINARY_DIR}/generated_by_cmake/config_info_generated.cmake
OUTPUT_VARIABLE _discard # we don't care about the output
)
include(config_info_generated)

13
modules/UseC.cmake Normal file
View File

@ -0,0 +1,13 @@
enable_language(C)
if(NOT DEFINED CMAKE_C_COMPILER_ID)
message(FATAL_ERROR "CMAKE_C_COMPILER_ID variable is not defined!")
endif()
if(NOT CMAKE_C_COMPILER_WORKS)
message(FATAL_ERROR "CMAKE_C_COMPILER_WORKS is false!")
endif()
if(DEFINED EXTRA_C_FLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
endif()

7
modules/UseCPP.cmake Normal file
View File

@ -0,0 +1,7 @@
set(CPP)
# forward CPP directly to the code
if(NOT "${CPP}" STREQUAL "")
add_definitions(${CPP})
endif()

13
modules/UseCXX.cmake Normal file
View File

@ -0,0 +1,13 @@
enable_language(CXX)
if(NOT DEFINED CMAKE_CXX_COMPILER_ID)
message(FATAL_ERROR "CMAKE_CXX_COMPILER_ID variable is not defined!")
endif()
if(NOT CMAKE_CXX_COMPILER_WORKS)
message(FATAL_ERROR "CMAKE_CXX_COMPILER_WORKS is false!")
endif()
if(DEFINED EXTRA_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
endif()

View File

@ -0,0 +1,18 @@
option(ENABLE_CODE_COVERAGE "Enable code coverage" OFF)
if(ENABLE_CODE_COVERAGE)
if(DEFINED CMAKE_Fortran_COMPILER_ID)
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
endif()
if(DEFINED CMAKE_CXX_COMPILER_ID)
if(CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
endif()
endif()

15
modules/UseFortran.cmake Normal file
View File

@ -0,0 +1,15 @@
enable_language(Fortran)
set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/include/fortran)
if(NOT DEFINED CMAKE_Fortran_COMPILER_ID)
message(FATAL_ERROR "CMAKE_Fortran_COMPILER_ID variable is not defined!")
endif()
if(NOT CMAKE_Fortran_COMPILER_WORKS)
message(FATAL_ERROR "CMAKE_Fortran_COMPILER_WORKS is false!")
endif()
if(DEFINED EXTRA_Fortran_FLAGS)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${EXTRA_Fortran_FLAGS}")
endif()

18
modules/UseInt64.cmake Normal file
View File

@ -0,0 +1,18 @@
option(ENABLE_64BIT_INTEGERS "Enable 64-bit integers" OFF)
if(ENABLE_64BIT_INTEGERS)
if(DEFINED CMAKE_Fortran_COMPILER_ID)
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-integer-8")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -i8")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES PGI)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -i8")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES XL)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qintsize=8 -q64")
endif()
endif()
endif()

12
modules/UseMPI.cmake Normal file
View File

@ -0,0 +1,12 @@
option(ENABLE_MPI "Enable MPI parallelization" OFF)
# on Cray configure with -D MPI_FOUND=1
if(ENABLE_MPI AND NOT MPI_FOUND)
find_package(MPI)
if(MPI_FOUND)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${MPI_COMPILE_FLAGS}")
include_directories(${MPI_INCLUDE_PATH})
else()
message(FATAL_ERROR "-- You asked for MPI, but CMake could not find any MPI installation, check $PATH")
endif()
endif()

451
modules/UseMathLibs.cmake Normal file
View File

@ -0,0 +1,451 @@
# Copyright (c) 2015 by Radovan Bast and Jonas Juselius
# see https://github.com/scisoft/cframe/blob/master/LICENSE
# CMake variables used:
# - MATH_LIB_SEARCH_ORDER, example: set(MATH_LIB_SEARCH_ORDER MKL ESSL ATLAS ACML SYSTEM_NATIVE)
# - ENABLE_BLAS
# - ENABLE_LAPACK
# - BLAS_FOUND
# - LAPACK_FOUND
# - BLAS_LANG
# - LAPACK_LANG
# - BLAS_TYPE
# - LAPACK_TYPE
# - ENABLE_64BIT_INTEGERS
# - CMAKE_HOST_SYSTEM_PROCESSOR
# - BLACS_IMPLEMENTATION
# - MKL_FLAG
# Environment variables used:
# - MATH_ROOT
# - BLAS_ROOT
# - LAPACK_ROOT
# - MKL_ROOT
# - MKLROOT
# CMake variables set:
# - MATH_LIBS
# - BLAS_FOUND
# - LAPACK_FOUND
#-------------------------------------------------------------------------------
# SYSTEM_NATIVE
set(SYSTEM_NATIVE_BLAS_INCLUDE_PATH_SUFFIXES)
set(SYSTEM_NATIVE_LAPACK_INCLUDE_PATH_SUFFIXES)
set(SYSTEM_NATIVE_BLAS_HEADERS cblas.h)
set(SYSTEM_NATIVE_LAPACK_HEADERS clapack.h)
set(SYSTEM_NATIVE_BLAS_LIBRARY_PATH_SUFFIXES)
set(SYSTEM_NATIVE_LAPACK_LIBRARY_PATH_SUFFIXES)
set(SYSTEM_NATIVE_BLAS_LIBS blas)
set(SYSTEM_NATIVE_LAPACK_LIBS lapack)
#-------------------------------------------------------------------------------
# ESSL
set(ESSL_BLAS_INCLUDE_PATH_SUFFIXES)
set(ESSL_LAPACK_INCLUDE_PATH_SUFFIXES)
set(ESSL_BLAS_HEADERS UNKNOWN)
set(ESSL_LAPACK_HEADERS UNKNOWN)
set(ESSL_BLAS_LIBRARY_PATH_SUFFIXES)
set(ESSL_LAPACK_LIBRARY_PATH_SUFFIXES)
if(ENABLE_64BIT_INTEGERS)
set(ESSL_BLAS_LIBS esslsmp6464)
set(ESSL_LAPACK_LIBS esslsmp6464)
else()
set(ESSL_BLAS_LIBS essl)
set(ESSL_LAPACK_LIBS essl)
endif()
#-------------------------------------------------------------------------------
# ACML
set(ACML_BLAS_INCLUDE_PATH_SUFFIXES)
set(ACML_LAPACK_INCLUDE_PATH_SUFFIXES)
set(ACML_BLAS_HEADERS cblas.h)
set(ACML_LAPACK_HEADERS clapack.h)
set(ACML_BLAS_LIBRARY_PATH_SUFFIXES libso)
set(ACML_LAPACK_LIBRARY_PATH_SUFFIXES libso)
set(ACML_BLAS_LIBS acml)
set(ACML_LAPACK_LIBS acml)
#-------------------------------------------------------------------------------
# ATLAS
set(ATLAS_BLAS_INCLUDE_PATH_SUFFIXES atlas)
set(ATLAS_LAPACK_INCLUDE_PATH_SUFFIXES atlas)
set(ATLAS_BLAS_HEADERS cblas.h)
set(ATLAS_LAPACK_HEADERS clapack.h)
set(ATLAS_BLAS_LIBRARY_PATH_SUFFIXES atlas atlas-base atlas-base/atlas atlas-sse3)
set(ATLAS_LAPACK_LIBRARY_PATH_SUFFIXES atlas atlas-base atlas-base/atlas atlas-sse3)
set(ATLAS_BLAS_LIBS f77blas cblas atlas)
set(ATLAS_LAPACK_LIBS atlas lapack)
#-------------------------------------------------------------------------------
# OPENBLAS (no LAPACK in OPENBLAS)
set(OPENBLAS_BLAS_INCLUDE_PATH_SUFFIXES)
set(OPENBLAS_BLAS_HEADERS cblas_openblas.h)
set(OPENBLAS_BLAS_LIBRARY_PATH_SUFFIXES)
set(OPENBLAS_BLAS_LIBS openblas)
#-------------------------------------------------------------------------------
# MKL
set(MKL_BLAS_INCLUDE_PATH_SUFFIXES)
set(MKL_LAPACK_INCLUDE_PATH_SUFFIXES)
set(MKL_BLAS_HEADERS mkl_cblas.h)
set(MKL_LAPACK_HEADERS mkl_lapack.h)
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(MKL_BLAS_LIBRARY_PATH_SUFFIXES intel64 em64t)
set(MKL_LAPACK_LIBRARY_PATH_SUFFIXES intel64 em64t)
else()
set(MKL_BLAS_LIBRARY_PATH_SUFFIXES ia32 32)
set(MKL_LAPACK_LIBRARY_PATH_SUFFIXES ia32 32)
endif()
set(MKL_COMPILER_BINDINGS ${CMAKE_${BLAS_LANG}_COMPILER_ID})
set(_thread_lib)
if(MKL_COMPILER_BINDINGS MATCHES Intel)
set(_thread_lib mkl_intel_thread)
endif()
if(MKL_COMPILER_BINDINGS MATCHES PGI)
set(_thread_lib mkl_pgi_thread)
endif()
if(MKL_COMPILER_BINDINGS MATCHES GNU)
set(_thread_lib mkl_gnu_thread)
endif()
if(MKL_COMPILER_BINDINGS MATCHES Clang)
set(_thread_lib mkl_gnu_thread)
endif()
if(MKL_COMPILER_BINDINGS MATCHES Intel)
set(_compiler_mkl_interface mkl_intel)
endif()
if(MKL_COMPILER_BINDINGS MATCHES PGI)
set(_compiler_mkl_interface mkl_intel)
endif()
if(MKL_COMPILER_BINDINGS MATCHES GNU)
set(_compiler_mkl_interface mkl_gf)
endif()
if(MKL_COMPILER_BINDINGS MATCHES Clang)
set(_compiler_mkl_interface mkl_gf)
endif()
set(_lib_suffix)
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
if(ENABLE_64BIT_INTEGERS)
set(_lib_suffix _ilp64)
else()
set(_lib_suffix _lp64)
endif()
endif()
if(ENABLE_SCALAPACK)
set(_scalapack_lib mkl_scalapack${_lib_suffix})
if(${BLACS_IMPLEMENTATION} STREQUAL "intelmpi")
set(_blacs_lib mkl_blacs_intelmpi${_lib_suffix})
elseif(${BLACS_IMPLEMENTATION} STREQUAL "openmpi")
set(_blacs_lib mkl_blacs_openmpi${_lib_suffix})
elseif(${BLACS_IMPLEMENTATION} STREQUAL "sgimpt")
set(_blacs_lib mkl_blacs_sgimpt${_lib_suffix})
else()
message(FATAL_ERROR "BLACS implementation ${BLACS_IMPLEMENTATION} not recognized/supported")
endif()
else()
set(_scalapack_lib)
set(_blacs_lib)
endif()
# MKL 10.0.1.014
set(MKL_BLAS_LIBS ${_scalapack_lib} ${_compiler_mkl_interface}${_lib_suffix} ${_thread_lib} mkl_core mkl_def mkl_mc ${_blacs_lib} guide pthread m)
# then try this MKL BLAS combination
set(MKL_BLAS_LIBS2 ${_scalapack_lib} ${_compiler_mkl_interface}${_lib_suffix} ${_thread_lib} mkl_core ${_blacs_lib} guide pthread m)
# newer MKL BLAS versions do not have libguide
set(MKL_BLAS_LIBS3 ${_scalapack_lib} ${_compiler_mkl_interface}${_lib_suffix} ${_thread_lib} mkl_core ${_blacs_lib} pthread m)
# ancient MKL BLAS
set(MKL_BLAS_LIBS4 mkl guide m)
set(MKL_LAPACK_LIBS mkl_lapack95${_lib_suffix} ${_compiler_mkl_interface}${_lib_suffix})
# older MKL LAPACK
set(MKL_LAPACK_LIBS2 mkl_lapack)
unset(_lib_suffix)
unset(_thread_lib)
unset(_compiler_mkl_interface)
unset(_scalapack_lib)
unset(_blacs_lib)
macro(find_math_header _service _header)
string(TOUPPER ${_service} _SERVICE)
find_path(${_SERVICE}_INCLUDE_DIRS
NAMES ${_header}
PATHS ${${_SERVICE}_ROOT}
HINTS ${${_SERVICE}_ROOT}/include
PATH_SUFFIXES ${MATH_INCLUDE_PATH_SUFFIXES}
NO_DEFAULT_PATH
)
# the following is needed for Atlas' clapack.h
# this whole code needs major cleanup soon (2014-10-31)
find_path(${_SERVICE}_INCLUDE_DIRS
NAMES ${_header}
PATH_SUFFIXES ${MATH_INCLUDE_PATH_SUFFIXES}
)
find_path(${_SERVICE}_INCLUDE_DIRS
NAMES ${_header}
PATH_SUFFIXES include
)
set(${_SERVICE}_H ${_header})
unset(_SERVICE)
endmacro()
macro(find_math_libs _service)
string(TOUPPER ${_service} _SERVICE)
if(${_SERVICE}_FOUND)
return()
endif()
set(_lib)
set(_libs)
foreach(l ${ARGN})
find_library(_lib
NAMES ${l}
PATHS ${${_SERVICE}_ROOT}
HINTS ${${_SERVICE}_ROOT}/lib64 ${${_SERVICE}_ROOT}/lib
PATH_SUFFIXES ${MATH_LIBRARY_PATH_SUFFIXES}
NO_DEFAULT_PATH
)
find_library(_lib
NAMES ${l}
PATH_SUFFIXES ${MATH_LIBRARY_PATH_SUFFIXES}
)
if(_lib)
set(_libs ${_libs} ${_lib})
else()
set(${_SERVICE}_LIBRARIES ${_SERVICE}_LIBRARIES-NOTFOUND)
set(_libs ${_SERVICE}_LIBRARIES-NOTFOUND)
break()
endif()
unset(_lib CACHE)
endforeach()
set(${_SERVICE}_LIBRARIES ${_libs})
unset(_lib CACHE)
unset(_libs CACHE)
unset(_SERVICE)
unset(l)
endmacro()
macro(cache_math_result _service MATH_TYPE)
string(TOUPPER ${_service} _SERVICE)
set(${_SERVICE}_FIND_QUIETLY TRUE)
if(DEFINED ${_SERVICE}_INCLUDE_DIRS)
find_package_handle_standard_args(
${_SERVICE}
"Could NOT find ${MATH_TYPE} ${_SERVICE}"
${_SERVICE}_LIBRARIES
${_SERVICE}_INCLUDE_DIRS
)
else()
find_package_handle_standard_args(
${_SERVICE}
"Could NOT find ${MATH_TYPE} ${_SERVICE}"
${_SERVICE}_LIBRARIES
)
endif()
if(${_SERVICE}_FOUND)
set(${_SERVICE}_TYPE ${MATH_TYPE} CACHE STRING
"${_SERVICE} type")
mark_as_advanced(${_SERVICE}_TYPE)
add_definitions(-DHAVE_${MATH_TYPE}_${_SERVICE})
set(HAVE_${_SERVICE} ON CACHE INTERNAL
"Defined if ${_SERVICE} is available"
)
set(HAVE_${MATH_TYPE}_${_SERVICE} ON CACHE INTERNAL
"Defined if ${MATH_TYPE}_${_SERVICE} is available"
)
set(${_SERVICE}_LIBRARIES ${${_SERVICE}_LIBRARIES} CACHE STRING
"${_SERVICE} libraries"
)
mark_as_advanced(${_SERVICE}_LIBRARIES)
if(DEFINED ${_SERVICE}_INCLUDE_DIRS)
set(${_SERVICE}_H ${${_SERVICE}_H} CACHE STRING
"${_SERVICE} header file")
mark_as_advanced(${_SERVICE}_H)
set(${_SERVICE}_INCLUDE_DIRS ${${_SERVICE}_INCLUDE_DIRS}
CACHE STRING "${_SERVICE} include directory"
)
mark_as_advanced(${_SERVICE}_INCLUDE_DIRS)
endif()
else()
set(${_SERVICE}_LIBRARIES ${_SERVICE}_LIBRARIES-NOTFOUND)
if(DEFINED ${_SERVICE}_H)
set(${_SERVICE}_INCLUDE_DIRS ${_SERVICE}_INCLUDE_DIRS-NOTFOUND)
unset(${_SERVICE}_H)
endif()
endif()
set(${_SERVICE}_FOUND ${${_SERVICE}_FOUND} PARENT_SCOPE)
unset(MATH_TYPE)
unset(_SERVICE)
endmacro()
macro(config_math_service _SERVICE)
if(EXISTS $ENV{MATH_ROOT})
if("${${_SERVICE}_ROOT}" STREQUAL "")
set(${_SERVICE}_ROOT $ENV{MATH_ROOT})
message("-- ${_SERVICE} will be searched for based on MATH_ROOT=${${_SERVICE}_ROOT} ")
endif()
endif()
if(EXISTS $ENV{${_SERVICE}_ROOT})
if("${${_SERVICE}_ROOT}" STREQUAL "")
set(${_SERVICE}_ROOT $ENV{${_SERVICE}_ROOT})
message("-- ${_SERVICE} will be searched for based on ${_SERVICE}_ROOT=${${_SERVICE}_ROOT}")
endif()
endif()
if(EXISTS $ENV{MKL_ROOT})
if("${${_SERVICE}_ROOT}" STREQUAL "")
set(${_SERVICE}_ROOT $ENV{MKL_ROOT})
message("-- ${_SERVICE} will be searched for based on MKL_ROOT=${${_SERVICE}_ROOT}")
endif()
endif()
if(EXISTS $ENV{MKLROOT})
if("${${_SERVICE}_ROOT}" STREQUAL "")
set(${_SERVICE}_ROOT $ENV{MKLROOT})
message("-- ${_SERVICE} will be searched for based on MKLROOT=${${_SERVICE}_ROOT}")
endif()
endif()
if(${_SERVICE}_INCLUDE_DIRS AND ${_SERVICE}_LIBRARIES)
set(${_SERVICE}_FIND_QUIETLY TRUE)
endif()
if(NOT ${_SERVICE}_FIND_COMPONENTS)
if(DEFINED ${_SERVICE}_TYPE)
set(${_SERVICE}_FIND_COMPONENTS ${${_SERVICE}_TYPE})
else()
set(${_SERVICE}_FIND_COMPONENTS ${MATH_LIB_SEARCH_ORDER})
endif()
endif()
find_service(${_SERVICE})
if(${_SERVICE}_FOUND)
# take care of omp flags
set(_omp_flag)
if(HAVE_MKL_BLAS OR HAVE_MKL_LAPACK)
if(MKL_COMPILER_BINDINGS MATCHES Intel)
set(_omp_flag -openmp)
endif()
if(MKL_COMPILER_BINDINGS MATCHES GNU)
set(_omp_flag -fopenmp)
endif()
if(MKL_COMPILER_BINDINGS MATCHES PGI)
set(_omp_flag -mp)
endif()
endif()
if(HAVE_MKL_${_SERVICE})
set(${_SERVICE}_LIBRARIES -Wl,--start-group ${${_SERVICE}_LIBRARIES} ${_omp_flag} -Wl,--end-group)
endif()
unset(_omp_flag)
find_package_message(${_SERVICE}
"Found ${_SERVICE}: ${${_SERVICE}_TYPE} (${${_SERVICE}_LIBRARIES})"
"[${${_SERVICE}_LIBRARIES}]"
)
set(MATH_LIBS
${MATH_LIBS}
${${_SERVICE}_LIBRARIES}
)
else()
add_definitions(-DUSE_BUILTIN_${_SERVICE})
set(USE_BUILTIN_${_SERVICE} TRUE)
endif()
endmacro()
macro(find_math_library _myservice _mytype)
set(MATH_INCLUDE_PATH_SUFFIXES ${${_mytype}_${_myservice}_INCLUDE_PATH_SUFFIXES})
if(${_myservice}_LANG STREQUAL "C")
find_math_header(${_myservice} ${${_mytype}_${_myservice}_HEADERS})
endif()
set(MATH_LIBRARY_PATH_SUFFIXES ${${_mytype}_${_myservice}_LIBRARY_PATH_SUFFIXES})
find_math_libs(${_myservice} ${${_mytype}_${_myservice}_LIBS})
# try some alternative patterns (if defined) until we find it
foreach(_i 2 3 4 5 6 7 8 9)
if(NOT ${_myservice}_LIBRARIES)
if(DEFINED ${_mytype}_${_myservice}_LIBS${_i})
find_math_libs(${_myservice} ${${_mytype}_${_myservice}_LIBS${_i}})
endif()
endif()
endforeach()
endmacro()
function(find_service _myservice)
foreach(_component ${${_myservice}_FIND_COMPONENTS})
find_math_library(${_myservice} ${_component})
cache_math_result(${_myservice} ${_component})
if(${_myservice}_FOUND)
break()
endif()
endforeach()
endfunction()
foreach(_service BLAS LAPACK)
if(NOT ${_service}_LANG)
set(${_service}_LANG C)
elseif(${_service}_LANG STREQUAL "C" OR ${_service}_LANG STREQUAL "CXX")
set(${_service}_LANG C)
elseif(NOT ${_service}_LANG STREQUAL "Fortran")
message(FATAL_ERROR "Invalid ${_service} library linker language: ${${_service}_LANG}")
endif()
endforeach()
set(MATH_LIBS)
if(NOT MKL_FLAG STREQUAL "off")
set(EXTERNAL_LIBS ${EXTERNAL_LIBS} -mkl=${MKL_FLAG})
message(STATUS "User set explicit MKL flag which is passed to the compiler and linker: -mkl=${MKL_FLAG}")
message(STATUS "This disables math detection and builtin math libraries")
message(STATUS "Setting -DHAVE_MKL_BLAS and -DHAVE_MKL_LAPACK")
add_definitions(-DHAVE_MKL_BLAS)
add_definitions(-DHAVE_MKL_LAPACK)
set(BLAS_FOUND TRUE)
set(LAPACK_FOUND TRUE)
endif()
if(ENABLE_BLAS STREQUAL "auto" OR ENABLE_LAPACK STREQUAL "auto" AND NOT ${_service}_FOUND)
message(STATUS "Math lib search order is ${MATH_LIB_SEARCH_ORDER}")
endif()
foreach(_service BLAS LAPACK)
if(ENABLE_${_service} STREQUAL "auto" AND NOT ${_service}_FOUND)
config_math_service(${_service})
if(${_service}_FOUND)
include_directories(${${_service}_INCLUDE_DIRS})
endif()
endif()
endforeach()

9
modules/UseOMP.cmake Normal file
View File

@ -0,0 +1,9 @@
option(ENABLE_OPENMP "Enable OpenMP parallelization" OFF)
if(ENABLE_OPENMP)
find_package(OpenMP)
if(OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_C_FLAGS}")
endif()
endif()

View File

@ -0,0 +1 @@
# nothing yet

View File

@ -0,0 +1,19 @@
function(guard_against_in_source in_source_dir in_binary_dir)
if(${in_source_dir} STREQUAL ${in_binary_dir})
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.")
endif()
endfunction()
function(guard_against_bad_build_types in_build_type)
string(TOLOWER "${in_build_type}" cmake_build_type_tolower)
string(TOUPPER "${in_build_type}" cmake_build_type_toupper)
if( NOT cmake_build_type_tolower STREQUAL "debug"
AND NOT cmake_build_type_tolower STREQUAL "release"
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")
message(FATAL_ERROR "Unknown build type \"${in_build_type}\". Allowed values are Debug, Release, RelWithDebInfo (case-insensitive).")
endif()
endfunction()
guard_against_in_source(${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
guard_against_bad_build_types(${CMAKE_BUILD_TYPE})

View File

@ -0,0 +1,24 @@
option(ENABLE_STATIC_LINKING "Enable static libraries linking" OFF)
if(ENABLE_STATIC_LINKING)
if(DEFINED CMAKE_Fortran_COMPILER_ID)
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -static")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -static-libgcc -static-intel")
endif()
if(CMAKE_Fortran_COMPILER_ID MATCHES PGI)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Bstatic")
endif()
endif()
if(DEFINED CMAKE_C_COMPILER_ID)
if(CMAKE_C_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static -fpic")
endif()
if(CMAKE_C_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Bstatic -fpic")
endif()
endif()
endif()