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.
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
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
this software without specific prior written permission.

View File

@ -1,2 +1,60 @@
# autocmake
CMake plugin composer.
# Autocmake
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()