Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
331b81bf32
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
|
.cache/
|
||||||
|
venv/
|
||||||
*.pyc
|
*.pyc
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
@ -5,7 +7,7 @@ __pycache__/
|
|||||||
test/*/CMakeLists.txt
|
test/*/CMakeLists.txt
|
||||||
test/*/build*/
|
test/*/build*/
|
||||||
test/*/cmake/update.py
|
test/*/cmake/update.py
|
||||||
test/*/cmake/lib/
|
test/*/cmake/autocmake/
|
||||||
test/*/cmake/downloaded/
|
test/*/cmake/downloaded/
|
||||||
test/*/setup
|
test/*/setup
|
||||||
|
|
||||||
|
38
.travis.yml
38
.travis.yml
@ -5,6 +5,7 @@ matrix:
|
|||||||
include:
|
include:
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
|
python: 2.7
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
env: SOURCES=ubuntu-toolchain-r-test
|
env: SOURCES=ubuntu-toolchain-r-test
|
||||||
addons:
|
addons:
|
||||||
@ -28,6 +29,30 @@ matrix:
|
|||||||
# boost
|
# boost
|
||||||
- libboost-all-dev
|
- libboost-all-dev
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
python: 3.5
|
||||||
|
compiler: gcc
|
||||||
|
env: SOURCES=ubuntu-toolchain-r-test
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
packages:
|
||||||
|
# compilers
|
||||||
|
- g++
|
||||||
|
- gfortran
|
||||||
|
# math libraries
|
||||||
|
- libblas-dev
|
||||||
|
- liblapack-dev
|
||||||
|
- libatlas-base-dev
|
||||||
|
# mpi
|
||||||
|
- openmpi-bin
|
||||||
|
- libopenmpi-dev
|
||||||
|
# python library, development version
|
||||||
|
- libpython2.7
|
||||||
|
# boost
|
||||||
|
- libboost-all-dev
|
||||||
|
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode6.4
|
osx_image: xcode6.4
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
@ -40,20 +65,21 @@ install:
|
|||||||
pip install virtualenv
|
pip install virtualenv
|
||||||
elif [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
elif [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||||
pip install --user virtualenv
|
pip install --user virtualenv
|
||||||
|
curl https://cmake.org/files/v3.5/cmake-3.5.2-Linux-x86_64.tar.gz | tar xvz
|
||||||
|
export PATH=~/cmake-3.5.2-Linux-x86_64/bin:$PATH
|
||||||
|
export LD_LIBARY_PATH=~/cmake-3.5.2-Linux-x86_64/lib:$LD_LIBRARY_PATH
|
||||||
fi
|
fi
|
||||||
- virtualenv venv
|
- virtualenv venv
|
||||||
- source venv/bin/activate
|
- source venv/bin/activate
|
||||||
- pip install pep8 pytest
|
- pip install -r requirements.txt
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# pep8 tests
|
# pep8 tests
|
||||||
- pep8 --ignore=E501 update.py
|
- pep8 --ignore E501 update.py
|
||||||
- pep8 --ignore=E501 test/test.py
|
- pep8 --ignore E501,E265 autocmake
|
||||||
- pep8 --ignore=E501 lib/config.py
|
|
||||||
# unit tests
|
# unit tests
|
||||||
- py.test -vv update.py
|
- py.test -vv autocmake/*
|
||||||
- py.test -vv test/test.py
|
- py.test -vv test/test.py
|
||||||
- py.test -vv lib/config.py
|
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
- Miroslav Ilias (Windows, portability, earliest adopter testing and feedback, math library testing)
|
- Miroslav Ilias (Windows, portability, earliest adopter testing and feedback, math library testing)
|
||||||
- Ivan Hrasko (Windows, Appveyor testing)
|
- Ivan Hrasko (Windows, Appveyor testing)
|
||||||
- Dan Jonsson (idea for configuration file approach)
|
- Dan Jonsson (idea for configuration file approach which preceded YAML solution)
|
||||||
- Roberto Di Remigio (design ideas and testing, OS X testing, Boost)
|
- Roberto Di Remigio (design ideas and testing, OS X testing, Boost)
|
||||||
|
|
||||||
For a list of all the contributions see https://github.com/scisoft/autocmake/contributors.
|
For a list of all the contributions,
|
||||||
|
see https://github.com/coderefinery/autocmake/contributors.
|
||||||
|
3
LICENSE
3
LICENSE
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2015-2016, Jonas Juselius and Radovan Bast
|
Copyright (c) 2015-2016 by Radovan Bast, Jonas Juselius, and contributors.
|
||||||
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
|
||||||
@ -25,4 +25,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
20
README.md
20
README.md
@ -1,23 +1,29 @@
|
|||||||
[](https://travis-ci.org/scisoft/autocmake/builds)
|
[](https://travis-ci.org/coderefinery/autocmake/builds)
|
||||||
[](https://ci.appveyor.com/project/bast/autocmake/history)
|
|
||||||
[](http://autocmake.readthedocs.org)
|
[](http://autocmake.readthedocs.org)
|
||||||
[](../master/LICENSE)
|
[](../master/LICENSE)
|
||||||
|
|
||||||
|

|
||||||
# Autocmake
|
|
||||||
|
|
||||||
A CMake plugin composer.
|
A CMake plugin composer.
|
||||||
Licensed under [BSD-3](../master/LICENSE).
|
Licensed under [BSD-3](../master/LICENSE).
|
||||||
See http://autocmake.org.
|
See http://autocmake.org.
|
||||||
|
|
||||||
|
|
||||||
### Projects using Autocmake
|
## Documentation
|
||||||
|
|
||||||
- [Numgrid](https://github.com/bast/numgrid/)
|
- [Latest stable code](http://autocmake.readthedocs.io/en/stable-0.x/) (stable-0.x branch)
|
||||||
- [XCint](https://github.com/bast/xcint/)
|
- [Bleeding edge code](http://autocmake.readthedocs.io/en/latest/) (master branch)
|
||||||
|
|
||||||
|
|
||||||
|
## Projects using Autocmake
|
||||||
|
|
||||||
|
- [Numgrid](https://github.com/dftlibs/numgrid/)
|
||||||
|
- [XCint](https://github.com/dftlibs/xcint/)
|
||||||
- [DIRAC](http://diracprogram.org)
|
- [DIRAC](http://diracprogram.org)
|
||||||
- [mathlib-tester](https://github.com/miroi/mathlibs-tester)
|
- [mathlib-tester](https://github.com/miroi/mathlibs-tester)
|
||||||
- [Fortran Input Reader](https://github.com/miroi/fortran_input_reader)
|
- [Fortran Input Reader](https://github.com/miroi/fortran_input_reader)
|
||||||
- [PCMSolver](https://github.com/PCMSolver/pcmsolver)
|
- [PCMSolver](https://github.com/PCMSolver/pcmsolver)
|
||||||
|
- GRASP: General-purpose Relativistic Atomic Structure Program
|
||||||
|
- [MRChem](https://github.com/MRChemSoft/mrchem)
|
||||||
|
|
||||||
If you use Autocmake, please link to your project via a pull request.
|
If you use Autocmake, please link to your project via a pull request.
|
||||||
|
57
appveyor.yml
57
appveyor.yml
@ -1,57 +0,0 @@
|
|||||||
# OS: 64-bit Windows Server 2012 R2
|
|
||||||
# Compilers: 64-bit MinGw-w64 5.1.0 (downloaded during script execution)
|
|
||||||
# Python: 2.7, 64-bit
|
|
||||||
# "ps:" commands are executed in PowerShell
|
|
||||||
|
|
||||||
# build version format: 1.0.1, 1.0.2, ...
|
|
||||||
version: 1.0.{build}
|
|
||||||
|
|
||||||
# prepare environment
|
|
||||||
environment:
|
|
||||||
# set custom path (will be more extended later in build_script section)
|
|
||||||
path: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Git\cmd;C:\Program Files\7-Zip;C:\Program Files (x86)\CMake\bin
|
|
||||||
# set MinGw-w64 (64-bit) version 5.1.0 download URL
|
|
||||||
url: http://kent.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/5.1.0/threads-posix/seh/x86_64-5.1.0-release-posix-seh-rt_v4-rev0.7z
|
|
||||||
matrix:
|
|
||||||
# - python: C:\Python27;C:\Python27\Scripts
|
|
||||||
- python: C:\Python27-x64;C:\Python27-x64\Scripts
|
|
||||||
# - python: C:\Python34;C:\Python34\Scripts
|
|
||||||
# - python: C:\Python34-x64;C:\Python34-x64\Scripts
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
# add location of used Python to path
|
|
||||||
- set path=%path%;%python%
|
|
||||||
|
|
||||||
# create dir for custom software and move there
|
|
||||||
- mkdir C:\software && cd C:\software
|
|
||||||
|
|
||||||
# download and unpack MinGw-w64 compilers
|
|
||||||
- ps: wget $env:url -OutFile MinGW.7z
|
|
||||||
- 7z x MinGW.7z > NUL
|
|
||||||
# add compilers binary dir to path
|
|
||||||
- set path=%path%;C:\software\mingw64\bin
|
|
||||||
|
|
||||||
# download and unpack the OpenBLAS library, integer*4 (or i32lp64) version
|
|
||||||
- ps: wget http://skylink.dl.sourceforge.net/project/openblas/v0.2.14/OpenBLAS-v0.2.14-Win64-int32.zip -OutFile OpenBLAS-v0.2.14-Win64-int32.zip
|
|
||||||
- 7z x OpenBLAS-v0.2.14-Win64-int32.zip > NUL
|
|
||||||
# add both OpenBLAS dynamic (libopenblas.dll) and static (libopenblas.a) library files dir to path
|
|
||||||
- set path=%path%;C:\software\OpenBLAS-v0.2.14-Win64-int32\bin;C:\software\OpenBLAS-v0.2.14-Win64-int32\lib;C:\software\OpenBLAS-v0.2.14-Win64-int32\include
|
|
||||||
|
|
||||||
# download and upgrade pip
|
|
||||||
- ps: wget https://bootstrap.pypa.io/get-pip.py -OutFile get-pip.py
|
|
||||||
- python get-pip.py
|
|
||||||
|
|
||||||
# install py.test
|
|
||||||
- pip install pytest
|
|
||||||
|
|
||||||
# go back to project source dir
|
|
||||||
- cd %APPVEYOR_BUILD_FOLDER%
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
# show environment
|
|
||||||
- echo %path%
|
|
||||||
- py.test --version
|
|
||||||
# run tests
|
|
||||||
- py.test -vv update.py
|
|
||||||
- py.test -vv test/test.py
|
|
||||||
- py.test -vv lib/config.py
|
|
1
autocmake/__init__.py
Normal file
1
autocmake/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
__version__ = '1.0.0-alpha-x'
|
@ -1,12 +1,5 @@
|
|||||||
|
|
||||||
# Copyright (c) 2015 by Radovan Bast and Jonas Juselius
|
|
||||||
# See https://github.com/scisoft/autocmake/blob/master/LICENSE
|
|
||||||
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
|
||||||
|
|
||||||
|
|
||||||
def module_exists(module_name):
|
def module_exists(module_name):
|
||||||
@ -23,10 +16,12 @@ def check_cmake_exists(cmake_command):
|
|||||||
Check whether CMake is installed. If not, print
|
Check whether CMake is installed. If not, print
|
||||||
informative error message and quits.
|
informative error message and quits.
|
||||||
"""
|
"""
|
||||||
p = subprocess.Popen('%s --version' % cmake_command,
|
from subprocess import Popen, PIPE
|
||||||
shell=True,
|
|
||||||
stdin=subprocess.PIPE,
|
p = Popen('{0} --version'.format(cmake_command),
|
||||||
stdout=subprocess.PIPE)
|
shell=True,
|
||||||
|
stdin=PIPE,
|
||||||
|
stdout=PIPE)
|
||||||
if not ('cmake version' in p.communicate()[0].decode('UTF-8')):
|
if not ('cmake version' in p.communicate()[0].decode('UTF-8')):
|
||||||
sys.stderr.write(' This code is built using CMake\n\n')
|
sys.stderr.write(' This code is built using CMake\n\n')
|
||||||
sys.stderr.write(' CMake is not found\n')
|
sys.stderr.write(' CMake is not found\n')
|
||||||
@ -46,7 +41,7 @@ def setup_build_path(build_path):
|
|||||||
fname = os.path.join(build_path, 'CMakeCache.txt')
|
fname = os.path.join(build_path, 'CMakeCache.txt')
|
||||||
if os.path.exists(fname):
|
if os.path.exists(fname):
|
||||||
sys.stderr.write('aborting setup\n')
|
sys.stderr.write('aborting setup\n')
|
||||||
sys.stderr.write('build directory %s which contains CMakeCache.txt already exists\n' % build_path)
|
sys.stderr.write('build directory {0} which contains CMakeCache.txt already exists\n'.format(build_path))
|
||||||
sys.stderr.write('remove the build directory and then rerun setup\n')
|
sys.stderr.write('remove the build directory and then rerun setup\n')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
@ -74,7 +69,7 @@ def adapt_cmake_command_to_platform(cmake_command, platform):
|
|||||||
"""
|
"""
|
||||||
if platform == 'win32':
|
if platform == 'win32':
|
||||||
pos = cmake_command.find('cmake')
|
pos = cmake_command.find('cmake')
|
||||||
s = ['set %s &&' % e for e in cmake_command[:pos].split()]
|
s = ['set {0} &&'.format(e) for e in cmake_command[:pos].split()]
|
||||||
s.append(cmake_command[pos:])
|
s.append(cmake_command[pos:])
|
||||||
return ' '.join(s)
|
return ' '.join(s)
|
||||||
else:
|
else:
|
||||||
@ -85,33 +80,40 @@ def run_cmake(command, build_path, default_build_path):
|
|||||||
"""
|
"""
|
||||||
Execute CMake command.
|
Execute CMake command.
|
||||||
"""
|
"""
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
from shutil import rmtree
|
||||||
|
|
||||||
topdir = os.getcwd()
|
topdir = os.getcwd()
|
||||||
os.chdir(build_path)
|
os.chdir(build_path)
|
||||||
p = subprocess.Popen(command,
|
p = Popen(command,
|
||||||
shell=True,
|
shell=True,
|
||||||
stdin=subprocess.PIPE,
|
stdin=PIPE,
|
||||||
stdout=subprocess.PIPE,
|
stdout=PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=PIPE)
|
||||||
stdout_coded, stderr_coded = p.communicate()
|
stdout_coded, stderr_coded = p.communicate()
|
||||||
stdout = stdout_coded.decode('UTF-8')
|
stdout = stdout_coded.decode('UTF-8')
|
||||||
stderr = stderr_coded.decode('UTF-8')
|
stderr = stderr_coded.decode('UTF-8')
|
||||||
|
|
||||||
|
# print cmake output to screen
|
||||||
|
print(stdout)
|
||||||
|
|
||||||
if stderr:
|
if stderr:
|
||||||
sys.stderr.write(stderr)
|
sys.stderr.write(stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
# print cmake output to screen
|
|
||||||
print(stdout)
|
|
||||||
# write cmake output to file
|
# write cmake output to file
|
||||||
f = open('cmake_output', 'w')
|
with open('cmake_output', 'w') as f:
|
||||||
f.write(stdout)
|
f.write(stdout)
|
||||||
f.close()
|
|
||||||
# change directory and return
|
# change directory and return
|
||||||
os.chdir(topdir)
|
os.chdir(topdir)
|
||||||
|
|
||||||
if 'Configuring incomplete' in stdout:
|
if 'Configuring incomplete' in stdout:
|
||||||
# configuration was not successful
|
# configuration was not successful
|
||||||
if (build_path == default_build_path):
|
if (build_path == default_build_path):
|
||||||
# remove build_path iff not set by the user
|
# remove build_path iff not set by the user
|
||||||
# otherwise removal can be dangerous
|
# otherwise removal can be dangerous
|
||||||
shutil.rmtree(default_build_path)
|
rmtree(default_build_path)
|
||||||
else:
|
else:
|
||||||
# configuration was successful
|
# configuration was successful
|
||||||
save_setup_command(sys.argv, build_path)
|
save_setup_command(sys.argv, build_path)
|
||||||
@ -136,9 +138,8 @@ def save_setup_command(argv, build_path):
|
|||||||
Save setup command to a file.
|
Save setup command to a file.
|
||||||
"""
|
"""
|
||||||
file_name = os.path.join(build_path, 'setup_command')
|
file_name = os.path.join(build_path, 'setup_command')
|
||||||
f = open(file_name, 'w')
|
with open(file_name, 'w') as f:
|
||||||
f.write(' '.join(argv[:]) + '\n')
|
f.write(' '.join(argv[:]) + '\n')
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
def configure(root_directory, build_path, cmake_command, only_show):
|
def configure(root_directory, build_path, cmake_command, only_show):
|
||||||
@ -158,7 +159,7 @@ def configure(root_directory, build_path, cmake_command, only_show):
|
|||||||
|
|
||||||
cmake_command = adapt_cmake_command_to_platform(cmake_command, sys.platform)
|
cmake_command = adapt_cmake_command_to_platform(cmake_command, sys.platform)
|
||||||
|
|
||||||
print('%s\n' % cmake_command)
|
print('{0}\n'.format(cmake_command))
|
||||||
if only_show:
|
if only_show:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
1
autocmake/external/__init__.py
vendored
Normal file
1
autocmake/external/__init__.py
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
# empty - this line is here to avoid problem when fetching empty files from web
|
228
lib/docopt/docopt.py → autocmake/external/docopt.py
vendored
228
lib/docopt/docopt.py → autocmake/external/docopt.py
vendored
@ -11,7 +11,7 @@ import re
|
|||||||
|
|
||||||
|
|
||||||
__all__ = ['docopt']
|
__all__ = ['docopt']
|
||||||
__version__ = '0.6.1'
|
__version__ = '0.6.2'
|
||||||
|
|
||||||
|
|
||||||
class DocoptLanguageError(Exception):
|
class DocoptLanguageError(Exception):
|
||||||
@ -47,18 +47,18 @@ class Pattern(object):
|
|||||||
if not hasattr(self, 'children'):
|
if not hasattr(self, 'children'):
|
||||||
return self
|
return self
|
||||||
uniq = list(set(self.flat())) if uniq is None else uniq
|
uniq = list(set(self.flat())) if uniq is None else uniq
|
||||||
for i, child in enumerate(self.children):
|
for i, c in enumerate(self.children):
|
||||||
if not hasattr(child, 'children'):
|
if not hasattr(c, 'children'):
|
||||||
assert child in uniq
|
assert c in uniq
|
||||||
self.children[i] = uniq[uniq.index(child)]
|
self.children[i] = uniq[uniq.index(c)]
|
||||||
else:
|
else:
|
||||||
child.fix_identities(uniq)
|
c.fix_identities(uniq)
|
||||||
|
|
||||||
def fix_repeating_arguments(self):
|
def fix_repeating_arguments(self):
|
||||||
"""Fix elements that should accumulate/increment values."""
|
"""Fix elements that should accumulate/increment values."""
|
||||||
either = [list(child.children) for child in transform(self).children]
|
either = [list(c.children) for c in self.either.children]
|
||||||
for case in either:
|
for case in either:
|
||||||
for e in [child for child in case if case.count(child) > 1]:
|
for e in [c for c in case if case.count(c) > 1]:
|
||||||
if type(e) is Argument or type(e) is Option and e.argcount:
|
if type(e) is Argument or type(e) is Option and e.argcount:
|
||||||
if e.value is None:
|
if e.value is None:
|
||||||
e.value = []
|
e.value = []
|
||||||
@ -68,40 +68,47 @@ class Pattern(object):
|
|||||||
e.value = 0
|
e.value = 0
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@property
|
||||||
def transform(pattern):
|
def either(self):
|
||||||
"""Expand pattern into an (almost) equivalent one, but with single Either.
|
"""Transform pattern into an equivalent, with only top-level Either."""
|
||||||
|
# Currently the pattern will not be equivalent, but more "narrow",
|
||||||
Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d)
|
# although good enough to reason about list arguments.
|
||||||
Quirks: [-a] => (-a), (-a...) => (-a -a)
|
ret = []
|
||||||
|
groups = [[self]]
|
||||||
"""
|
while groups:
|
||||||
result = []
|
children = groups.pop(0)
|
||||||
groups = [[pattern]]
|
types = [type(c) for c in children]
|
||||||
while groups:
|
if Either in types:
|
||||||
children = groups.pop(0)
|
either = [c for c in children if type(c) is Either][0]
|
||||||
parents = [Required, Optional, OptionsShortcut, Either, OneOrMore]
|
children.pop(children.index(either))
|
||||||
if any(t in map(type, children) for t in parents):
|
for c in either.children:
|
||||||
child = [c for c in children if type(c) in parents][0]
|
|
||||||
children.remove(child)
|
|
||||||
if type(child) is Either:
|
|
||||||
for c in child.children:
|
|
||||||
groups.append([c] + children)
|
groups.append([c] + children)
|
||||||
elif type(child) is OneOrMore:
|
elif Required in types:
|
||||||
groups.append(child.children * 2 + children)
|
required = [c for c in children if type(c) is Required][0]
|
||||||
|
children.pop(children.index(required))
|
||||||
|
groups.append(list(required.children) + children)
|
||||||
|
elif Optional in types:
|
||||||
|
optional = [c for c in children if type(c) is Optional][0]
|
||||||
|
children.pop(children.index(optional))
|
||||||
|
groups.append(list(optional.children) + children)
|
||||||
|
elif AnyOptions in types:
|
||||||
|
optional = [c for c in children if type(c) is AnyOptions][0]
|
||||||
|
children.pop(children.index(optional))
|
||||||
|
groups.append(list(optional.children) + children)
|
||||||
|
elif OneOrMore in types:
|
||||||
|
oneormore = [c for c in children if type(c) is OneOrMore][0]
|
||||||
|
children.pop(children.index(oneormore))
|
||||||
|
groups.append(list(oneormore.children) * 2 + children)
|
||||||
else:
|
else:
|
||||||
groups.append(child.children + children)
|
ret.append(children)
|
||||||
else:
|
return Either(*[Required(*e) for e in ret])
|
||||||
result.append(children)
|
|
||||||
return Either(*[Required(*e) for e in result])
|
|
||||||
|
|
||||||
|
|
||||||
class LeafPattern(Pattern):
|
class ChildPattern(Pattern):
|
||||||
|
|
||||||
"""Leaf/terminal node of a pattern tree."""
|
|
||||||
|
|
||||||
def __init__(self, name, value=None):
|
def __init__(self, name, value=None):
|
||||||
self.name, self.value = name, value
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '%s(%r, %r)' % (self.__class__.__name__, self.name, self.value)
|
return '%s(%r, %r)' % (self.__class__.__name__, self.name, self.value)
|
||||||
@ -130,9 +137,7 @@ class LeafPattern(Pattern):
|
|||||||
return True, left_, collected + [match]
|
return True, left_, collected + [match]
|
||||||
|
|
||||||
|
|
||||||
class BranchPattern(Pattern):
|
class ParentPattern(Pattern):
|
||||||
|
|
||||||
"""Branch/inner node of a pattern tree."""
|
|
||||||
|
|
||||||
def __init__(self, *children):
|
def __init__(self, *children):
|
||||||
self.children = list(children)
|
self.children = list(children)
|
||||||
@ -144,15 +149,15 @@ class BranchPattern(Pattern):
|
|||||||
def flat(self, *types):
|
def flat(self, *types):
|
||||||
if type(self) in types:
|
if type(self) in types:
|
||||||
return [self]
|
return [self]
|
||||||
return sum([child.flat(*types) for child in self.children], [])
|
return sum([c.flat(*types) for c in self.children], [])
|
||||||
|
|
||||||
|
|
||||||
class Argument(LeafPattern):
|
class Argument(ChildPattern):
|
||||||
|
|
||||||
def single_match(self, left):
|
def single_match(self, left):
|
||||||
for n, pattern in enumerate(left):
|
for n, p in enumerate(left):
|
||||||
if type(pattern) is Argument:
|
if type(p) is Argument:
|
||||||
return n, Argument(self.name, pattern.value)
|
return n, Argument(self.name, p.value)
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -165,23 +170,25 @@ class Argument(LeafPattern):
|
|||||||
class Command(Argument):
|
class Command(Argument):
|
||||||
|
|
||||||
def __init__(self, name, value=False):
|
def __init__(self, name, value=False):
|
||||||
self.name, self.value = name, value
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
def single_match(self, left):
|
def single_match(self, left):
|
||||||
for n, pattern in enumerate(left):
|
for n, p in enumerate(left):
|
||||||
if type(pattern) is Argument:
|
if type(p) is Argument:
|
||||||
if pattern.value == self.name:
|
if p.value == self.name:
|
||||||
return n, Command(self.name, True)
|
return n, Command(self.name, True)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
class Option(LeafPattern):
|
class Option(ChildPattern):
|
||||||
|
|
||||||
def __init__(self, short=None, long=None, argcount=0, value=False):
|
def __init__(self, short=None, long=None, argcount=0, value=False):
|
||||||
assert argcount in (0, 1)
|
assert argcount in (0, 1)
|
||||||
self.short, self.long, self.argcount = short, long, argcount
|
self.short, self.long = short, long
|
||||||
|
self.argcount, self.value = argcount, value
|
||||||
self.value = None if value is False and argcount else value
|
self.value = None if value is False and argcount else value
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -202,9 +209,9 @@ class Option(LeafPattern):
|
|||||||
return class_(short, long, argcount, value)
|
return class_(short, long, argcount, value)
|
||||||
|
|
||||||
def single_match(self, left):
|
def single_match(self, left):
|
||||||
for n, pattern in enumerate(left):
|
for n, p in enumerate(left):
|
||||||
if self.name == pattern.name:
|
if self.name == p.name:
|
||||||
return n, pattern
|
return n, p
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -216,34 +223,34 @@ class Option(LeafPattern):
|
|||||||
self.argcount, self.value)
|
self.argcount, self.value)
|
||||||
|
|
||||||
|
|
||||||
class Required(BranchPattern):
|
class Required(ParentPattern):
|
||||||
|
|
||||||
def match(self, left, collected=None):
|
def match(self, left, collected=None):
|
||||||
collected = [] if collected is None else collected
|
collected = [] if collected is None else collected
|
||||||
l = left
|
l = left
|
||||||
c = collected
|
c = collected
|
||||||
for pattern in self.children:
|
for p in self.children:
|
||||||
matched, l, c = pattern.match(l, c)
|
matched, l, c = p.match(l, c)
|
||||||
if not matched:
|
if not matched:
|
||||||
return False, left, collected
|
return False, left, collected
|
||||||
return True, l, c
|
return True, l, c
|
||||||
|
|
||||||
|
|
||||||
class Optional(BranchPattern):
|
class Optional(ParentPattern):
|
||||||
|
|
||||||
def match(self, left, collected=None):
|
def match(self, left, collected=None):
|
||||||
collected = [] if collected is None else collected
|
collected = [] if collected is None else collected
|
||||||
for pattern in self.children:
|
for p in self.children:
|
||||||
m, left, collected = pattern.match(left, collected)
|
m, left, collected = p.match(left, collected)
|
||||||
return True, left, collected
|
return True, left, collected
|
||||||
|
|
||||||
|
|
||||||
class OptionsShortcut(Optional):
|
class AnyOptions(Optional):
|
||||||
|
|
||||||
"""Marker/placeholder for [options] shortcut."""
|
"""Marker/placeholder for [options] shortcut."""
|
||||||
|
|
||||||
|
|
||||||
class OneOrMore(BranchPattern):
|
class OneOrMore(ParentPattern):
|
||||||
|
|
||||||
def match(self, left, collected=None):
|
def match(self, left, collected=None):
|
||||||
assert len(self.children) == 1
|
assert len(self.children) == 1
|
||||||
@ -265,13 +272,13 @@ class OneOrMore(BranchPattern):
|
|||||||
return False, left, collected
|
return False, left, collected
|
||||||
|
|
||||||
|
|
||||||
class Either(BranchPattern):
|
class Either(ParentPattern):
|
||||||
|
|
||||||
def match(self, left, collected=None):
|
def match(self, left, collected=None):
|
||||||
collected = [] if collected is None else collected
|
collected = [] if collected is None else collected
|
||||||
outcomes = []
|
outcomes = []
|
||||||
for pattern in self.children:
|
for p in self.children:
|
||||||
matched, _, _ = outcome = pattern.match(left, collected)
|
matched, _, _ = outcome = p.match(left, collected)
|
||||||
if matched:
|
if matched:
|
||||||
outcomes.append(outcome)
|
outcomes.append(outcome)
|
||||||
if outcomes:
|
if outcomes:
|
||||||
@ -279,18 +286,12 @@ class Either(BranchPattern):
|
|||||||
return False, left, collected
|
return False, left, collected
|
||||||
|
|
||||||
|
|
||||||
class Tokens(list):
|
class TokenStream(list):
|
||||||
|
|
||||||
def __init__(self, source, error=DocoptExit):
|
def __init__(self, source, error):
|
||||||
self += source.split() if hasattr(source, 'split') else source
|
self += source.split() if hasattr(source, 'split') else source
|
||||||
self.error = error
|
self.error = error
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_pattern(source):
|
|
||||||
source = re.sub(r'([\[\]\(\)\|]|\.\.\.)', r' \1 ', source)
|
|
||||||
source = [s for s in re.split('\s+|(\S*<.*?>)', source) if s]
|
|
||||||
return Tokens(source, error=DocoptLanguageError)
|
|
||||||
|
|
||||||
def move(self):
|
def move(self):
|
||||||
return self.pop(0) if len(self) else None
|
return self.pop(0) if len(self) else None
|
||||||
|
|
||||||
@ -323,7 +324,7 @@ def parse_long(tokens, options):
|
|||||||
raise tokens.error('%s must not have an argument' % o.long)
|
raise tokens.error('%s must not have an argument' % o.long)
|
||||||
else:
|
else:
|
||||||
if value is None:
|
if value is None:
|
||||||
if tokens.current() in [None, '--']:
|
if tokens.current() is None:
|
||||||
raise tokens.error('%s requires argument' % o.long)
|
raise tokens.error('%s requires argument' % o.long)
|
||||||
value = tokens.move()
|
value = tokens.move()
|
||||||
if tokens.error is DocoptExit:
|
if tokens.error is DocoptExit:
|
||||||
@ -354,7 +355,7 @@ def parse_shorts(tokens, options):
|
|||||||
value = None
|
value = None
|
||||||
if o.argcount != 0:
|
if o.argcount != 0:
|
||||||
if left == '':
|
if left == '':
|
||||||
if tokens.current() in [None, '--']:
|
if tokens.current() is None:
|
||||||
raise tokens.error('%s requires argument' % short)
|
raise tokens.error('%s requires argument' % short)
|
||||||
value = tokens.move()
|
value = tokens.move()
|
||||||
else:
|
else:
|
||||||
@ -367,7 +368,8 @@ def parse_shorts(tokens, options):
|
|||||||
|
|
||||||
|
|
||||||
def parse_pattern(source, options):
|
def parse_pattern(source, options):
|
||||||
tokens = Tokens.from_pattern(source)
|
tokens = TokenStream(re.sub(r'([\[\]\(\)\|]|\.\.\.)', r' \1 ', source),
|
||||||
|
DocoptLanguageError)
|
||||||
result = parse_expr(tokens, options)
|
result = parse_expr(tokens, options)
|
||||||
if tokens.current() is not None:
|
if tokens.current() is not None:
|
||||||
raise tokens.error('unexpected ending: %r' % ' '.join(tokens))
|
raise tokens.error('unexpected ending: %r' % ' '.join(tokens))
|
||||||
@ -414,7 +416,7 @@ def parse_atom(tokens, options):
|
|||||||
return [result]
|
return [result]
|
||||||
elif token == 'options':
|
elif token == 'options':
|
||||||
tokens.move()
|
tokens.move()
|
||||||
return [OptionsShortcut()]
|
return [AnyOptions()]
|
||||||
elif token.startswith('--') and token != '--':
|
elif token.startswith('--') and token != '--':
|
||||||
return parse_long(tokens, options)
|
return parse_long(tokens, options)
|
||||||
elif token.startswith('-') and token not in ('-', '--'):
|
elif token.startswith('-') and token not in ('-', '--'):
|
||||||
@ -450,26 +452,27 @@ def parse_argv(tokens, options, options_first=False):
|
|||||||
|
|
||||||
|
|
||||||
def parse_defaults(doc):
|
def parse_defaults(doc):
|
||||||
defaults = []
|
# in python < 2.7 you can't pass flags=re.MULTILINE
|
||||||
for s in parse_section('options:', doc):
|
split = re.split('\n *(<\S+?>|-\S+?)', doc)[1:]
|
||||||
# FIXME corner case "bla: options: --foo"
|
split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])]
|
||||||
_, _, s = s.partition(':') # get rid of "options:"
|
options = [Option.parse(s) for s in split if s.startswith('-')]
|
||||||
split = re.split('\n[ \t]*(-\S+?)', '\n' + s)[1:]
|
#arguments = [Argument.parse(s) for s in split if s.startswith('<')]
|
||||||
split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])]
|
#return options, arguments
|
||||||
options = [Option.parse(s) for s in split if s.startswith('-')]
|
return options
|
||||||
defaults += options
|
|
||||||
return defaults
|
|
||||||
|
|
||||||
|
|
||||||
def parse_section(name, source):
|
def printable_usage(doc):
|
||||||
pattern = re.compile('^([^\n]*' + name + '[^\n]*\n?(?:[ \t].*?(?:\n|$))*)',
|
# in python < 2.7 you can't pass flags=re.IGNORECASE
|
||||||
re.IGNORECASE | re.MULTILINE)
|
usage_split = re.split(r'([Uu][Ss][Aa][Gg][Ee]:)', doc)
|
||||||
return [s.strip() for s in pattern.findall(source)]
|
if len(usage_split) < 3:
|
||||||
|
raise DocoptLanguageError('"usage:" (case-insensitive) not found.')
|
||||||
|
if len(usage_split) > 3:
|
||||||
|
raise DocoptLanguageError('More than one "usage:" (case-insensitive).')
|
||||||
|
return re.split(r'\n\s*\n', ''.join(usage_split[1:]))[0].strip()
|
||||||
|
|
||||||
|
|
||||||
def formal_usage(section):
|
def formal_usage(printable_usage):
|
||||||
_, _, section = section.partition(':') # drop "usage:"
|
pu = printable_usage.split()[1:] # split and drop "usage:"
|
||||||
pu = section.split()
|
|
||||||
return '( ' + ' '.join(') | (' if s == pu[0] else s for s in pu[1:]) + ' )'
|
return '( ' + ' '.join(') | (' if s == pu[0] else s for s in pu[1:]) + ' )'
|
||||||
|
|
||||||
|
|
||||||
@ -509,7 +512,7 @@ def docopt(doc, argv=None, help=True, version=None, options_first=False):
|
|||||||
If passed, the object will be printed if --version is in
|
If passed, the object will be printed if --version is in
|
||||||
`argv`.
|
`argv`.
|
||||||
options_first : bool (default: False)
|
options_first : bool (default: False)
|
||||||
Set to True to require options precede positional arguments,
|
Set to True to require options preceed positional arguments,
|
||||||
i.e. to forbid options and positional arguments intermix.
|
i.e. to forbid options and positional arguments intermix.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
@ -523,15 +526,15 @@ def docopt(doc, argv=None, help=True, version=None, options_first=False):
|
|||||||
-------
|
-------
|
||||||
>>> from docopt import docopt
|
>>> from docopt import docopt
|
||||||
>>> doc = '''
|
>>> doc = '''
|
||||||
... Usage:
|
Usage:
|
||||||
... my_program tcp <host> <port> [--timeout=<seconds>]
|
my_program tcp <host> <port> [--timeout=<seconds>]
|
||||||
... my_program serial <port> [--baud=<n>] [--timeout=<seconds>]
|
my_program serial <port> [--baud=<n>] [--timeout=<seconds>]
|
||||||
... my_program (-h | --help | --version)
|
my_program (-h | --help | --version)
|
||||||
...
|
|
||||||
... Options:
|
Options:
|
||||||
... -h, --help Show this screen and exit.
|
-h, --help Show this screen and exit.
|
||||||
... --baud=<n> Baudrate [default: 9600]
|
--baud=<n> Baudrate [default: 9600]
|
||||||
... '''
|
'''
|
||||||
>>> argv = ['tcp', '127.0.0.1', '80', '--timeout', '30']
|
>>> argv = ['tcp', '127.0.0.1', '80', '--timeout', '30']
|
||||||
>>> docopt(doc, argv)
|
>>> docopt(doc, argv)
|
||||||
{'--baud': '9600',
|
{'--baud': '9600',
|
||||||
@ -550,15 +553,9 @@ def docopt(doc, argv=None, help=True, version=None, options_first=False):
|
|||||||
at https://github.com/docopt/docopt#readme
|
at https://github.com/docopt/docopt#readme
|
||||||
|
|
||||||
"""
|
"""
|
||||||
argv = sys.argv[1:] if argv is None else argv
|
if argv is None:
|
||||||
|
argv = sys.argv[1:]
|
||||||
usage_sections = parse_section('usage:', doc)
|
DocoptExit.usage = printable_usage(doc)
|
||||||
if len(usage_sections) == 0:
|
|
||||||
raise DocoptLanguageError('"usage:" (case-insensitive) not found.')
|
|
||||||
if len(usage_sections) > 1:
|
|
||||||
raise DocoptLanguageError('More than one "usage:" (case-insensitive).')
|
|
||||||
DocoptExit.usage = usage_sections[0]
|
|
||||||
|
|
||||||
options = parse_defaults(doc)
|
options = parse_defaults(doc)
|
||||||
pattern = parse_pattern(formal_usage(DocoptExit.usage), options)
|
pattern = parse_pattern(formal_usage(DocoptExit.usage), options)
|
||||||
# [default] syntax for argument is disabled
|
# [default] syntax for argument is disabled
|
||||||
@ -566,13 +563,14 @@ def docopt(doc, argv=None, help=True, version=None, options_first=False):
|
|||||||
# same_name = [d for d in arguments if d.name == a.name]
|
# same_name = [d for d in arguments if d.name == a.name]
|
||||||
# if same_name:
|
# if same_name:
|
||||||
# a.value = same_name[0].value
|
# a.value = same_name[0].value
|
||||||
argv = parse_argv(Tokens(argv), list(options), options_first)
|
argv = parse_argv(TokenStream(argv, DocoptExit), list(options),
|
||||||
|
options_first)
|
||||||
pattern_options = set(pattern.flat(Option))
|
pattern_options = set(pattern.flat(Option))
|
||||||
for options_shortcut in pattern.flat(OptionsShortcut):
|
for ao in pattern.flat(AnyOptions):
|
||||||
doc_options = parse_defaults(doc)
|
doc_options = parse_defaults(doc)
|
||||||
options_shortcut.children = list(set(doc_options) - pattern_options)
|
ao.children = list(set(doc_options) - pattern_options)
|
||||||
#if any_options:
|
#if any_options:
|
||||||
# options_shortcut.children += [Option(o.short, o.long, o.argcount)
|
# ao.children += [Option(o.short, o.long, o.argcount)
|
||||||
# for o in argv if type(o) is Option]
|
# for o in argv if type(o) is Option]
|
||||||
extras(help, version, argv, doc)
|
extras(help, version, argv, doc)
|
||||||
matched, left, collected = pattern.fix().match(argv)
|
matched, left, collected = pattern.fix().match(argv)
|
46
autocmake/extract.py
Normal file
46
autocmake/extract.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
def extract_list(config, section):
|
||||||
|
from collections import Iterable
|
||||||
|
l = []
|
||||||
|
if 'modules' in config:
|
||||||
|
for module in config['modules']:
|
||||||
|
for k, v in module.items():
|
||||||
|
for x in v:
|
||||||
|
if section in x:
|
||||||
|
if isinstance(x[section], Iterable) and not isinstance(x[section], str):
|
||||||
|
for y in x[section]:
|
||||||
|
l.append(y)
|
||||||
|
else:
|
||||||
|
l.append(x[section])
|
||||||
|
return l
|
||||||
|
|
||||||
|
|
||||||
|
def to_d(l):
|
||||||
|
"""
|
||||||
|
Converts list of dicts to dict.
|
||||||
|
"""
|
||||||
|
_d = {}
|
||||||
|
for x in l:
|
||||||
|
for k, v in x.items():
|
||||||
|
_d[k] = v
|
||||||
|
return _d
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_d():
|
||||||
|
l = [{'a': 'b'}, {'c': 'd'}]
|
||||||
|
d = {'a': 'b', 'c': 'd'}
|
||||||
|
assert to_d(l) == d
|
||||||
|
|
||||||
|
|
||||||
|
def to_l(x):
|
||||||
|
"""
|
||||||
|
Converts list of dicts to dict.
|
||||||
|
"""
|
||||||
|
if isinstance(x, str):
|
||||||
|
return [x]
|
||||||
|
else:
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
def test_to_l():
|
||||||
|
assert to_l('foo') == ['foo']
|
||||||
|
assert to_l(['foo', 'bar']) == ['foo', 'bar']
|
176
autocmake/generate.py
Normal file
176
autocmake/generate.py
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
def gen_cmake_command(config):
|
||||||
|
"""
|
||||||
|
Generate CMake command.
|
||||||
|
"""
|
||||||
|
from autocmake.extract import extract_list
|
||||||
|
|
||||||
|
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 = []")
|
||||||
|
|
||||||
|
for env in config['export']:
|
||||||
|
s.append(' command.append({0})'.format(env))
|
||||||
|
|
||||||
|
s.append(" command.append(arguments['--cmake-executable'])")
|
||||||
|
|
||||||
|
for definition in config['define']:
|
||||||
|
s.append(' command.append({0})'.format(definition))
|
||||||
|
|
||||||
|
s.append(" command.append('-DCMAKE_BUILD_TYPE={0}'.format(arguments['--type']))")
|
||||||
|
s.append(" command.append('-G \"{0}\"'.format(arguments['--generator']))")
|
||||||
|
s.append(" if arguments['--cmake-options'] != \"''\":")
|
||||||
|
s.append(" command.append(arguments['--cmake-options'])")
|
||||||
|
s.append(" if arguments['--prefix']:")
|
||||||
|
s.append(" command.append('-DCMAKE_INSTALL_PREFIX=\"{0}\"'.format(arguments['--prefix']))")
|
||||||
|
|
||||||
|
s.append("\n return ' '.join(command)")
|
||||||
|
|
||||||
|
return '\n'.join(s)
|
||||||
|
|
||||||
|
|
||||||
|
def autogenerated_notice():
|
||||||
|
from datetime import date
|
||||||
|
from . import __version__
|
||||||
|
|
||||||
|
current_year = date.today().year
|
||||||
|
year_range = '2015-{0}'.format(current_year)
|
||||||
|
|
||||||
|
s = []
|
||||||
|
s.append('# This file is autogenerated by Autocmake v{0} http://autocmake.org'.format(__version__))
|
||||||
|
s.append('# Copyright (c) {0} by Radovan Bast, Jonas Juselius, and contributors.'.format(year_range))
|
||||||
|
|
||||||
|
return '\n'.join(s)
|
||||||
|
|
||||||
|
|
||||||
|
def gen_setup(config, relative_path, setup_script_name):
|
||||||
|
"""
|
||||||
|
Generate setup script.
|
||||||
|
"""
|
||||||
|
from autocmake.extract import extract_list
|
||||||
|
|
||||||
|
s = []
|
||||||
|
s.append('#!/usr/bin/env python')
|
||||||
|
s.append('\n{0}'.format(autogenerated_notice()))
|
||||||
|
s.append('\nimport os')
|
||||||
|
s.append('import sys')
|
||||||
|
|
||||||
|
s.append("\nsys.path.insert(0, '{0}')".format(relative_path))
|
||||||
|
|
||||||
|
s.append('from autocmake import configure')
|
||||||
|
s.append('from autocmake.external import docopt')
|
||||||
|
|
||||||
|
s.append('\n\noptions = """')
|
||||||
|
s.append('Usage:')
|
||||||
|
s.append(' ./{0} [options] [<builddir>]'.format(setup_script_name))
|
||||||
|
s.append(' ./{0} (-h | --help)'.format(setup_script_name))
|
||||||
|
s.append('\nOptions:')
|
||||||
|
|
||||||
|
options = []
|
||||||
|
|
||||||
|
for opt in config['docopt']:
|
||||||
|
first = opt.split()[0].strip()
|
||||||
|
rest = ' '.join(opt.split()[1:]).strip()
|
||||||
|
options.append([first, rest])
|
||||||
|
|
||||||
|
options.append(['--type=<TYPE>', 'Set the CMake build type (debug, release, or relwithdeb) [default: release].'])
|
||||||
|
options.append(['--generator=<STRING>', 'Set the CMake build system generator [default: Unix Makefiles].'])
|
||||||
|
options.append(['--show', 'Show CMake command and exit.'])
|
||||||
|
options.append(['--cmake-executable=<CMAKE_EXECUTABLE>', 'Set the CMake executable [default: cmake].'])
|
||||||
|
options.append(['--cmake-options=<STRING>', "Define options to CMake [default: '']."])
|
||||||
|
options.append(['--prefix=<PATH>', 'Set the install path for make install.'])
|
||||||
|
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")
|
||||||
|
s.append("# parse command line args")
|
||||||
|
s.append("try:")
|
||||||
|
s.append(" arguments = docopt.docopt(options, argv=None)")
|
||||||
|
s.append("except docopt.DocoptExit:")
|
||||||
|
s.append(r" sys.stderr.write('ERROR: bad input to {0}\n'.format(sys.argv[0]))")
|
||||||
|
s.append(" sys.stderr.write(options)")
|
||||||
|
s.append(" sys.exit(-1)")
|
||||||
|
s.append("\n")
|
||||||
|
s.append("# use extensions to validate/post-process args")
|
||||||
|
s.append("if configure.module_exists('extensions'):")
|
||||||
|
s.append(" import extensions")
|
||||||
|
s.append(" arguments = extensions.postprocess_args(sys.argv, arguments)")
|
||||||
|
s.append("\n")
|
||||||
|
s.append("root_directory = os.path.dirname(os.path.realpath(__file__))")
|
||||||
|
s.append("\n")
|
||||||
|
s.append("build_path = arguments['<builddir>']")
|
||||||
|
s.append("\n")
|
||||||
|
s.append("# create cmake command")
|
||||||
|
s.append("cmake_command = '{0} {1}'.format(gen_cmake_command(options, arguments), root_directory)")
|
||||||
|
s.append("\n")
|
||||||
|
s.append("# run cmake")
|
||||||
|
s.append("configure.configure(root_directory, build_path, cmake_command, arguments['--show'])")
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def gen_cmakelists(project_name, min_cmake_version, relative_path, modules):
|
||||||
|
"""
|
||||||
|
Generate CMakeLists.txt.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
|
s = []
|
||||||
|
|
||||||
|
s.append(autogenerated_notice())
|
||||||
|
|
||||||
|
s.append('\n# set minimum cmake version')
|
||||||
|
s.append('cmake_minimum_required(VERSION {0} FATAL_ERROR)'.format(min_cmake_version))
|
||||||
|
|
||||||
|
s.append('\n# project name')
|
||||||
|
s.append('project({0})'.format(project_name))
|
||||||
|
|
||||||
|
s.append('\n# do not rebuild if rules (compiler flags) change')
|
||||||
|
s.append('set(CMAKE_SKIP_RULE_DEPENDENCY TRUE)')
|
||||||
|
|
||||||
|
s.append('\n# if CMAKE_BUILD_TYPE undefined, we set it to Debug')
|
||||||
|
s.append('if(NOT CMAKE_BUILD_TYPE)')
|
||||||
|
s.append(' set(CMAKE_BUILD_TYPE "Debug")')
|
||||||
|
s.append('endif()')
|
||||||
|
|
||||||
|
if len(modules) > 0:
|
||||||
|
s.append('\n# directories which hold included cmake modules')
|
||||||
|
|
||||||
|
module_paths = [module.path for module in modules]
|
||||||
|
module_paths.append('downloaded') # this is done to be able to find fetched modules when testing
|
||||||
|
module_paths = list(set(module_paths))
|
||||||
|
module_paths.sort() # we do this to always get the same order and to minimize diffs
|
||||||
|
for directory in module_paths:
|
||||||
|
rel_cmake_module_path = os.path.join(relative_path, directory)
|
||||||
|
# on windows cmake corrects this so we have to make it wrong again
|
||||||
|
rel_cmake_module_path = rel_cmake_module_path.replace('\\', '/')
|
||||||
|
s.append('set(CMAKE_MODULE_PATH ${{CMAKE_MODULE_PATH}} ${{PROJECT_SOURCE_DIR}}/{0})'.format(rel_cmake_module_path))
|
||||||
|
|
||||||
|
if len(modules) > 0:
|
||||||
|
s.append('\n# included cmake modules')
|
||||||
|
for module in modules:
|
||||||
|
s.append('include({0})'.format(os.path.splitext(module.name)[0]))
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def align_options(options):
|
||||||
|
"""
|
||||||
|
Indents 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(' {0}{1} {2}'.format(opt[0], ' ' * (l - len(opt[0])), opt[1]))
|
||||||
|
return '\n'.join(s)
|
66
autocmake/interpolate.py
Normal file
66
autocmake/interpolate.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
def replace(s, d):
|
||||||
|
from re import findall
|
||||||
|
|
||||||
|
if isinstance(s, str):
|
||||||
|
for var in findall(r"%\(([A-Za-z0-9_]*)\)", s):
|
||||||
|
s = s.replace("%({0})".format(var), str(d[var]))
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def test_replace():
|
||||||
|
assert replace('hey %(foo) ho %(bar)',
|
||||||
|
{'foo': 'hey', 'bar': 'ho'}) == 'hey hey ho ho'
|
||||||
|
|
||||||
|
|
||||||
|
def interpolate(d, d_map):
|
||||||
|
from collections import Mapping, Iterable
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
|
for k, v in d.items():
|
||||||
|
if isinstance(v, Mapping):
|
||||||
|
d[k] = interpolate(d[k], d_map)
|
||||||
|
elif isinstance(v, Iterable) and not isinstance(v, str):
|
||||||
|
l = []
|
||||||
|
for x in v:
|
||||||
|
if isinstance(x, Mapping):
|
||||||
|
l.append(interpolate(x, d_map))
|
||||||
|
else:
|
||||||
|
l.append(replace(x, d_map))
|
||||||
|
d[k] = copy(l)
|
||||||
|
else:
|
||||||
|
d[k] = replace(d[k], d_map)
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def test_interpolate():
|
||||||
|
d = {'foo': 'hey',
|
||||||
|
'bar': 'ho',
|
||||||
|
'one': 'hey %(foo) ho %(bar)',
|
||||||
|
'two': {'one': 'hey %(foo) ho %(bar)',
|
||||||
|
'two': 'raboof'}}
|
||||||
|
d_interpolated = {'foo': 'hey',
|
||||||
|
'bar': 'ho',
|
||||||
|
'one': 'hey hey ho ho',
|
||||||
|
'two': {'one': 'hey hey ho ho',
|
||||||
|
'two': 'raboof'}}
|
||||||
|
assert interpolate(d, d) == d_interpolated
|
||||||
|
|
||||||
|
|
||||||
|
def test_interpolate_int():
|
||||||
|
d = {'foo': 1,
|
||||||
|
'bar': 2,
|
||||||
|
'one': 'hey %(foo) ho %(bar)',
|
||||||
|
'two': {'one': 'hey %(foo) ho %(bar)',
|
||||||
|
'two': 'raboof'}}
|
||||||
|
d_interpolated = {'foo': 1,
|
||||||
|
'bar': 2,
|
||||||
|
'one': 'hey 1 ho 2',
|
||||||
|
'two': {'one': 'hey 1 ho 2',
|
||||||
|
'two': 'raboof'}}
|
||||||
|
assert interpolate(d, d) == d_interpolated
|
||||||
|
|
||||||
|
|
||||||
|
def test_interpolate_nested():
|
||||||
|
d2 = {'modules': [{'fc': [{'source': '%(url_root)fc_optional.cmake'}]}], 'url_root': 'downloaded/downloaded_'}
|
||||||
|
d2_interpolated = {'modules': [{'fc': [{'source': 'downloaded/downloaded_fc_optional.cmake'}]}], 'url_root': 'downloaded/downloaded_'}
|
||||||
|
assert interpolate(d2, d2) == d2_interpolated
|
132
autocmake/parse_rst.py
Normal file
132
autocmake/parse_rst.py
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
def parse_cmake_module(s_in, overrides={}):
|
||||||
|
import sys
|
||||||
|
from collections import Mapping, Iterable, defaultdict
|
||||||
|
from autocmake.parse_yaml import parse_yaml
|
||||||
|
|
||||||
|
# we do not use the nicer sys.version_info.major
|
||||||
|
# for compatibility with Python < 2.7
|
||||||
|
if sys.version_info[0] > 2:
|
||||||
|
from io import StringIO
|
||||||
|
else:
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
|
parsed_config = defaultdict(lambda: None)
|
||||||
|
|
||||||
|
if 'autocmake.yml configuration::' not in s_in:
|
||||||
|
return parsed_config
|
||||||
|
|
||||||
|
s_out = []
|
||||||
|
is_rst_line = False
|
||||||
|
for line in s_in.split('\n'):
|
||||||
|
if is_rst_line:
|
||||||
|
if len(line) > 0:
|
||||||
|
if line[0] != '#':
|
||||||
|
is_rst_line = False
|
||||||
|
else:
|
||||||
|
is_rst_line = False
|
||||||
|
if is_rst_line:
|
||||||
|
s_out.append(line[2:])
|
||||||
|
if '#.rst:' in line:
|
||||||
|
is_rst_line = True
|
||||||
|
|
||||||
|
autocmake_entry = '\n'.join(s_out).split('autocmake.yml configuration::')[1]
|
||||||
|
autocmake_entry = autocmake_entry.replace('\n ', '\n')
|
||||||
|
|
||||||
|
buf = StringIO(autocmake_entry)
|
||||||
|
config = parse_yaml(buf, overrides)
|
||||||
|
|
||||||
|
for k, v in config.items():
|
||||||
|
if isinstance(v, Iterable) and not isinstance(v, str):
|
||||||
|
parsed_config[k] = [x for x in config[k]]
|
||||||
|
else:
|
||||||
|
parsed_config[k] = [config[k]]
|
||||||
|
|
||||||
|
return parsed_config
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_cmake_module():
|
||||||
|
|
||||||
|
s = r'''#.rst:
|
||||||
|
#
|
||||||
|
# Foo ...
|
||||||
|
#
|
||||||
|
# autocmake.yml configuration::
|
||||||
|
#
|
||||||
|
# docopt:
|
||||||
|
# - "--cxx=<CXX> C++ compiler [default: g++]."
|
||||||
|
# - "--extra-cxx-flags=<EXTRA_CXXFLAGS> Extra C++ compiler flags [default: '']."
|
||||||
|
# export: "'CXX={0}'.format(arguments['--cxx'])"
|
||||||
|
# define: "'-DEXTRA_CXXFLAGS=\"{0}\"'.format(arguments['--extra-cxx-flags'])"
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
||||||
|
message(FATAL_ERROR "CMAKE_C_COMPILER_ID variable is not defined!")
|
||||||
|
endif()'''
|
||||||
|
|
||||||
|
parsed_config = parse_cmake_module(s)
|
||||||
|
assert parsed_config['docopt'] == ["--cxx=<CXX> C++ compiler [default: g++].", "--extra-cxx-flags=<EXTRA_CXXFLAGS> Extra C++ compiler flags [default: '']."]
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_cmake_module_no_key():
|
||||||
|
|
||||||
|
s = '''#.rst:
|
||||||
|
#
|
||||||
|
# Foo ...
|
||||||
|
#
|
||||||
|
# Bar ...
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
||||||
|
message(FATAL_ERROR "CMAKE_C_COMPILER_ID variable is not defined!")
|
||||||
|
endif()'''
|
||||||
|
|
||||||
|
parsed_config = parse_cmake_module(s)
|
||||||
|
assert parsed_config['docopt'] is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_cmake_module_interpolate():
|
||||||
|
|
||||||
|
s = r'''#.rst:
|
||||||
|
#
|
||||||
|
# Foo ...
|
||||||
|
#
|
||||||
|
# autocmake.yml configuration::
|
||||||
|
#
|
||||||
|
# major: 1
|
||||||
|
# minor: 2
|
||||||
|
# patch: 3
|
||||||
|
# a: v%(major)
|
||||||
|
# b: v%(minor)
|
||||||
|
# c: v%(patch)
|
||||||
|
|
||||||
|
enable_language(CXX)'''
|
||||||
|
|
||||||
|
parsed_config = parse_cmake_module(s)
|
||||||
|
assert parsed_config['a'] == ['v1']
|
||||||
|
assert parsed_config['b'] == ['v2']
|
||||||
|
assert parsed_config['c'] == ['v3']
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_cmake_module_overrides():
|
||||||
|
|
||||||
|
s = r'''#.rst:
|
||||||
|
#
|
||||||
|
# Foo ...
|
||||||
|
#
|
||||||
|
# autocmake.yml configuration::
|
||||||
|
#
|
||||||
|
# major: 1
|
||||||
|
# minor: 2
|
||||||
|
# patch: 3
|
||||||
|
# a: v%(major)
|
||||||
|
# b: v%(minor)
|
||||||
|
# c: v%(patch)
|
||||||
|
|
||||||
|
enable_language(CXX)'''
|
||||||
|
|
||||||
|
parsed_config = parse_cmake_module(s, {'minor': 4})
|
||||||
|
assert parsed_config['a'] == ['v1']
|
||||||
|
assert parsed_config['b'] == ['v4']
|
||||||
|
assert parsed_config['c'] == ['v3']
|
30
autocmake/parse_yaml.py
Normal file
30
autocmake/parse_yaml.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
def parse_yaml(stream, overrides={}):
|
||||||
|
import yaml
|
||||||
|
import sys
|
||||||
|
from autocmake.interpolate import interpolate
|
||||||
|
|
||||||
|
try:
|
||||||
|
config = yaml.load(stream, yaml.SafeLoader)
|
||||||
|
except yaml.YAMLError as exc:
|
||||||
|
print(exc)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
for k in config:
|
||||||
|
if k in overrides:
|
||||||
|
config[k] = overrides[k]
|
||||||
|
|
||||||
|
config = interpolate(config, config)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_yaml():
|
||||||
|
text = """foo: bar
|
||||||
|
this: that
|
||||||
|
var: '%(foo)'
|
||||||
|
list:
|
||||||
|
- a: '%(foo)'
|
||||||
|
- b: '%(foo)'
|
||||||
|
- c: '%(foo)'"""
|
||||||
|
|
||||||
|
assert parse_yaml(text) == {'foo': 'bar', 'this': 'that', 'var': 'bar',
|
||||||
|
'list': [{'a': 'bar'}, {'b': 'bar'}, {'c': 'bar'}]}
|
22
doc/conf.py
22
doc/conf.py
@ -14,15 +14,15 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import shlex
|
|
||||||
|
|
||||||
sys.path.append(os.path.relpath(os.path.abspath('.')))
|
|
||||||
import extract_rst
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
import extract_rst
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.abspath('..'))
|
||||||
|
from autocmake import __version__ as _version
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
@ -52,17 +52,17 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'Autocmake'
|
project = u'Autocmake'
|
||||||
copyright = u'2015, Radovan Bast and Jonas Juselius'
|
copyright = u'2015-2016, Radovan Bast, Jonas Juselius, and contributors'
|
||||||
author = u'Radovan Bast and Jonas Juselius'
|
author = u'Radovan Bast, Jonas Juselius, and contributors'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
|
||||||
version = '0.0'
|
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.0'
|
release = _version
|
||||||
|
# The short X.Y version.
|
||||||
|
version = '.'.join(release.split('.')[0:2])
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
@ -228,7 +228,7 @@ latex_elements = {
|
|||||||
# author, documentclass [howto, manual, or own class]).
|
# author, documentclass [howto, manual, or own class]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, 'Autocmake.tex', u'Autocmake Documentation',
|
(master_doc, 'Autocmake.tex', u'Autocmake Documentation',
|
||||||
u'Radovan Bast and Jonas Juselius', 'manual'),
|
author, 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
@ -9,12 +9,12 @@ This documentation is refreshed upon each push to the central repository.
|
|||||||
|
|
||||||
The module reference documentation is generated from the module sources using
|
The module reference documentation is generated from the module sources using
|
||||||
``#.rst:`` tags (compare for instance
|
``#.rst:`` tags (compare for instance
|
||||||
http://autocmake.readthedocs.org/en/latest/module-reference.html#cc-cmake with
|
http://autocmake.readthedocs.io/en/latest/module-reference.html#cc-cmake with
|
||||||
https://github.com/scisoft/autocmake/blob/master/modules/cc.cmake).
|
https://github.com/coderefinery/autocmake/blob/master/modules/cc.cmake).
|
||||||
|
|
||||||
Please note that the lines following ``# autocmake.cfg configuration::`` are
|
Please note that the lines following ``# autocmake.yml configuration::`` are
|
||||||
understood by the ``update.py`` script to infer autocmake.cfg code from the
|
understood by the ``update.py`` script to infer autocmake.yml code from the
|
||||||
documentation. As an example consider
|
documentation. As an example consider
|
||||||
https://github.com/scisoft/autocmake/blob/master/modules/cc.cmake#L20-L25.
|
https://github.com/coderefinery/autocmake/blob/master/modules/cc.cmake#L20-L26.
|
||||||
Here, ``update.py`` will infer the configurations for ``docopt``, ``export``,
|
Here, ``update.py`` will infer the configurations for ``docopt``, ``export``,
|
||||||
and ``define``.
|
and ``define``.
|
||||||
|
@ -5,12 +5,16 @@ Testing Autocmake
|
|||||||
|
|
||||||
You will need to install `pytest <http://pytest.org/>`__.
|
You will need to install `pytest <http://pytest.org/>`__.
|
||||||
|
|
||||||
Check also the `Travis <https://github.com/scisoft/autocmake/blob/master/.travis.yml>`__
|
Check also the `Travis <https://github.com/coderefinery/autocmake/blob/master/.travis.yml>`__
|
||||||
build and test recipe for other requirements.
|
build and test recipe for other requirements.
|
||||||
|
|
||||||
Your contributions and changes should preserve the test set. You can run locally all tests with::
|
Your contributions and changes should preserve the test set and be PEP8 conform.
|
||||||
|
You can run locally all tests with::
|
||||||
|
|
||||||
$ py.test test/test.py
|
$ pep8 --ignore E501 update.py
|
||||||
|
$ pep8 --ignore E501,E265 autocmake
|
||||||
|
$ py.test -vv autocmake/*
|
||||||
|
$ py.test -vv test/test.py
|
||||||
|
|
||||||
You can also select individual tests, for example those with ``fc_blas`` string in the name::
|
You can also select individual tests, for example those with ``fc_blas`` string in the name::
|
||||||
|
|
||||||
@ -19,8 +23,5 @@ You can also select individual tests, for example those with ``fc_blas`` string
|
|||||||
For more options, see the ``py.test`` flags.
|
For more options, see the ``py.test`` flags.
|
||||||
|
|
||||||
This test set is run upon each push to the central repository.
|
This test set is run upon each push to the central repository.
|
||||||
See also the `Travis <https://travis-ci.org/scisoft/autocmake/builds>`__
|
See also the `Travis <https://travis-ci.org/coderefinery/autocmake/builds>`__
|
||||||
build and test history.
|
build and test history.
|
||||||
|
|
||||||
In addition we also test Autocmake on a Windows CI server: `Appveyor <https://ci.appveyor.com/project/bast/autocmake/history>`__.
|
|
||||||
This is controlled by `Appveyor <https://github.com/scisoft/autocmake/blob/master/appveyor.yml>`__.
|
|
||||||
|
@ -12,48 +12,48 @@ infrastructure files which will be needed to build the project::
|
|||||||
|
|
||||||
$ mkdir cmake # does not have to be called "cmake" - take the name you prefer
|
$ mkdir cmake # does not have to be called "cmake" - take the name you prefer
|
||||||
$ cd cmake
|
$ cd cmake
|
||||||
$ wget https://github.com/scisoft/autocmake/raw/master/update.py
|
$ wget https://github.com/coderefinery/autocmake/raw/master/update.py
|
||||||
|
$ virtualenv venv
|
||||||
|
$ source venv/bin/activate
|
||||||
|
$ pip install pyyaml
|
||||||
$ python update.py --self
|
$ python update.py --self
|
||||||
|
|
||||||
On the MS Windows system, you can use the PowerShell wget-replacement::
|
On the MS Windows system, you can use the PowerShell wget-replacement::
|
||||||
|
|
||||||
$ Invoke-WebRequest https://github.com/scisoft/autocmake/raw/master/update.py -OutFile update.py
|
$ Invoke-WebRequest https://github.com/coderefinery/autocmake/raw/master/update.py -OutFile update.py
|
||||||
|
|
||||||
This creates (or updates) the following files (an existing ``autocmake.cfg`` is
|
This creates (or updates) the following files (an existing ``autocmake.yml`` is
|
||||||
not overwritten by the script)::
|
not overwritten by the script)::
|
||||||
|
|
||||||
cmake/
|
cmake/
|
||||||
autocmake.cfg # edit this file
|
autocmake.yml # edit this file
|
||||||
update.py # no need to edit
|
update.py # no need to edit
|
||||||
lib/
|
autocmake/ # no need to edit
|
||||||
config.py # no need to edit
|
... # no need to edit
|
||||||
docopt/
|
|
||||||
docopt.py # no need to edit
|
|
||||||
|
|
||||||
Note that all other listed files are overwritten (use version control).
|
Note that ``update.py`` and files under ``autocmake/``
|
||||||
|
are overwritten (use version control).
|
||||||
|
|
||||||
|
|
||||||
Generating the CMake infrastructure
|
Generating the CMake infrastructure
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
Now customize ``autocmake.cfg`` to your needs
|
Now customize ``autocmake.yml`` to your needs
|
||||||
(see :ref:`autocmake_cfg`)
|
(see :ref:`autocmake_yml`)
|
||||||
and then run the ``update.py`` script which
|
and then run the ``update.py`` script which
|
||||||
creates ``CMakeLists.txt`` and a setup script in the target path::
|
creates ``CMakeLists.txt`` and a setup script in the target path::
|
||||||
|
|
||||||
$ python update.py ..
|
$ python update.py ..
|
||||||
|
|
||||||
The script also downloads external CMake modules specified in ``autocmake.cfg`` to a directory
|
The script also downloads external CMake modules specified in ``autocmake.yml`` to a directory
|
||||||
called ``downloaded/``::
|
called ``downloaded/``::
|
||||||
|
|
||||||
cmake/
|
cmake/
|
||||||
autocmake.cfg # edit this file
|
autocmake.yml # edit this file
|
||||||
update.py # no need to edit
|
update.py # no need to edit
|
||||||
lib/
|
autocmake/ # no need to edit
|
||||||
config.py # no need to edit
|
... # no need to edit
|
||||||
docopt/
|
downloaded/ # contains CMake modules fetched from the web
|
||||||
docopt.py # no need to edit
|
|
||||||
downloaded/ # contains CMake modules fetched from the web
|
|
||||||
|
|
||||||
|
|
||||||
Building the project
|
Building the project
|
||||||
|
@ -1,115 +1,101 @@
|
|||||||
|
|
||||||
.. _autocmake_cfg:
|
.. _autocmake_yml:
|
||||||
|
|
||||||
Configuring autocmake.cfg
|
Configuring autocmake.yml
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
The script ``autocmake.cfg`` is the high level place where you configure
|
The script ``autocmake.yml`` is the high level place where you configure
|
||||||
your project. Here is an example. We will discuss it in detail further
|
your project. Here is an example. We will discuss it in detail further
|
||||||
below::
|
below::
|
||||||
|
|
||||||
[project]
|
|
||||||
name: numgrid
|
name: numgrid
|
||||||
|
|
||||||
min_cmake_version: 2.8
|
min_cmake_version: 2.8
|
||||||
|
|
||||||
[fc]
|
url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/fc.cmake
|
|
||||||
|
|
||||||
[cc]
|
modules:
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/cc.cmake
|
- compilers:
|
||||||
|
- source:
|
||||||
[cxx]
|
- '%(url_root)modules/fc.cmake'
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/cxx.cmake
|
- '%(url_root)modules/cc.cmake'
|
||||||
|
- '%(url_root)modules/cxx.cmake'
|
||||||
[flags]
|
- flags:
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/compilers/GNU.CXX.cmake
|
- source:
|
||||||
https://github.com/scisoft/autocmake/raw/master/compilers/Intel.CXX.cmake
|
- '%(url_root)compilers/GNU.CXX.cmake'
|
||||||
|
- '%(url_root)compilers/Intel.CXX.cmake'
|
||||||
[rpath]
|
- 'compilers/Clang.CXX.cmake'
|
||||||
source: custom/rpath.cmake
|
- plugins:
|
||||||
|
- source:
|
||||||
[definitions]
|
- '%(url_root)modules/ccache.cmake'
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/definitions.cmake
|
- 'custom/rpath.cmake'
|
||||||
|
- '%(url_root)modules/definitions.cmake'
|
||||||
[coverage]
|
- '%(url_root)modules/code_coverage.cmake'
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/code_coverage.cmake
|
- '%(url_root)modules/safeguards.cmake'
|
||||||
|
- '%(url_root)modules/default_build_paths.cmake'
|
||||||
[safeguards]
|
- '%(url_root)modules/src.cmake'
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/safeguards.cmake
|
- '%(url_root)modules/googletest.cmake'
|
||||||
|
- 'custom/api.cmake'
|
||||||
[default_build_paths]
|
- 'custom/test.cmake'
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/src.cmake
|
|
||||||
|
|
||||||
[googletest]
|
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/googletest.cmake
|
|
||||||
|
|
||||||
[custom]
|
|
||||||
source: custom/api.cmake
|
|
||||||
custom/test.cmake
|
|
||||||
|
|
||||||
|
|
||||||
Name and order of sections
|
Name and order of sections
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
We see that the configuration file has sections.
|
First we define the project name (here "numgrid"). This section has to be there
|
||||||
The only section where the name matters is ``[project]``::
|
and it has to be called "project" (but it does not have to be on top).
|
||||||
|
|
||||||
[project]
|
We also have to define ``min_cmake_version``.
|
||||||
name: numgrid
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
This is where we define the project name (here "numgrid"). This section has to
|
The definition ``url_root`` is an interpolation (see :ref:`interpolation`) and
|
||||||
be there and it has to be called "project" (but it does not have to be on top).
|
we use it to avoid retyping the same line over and over and to be able to
|
||||||
|
change it in one place. The explicit name "url_root" has no special meaning to
|
||||||
|
Autocmake and we could have chosen a different name.
|
||||||
|
|
||||||
The names of the other sections do not matter to Autocmake. You could name them like this::
|
The section ``modules`` is a list of CMake plugins. The names of the list
|
||||||
|
elements (here "compilers", "flags", and "plugins") does not matter to
|
||||||
|
Autocmake. We could have called them "one", "two", and "whatever", but it would
|
||||||
|
not make much sense. It is better to choose names that are meaningful to you
|
||||||
|
and readers of your code.
|
||||||
|
|
||||||
[project]
|
The order of the elements under ``modules`` does matter and the list will be
|
||||||
name: numgrid
|
processed in the exact order as you specify them in ``autocmake.yml``.
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[one]
|
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/fc.cmake
|
|
||||||
|
|
||||||
[two]
|
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/cc.cmake
|
|
||||||
|
|
||||||
[whatever]
|
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/cxx.cmake
|
|
||||||
|
|
||||||
But it would not make much sense. It is better to choose names that are
|
|
||||||
meaningful to you.
|
|
||||||
|
|
||||||
The order of the sections does matter and the sections will be processed in the
|
|
||||||
exact order as you specify them in ``autocmake.cfg``.
|
|
||||||
|
|
||||||
|
|
||||||
Minimal example
|
Minimal example
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
As a minimal example we take an ``autocmake.cfg`` which only contains::
|
As a minimal example we take an ``autocmake.yml`` which only contains::
|
||||||
|
|
||||||
[project]
|
|
||||||
name: minime
|
name: minime
|
||||||
min_cmake_version: 2.8
|
min_cmake_version: 2.8
|
||||||
|
|
||||||
|
If you don't have the ``update.py`` script yet, you need to fetch it from the web::
|
||||||
|
|
||||||
|
$ wget https://github.com/coderefinery/autocmake/raw/master/update.py
|
||||||
|
|
||||||
First we make sure that the ``update.py`` script is up-to-date and that it has access
|
First we make sure that the ``update.py`` script is up-to-date and that it has access
|
||||||
to all libraries it needs::
|
to all libraries it needs::
|
||||||
|
|
||||||
$ python update.py --self
|
$ python update.py --self
|
||||||
|
|
||||||
- creating .gitignore
|
- creating .gitignore
|
||||||
- fetching lib/config.py
|
- fetching autocmake/configure.py
|
||||||
- fetching lib/docopt/docopt.py
|
- fetching autocmake/__init__.py
|
||||||
|
- fetching autocmake/external/docopt.py
|
||||||
|
- fetching autocmake/external/__init__.py
|
||||||
|
- fetching autocmake/generate.py
|
||||||
|
- fetching autocmake/extract.py
|
||||||
|
- fetching autocmake/interpolate.py
|
||||||
|
- fetching autocmake/parse_rst.py
|
||||||
|
- fetching autocmake/parse_yaml.py
|
||||||
- fetching update.py
|
- fetching update.py
|
||||||
|
|
||||||
Good. Now we can generate ``CMakeLists.txt`` and the setup script::
|
Good. Now we can generate ``CMakeLists.txt`` and the setup script::
|
||||||
|
|
||||||
$ python update ..
|
$ python update.py ..
|
||||||
|
|
||||||
- parsing autocmake.cfg
|
- parsing autocmake.yml
|
||||||
- generating CMakeLists.txt
|
- generating CMakeLists.txt
|
||||||
- generating setup script
|
- generating setup script
|
||||||
|
|
||||||
@ -147,38 +133,38 @@ the following default options::
|
|||||||
--show Show CMake command and exit.
|
--show Show CMake command and exit.
|
||||||
--cmake-executable=<CMAKE_EXECUTABLE> Set the CMake executable [default: cmake].
|
--cmake-executable=<CMAKE_EXECUTABLE> Set the CMake executable [default: cmake].
|
||||||
--cmake-options=<STRING> Define options to CMake [default: ''].
|
--cmake-options=<STRING> Define options to CMake [default: ''].
|
||||||
|
--prefix=<PATH> Set the install path for make install.
|
||||||
<builddir> Build directory.
|
<builddir> Build directory.
|
||||||
-h --help Show this screen.
|
-h --help Show this screen.
|
||||||
|
|
||||||
That's not too bad although currently we cannot do much with this since there
|
That's not too bad although currently we cannot do much with this since there
|
||||||
are no sources listed, no targets, hence nothing to build. We need to flesh out
|
are no sources listed, no targets, hence nothing to build. We need to flesh out
|
||||||
``CMakeLists.txt`` by extending ``autocmake.cfg``
|
``CMakeLists.txt`` by extending ``autocmake.yml`` and this is what we will do
|
||||||
and this is what we will do in the next section.
|
in the next section.
|
||||||
|
|
||||||
|
|
||||||
Assembling CMake plugins
|
Assembling CMake plugins
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
The preferred way to extend ``CMakeLists.txt`` is by editing ``autocmake.cfg``
|
The preferred way to extend ``CMakeLists.txt`` is by editing ``autocmake.yml``
|
||||||
and using the ``source`` option::
|
and using the ``source`` option::
|
||||||
|
|
||||||
[fc]
|
- compilers:
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/fc.cmake
|
- source:
|
||||||
|
- '%(url_root)modules/fc.cmake'
|
||||||
|
- '%(url_root)modules/cc.cmake'
|
||||||
|
- '%(url_root)modules/cxx.cmake'
|
||||||
|
|
||||||
This will download ``fc.cmake`` and include it in ``CMakeLists.txt``.
|
This will download ``fc.cmake``, ``cc.cmake``, and ``cxx.cmake``, and include
|
||||||
|
them in ``CMakeLists.txt``, in this order.
|
||||||
|
|
||||||
You can also include local CMake modules, e.g.::
|
You can also include local CMake modules, e.g.::
|
||||||
|
|
||||||
[rpath]
|
- source:
|
||||||
source: custom/rpath.cmake
|
- 'custom/rpath.cmake'
|
||||||
|
|
||||||
It is also OK to include several modules at once::
|
It is also OK to include several modules at once as we have seen above. The
|
||||||
|
modules will be included in the same order as they appear in ``autocmake.yml``.
|
||||||
[flags]
|
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/compilers/GNU.CXX.cmake
|
|
||||||
https://github.com/scisoft/autocmake/raw/master/compilers/Intel.CXX.cmake
|
|
||||||
|
|
||||||
The modules will be included in the same order as they appear in ``autocmake.cfg``.
|
|
||||||
|
|
||||||
|
|
||||||
Fetching files without including them in CMakeLists.txt
|
Fetching files without including them in CMakeLists.txt
|
||||||
@ -187,9 +173,9 @@ Fetching files without including them in CMakeLists.txt
|
|||||||
Sometimes you want to fetch a file without including it in ``CMakeLists.txt``.
|
Sometimes you want to fetch a file without including it in ``CMakeLists.txt``.
|
||||||
This can be done with the ``fetch`` option. This is for instance done by the
|
This can be done with the ``fetch`` option. This is for instance done by the
|
||||||
``git_info.cmake`` module (see
|
``git_info.cmake`` module (see
|
||||||
https://github.com/scisoft/autocmake/blob/master/modules/git_info/git_info.cmake#L10-L11).
|
https://github.com/coderefinery/autocmake/blob/master/modules/git_info/git_info.cmake#L10-L13).
|
||||||
|
|
||||||
If ``fetch`` is invoked in ``autocmake.cfg``, then the fetched file is placed
|
If ``fetch`` is invoked in ``autocmake.yml``, then the fetched file is placed
|
||||||
under ``downloaded/``. If ``fetch`` is invoked from within a CMake module
|
under ``downloaded/``. If ``fetch`` is invoked from within a CMake module
|
||||||
documentation (see below), then the fetched file is placed into the same
|
documentation (see below), then the fetched file is placed into the same
|
||||||
directory as the CMake module file which fetches it.
|
directory as the CMake module file which fetches it.
|
||||||
@ -199,11 +185,11 @@ Generating setup options
|
|||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Options for the setup script can be generated with the ``docopt``
|
Options for the setup script can be generated with the ``docopt``
|
||||||
option. As an example, the following ``autocmake.cfg`` snippet will add a
|
option. As an example, the following ``autocmake.yml`` snippet will add a
|
||||||
``--something`` flag::
|
``--something`` flag::
|
||||||
|
|
||||||
[my_section]
|
- my_section:
|
||||||
docopt: --something Enable something [default: False].
|
- docopt: "--something Enable something [default: False]."
|
||||||
|
|
||||||
|
|
||||||
Setting CMake options
|
Setting CMake options
|
||||||
@ -213,9 +199,9 @@ Configure-time CMake options can be generated with the ``define`` option.
|
|||||||
Consider the following example which toggles the CMake variable
|
Consider the following example which toggles the CMake variable
|
||||||
``ENABLE_SOMETHING``::
|
``ENABLE_SOMETHING``::
|
||||||
|
|
||||||
[my_section]
|
- my_section:
|
||||||
docopt: --something Enable something [default: False].
|
- docopt: "--something Enable something [default: False]."
|
||||||
define: '-DENABLE_SOMETHING={0}'.format(arguments['--something'])
|
- define: "'-DENABLE_SOMETHING={0}'.format(arguments['--enable-something'])"
|
||||||
|
|
||||||
|
|
||||||
Setting environment variables
|
Setting environment variables
|
||||||
@ -224,33 +210,23 @@ Setting environment variables
|
|||||||
You can export environment variables at configure-time using the ``export``
|
You can export environment variables at configure-time using the ``export``
|
||||||
option. Consider the following example::
|
option. Consider the following example::
|
||||||
|
|
||||||
[cc]
|
docopt:
|
||||||
docopt: --cc=<CC> C compiler [default: gcc].
|
- "--cc=<CC> C compiler [default: gcc]."
|
||||||
--extra-cc-flags=<EXTRA_CFLAGS> Extra C compiler flags [default: ''].
|
- "--extra-cc-flags=<EXTRA_CFLAGS> Extra C compiler flags [default: '']."
|
||||||
export: 'CC=%s' % arguments['--cc']
|
export: "'CC={0}'.format(arguments['--cc'])"
|
||||||
define: '-DEXTRA_CFLAGS="%s"' % arguments['--extra-cc-flags']
|
define: "'-DEXTRA_CFLAGS=\"{0}\"'.format(arguments['--extra-cc-flags'])"
|
||||||
|
|
||||||
|
|
||||||
Auto-generating configurations from the documentation
|
Auto-generating configurations from the documentation
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
To avoid a boring re-typing of boilerplate ``autocmake.cfg`` code it is possible
|
To avoid a boring re-typing of boilerplate ``autocmake.yml`` code it is possible
|
||||||
to auto-generate configurations from the documentation. This is the case
|
to auto-generate configurations from the documentation. This is the case
|
||||||
for many core modules which come with own options once you have sourced them.
|
for many core modules which come with own options once you have sourced them.
|
||||||
|
|
||||||
The lines following ``# autocmake.cfg configuration::`` are
|
The lines following ``# autocmake.yml configuration::`` are
|
||||||
understood by the ``update.py`` script to infer ``autocmake.cfg`` code from the
|
understood by the ``update.py`` script to infer ``autocmake.yml`` code from the
|
||||||
documentation. As an example consider
|
documentation. As an example consider
|
||||||
https://github.com/scisoft/autocmake/blob/master/modules/cc.cmake#L20-L25.
|
https://github.com/coderefinery/autocmake/blob/master/modules/cc.cmake#L20-L26.
|
||||||
Here, ``update.py`` will infer the configurations for ``docopt``, ``export``,
|
Here, ``update.py`` will infer the configurations for ``docopt``, ``export``,
|
||||||
and ``define``.
|
and ``define``.
|
||||||
|
|
||||||
|
|
||||||
Overriding documented configurations
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
Configurable documented defaults can be achieved using interpolations. See for
|
|
||||||
instance
|
|
||||||
https://github.com/scisoft/autocmake/blob/master/modules/boost/boost.cmake#L33-L36.
|
|
||||||
These can be modified within ``autocmake.cfg`` with a dictionary, e.g.:
|
|
||||||
https://github.com/scisoft/autocmake/blob/master/test/boost_libs/cmake/autocmake.cfg#L9
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Customizing CMake modules
|
Customizing CMake modules
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
The ``update.py`` script assembles modules listed in ``autocmake.cfg`` into
|
The ``update.py`` script assembles modules listed in ``autocmake.yml`` into
|
||||||
``CMakeLists.txt``. Those that are fetched from the web are placed inside
|
``CMakeLists.txt``. Those that are fetched from the web are placed inside
|
||||||
``downloaded/``. You have several options to customize downloaded CMake
|
``downloaded/``. You have several options to customize downloaded CMake
|
||||||
modules:
|
modules:
|
||||||
@ -22,7 +22,7 @@ Adapt local copies of CMake modules
|
|||||||
|
|
||||||
A slightly better solution is to download the CMake modules that you wish you customize
|
A slightly better solution is to download the CMake modules that you wish you customize
|
||||||
to a separate directory (e.g. ``custom/``) and source the customized CMake
|
to a separate directory (e.g. ``custom/``) and source the customized CMake
|
||||||
modules in ``autocmake.cfg``. Alternatively you can serve your custom modules
|
modules in ``autocmake.yml``. Alternatively you can serve your custom modules
|
||||||
from your own http server.
|
from your own http server.
|
||||||
|
|
||||||
|
|
||||||
@ -34,19 +34,30 @@ the branched customized versions. This will make it easier for you
|
|||||||
to stay up-to-date with upstream development.
|
to stay up-to-date with upstream development.
|
||||||
|
|
||||||
|
|
||||||
Overriding defaults
|
Overriding settings
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Some modules use interpolations to set defaults, see for instance
|
If you source a module which contains directives such as
|
||||||
https://github.com/scisoft/autocmake/blob/master/modules/boost/boost.cmake#L33-L36.
|
``define``,
|
||||||
These can be modified within ``autocmake.cfg``, e.g.:
|
``docopt``,
|
||||||
https://github.com/scisoft/autocmake/blob/master/test/boost_libs/cmake/autocmake.cfg#L9
|
``export``, or
|
||||||
|
``fetch``, and you wish to modify those,
|
||||||
|
then you can override these settings in ``autocmake.yml``.
|
||||||
|
Settings in ``autocmake.yml`` take precedence over
|
||||||
|
settings imported by a sourced module.
|
||||||
|
|
||||||
|
As an example consider the Boost module which defines and uses
|
||||||
|
interpolation variables ``major``, ``minor``, ``patch``, and ``components``, see
|
||||||
|
https://github.com/coderefinery/autocmake/blob/master/modules/boost/boost.cmake#L52-L55.
|
||||||
|
|
||||||
|
The recommended way to customize these is in ``autocmake.yml``, e.g.:
|
||||||
|
https://github.com/coderefinery/autocmake/blob/master/test/boost_libs/cmake/autocmake.yml#L12-L17.
|
||||||
|
|
||||||
|
|
||||||
Create own CMake modules
|
Create own CMake modules
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
Of course you can also create own modules and source them in ``autocmake.cfg``.
|
Of course you can also create own modules and source them in ``autocmake.yml``.
|
||||||
|
|
||||||
|
|
||||||
Contribute customizations to the "standard library"
|
Contribute customizations to the "standard library"
|
||||||
@ -54,5 +65,5 @@ Contribute customizations to the "standard library"
|
|||||||
|
|
||||||
If you think that your customization will be useful for other users as well,
|
If you think that your customization will be useful for other users as well,
|
||||||
you may consider contributing the changes directly to
|
you may consider contributing the changes directly to
|
||||||
https://github.com/scisoft/autocmake/. We very much encourage such
|
https://github.com/coderefinery/autocmake/. We very much encourage such
|
||||||
contributions. But we also strive for generality and portability.
|
contributions. But we also strive for generality and portability.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
Example Hello World project
|
Example hello world project
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
This is a brief example for the busy and impatient programmer. For a longer
|
This is a brief example for the busy and impatient programmer. For a longer
|
||||||
tour please see :ref:`autocmake_cfg`.
|
tour please see :ref:`autocmake_yml`.
|
||||||
|
|
||||||
We start with a mixed Fortran-C project with the following sources::
|
We start with a mixed Fortran-C project with the following sources::
|
||||||
|
|
||||||
@ -23,40 +23,49 @@ there. This is not necessary for Autocmake but it is a generally good practice::
|
|||||||
|
|
||||||
Now we create ``cmake/`` and fetch ``update.py``::
|
Now we create ``cmake/`` and fetch ``update.py``::
|
||||||
|
|
||||||
$ mkdir cmake
|
$ mkdir cmake # does not have to be called "cmake" - take the name you prefer
|
||||||
$ cd cmake/
|
$ cd cmake
|
||||||
$ wget https://raw.githubusercontent.com/scisoft/autocmake/master/update.py
|
$ wget https://github.com/coderefinery/autocmake/raw/master/update.py
|
||||||
$ python update.py --self
|
$ python update.py --self
|
||||||
|
|
||||||
Now from top-level our file tree looks like this::
|
Now from top-level our file tree looks like this::
|
||||||
|
|
||||||
.
|
.
|
||||||
|-- cmake
|
|-- cmake
|
||||||
| |-- autocmake.cfg
|
| |-- autocmake
|
||||||
| |-- lib
|
| | |-- __init__.py
|
||||||
| | |-- config.py
|
| | |-- configure.py
|
||||||
| | `-- docopt
|
| | |-- external
|
||||||
| | `-- docopt.py
|
| | | |-- __init__.py
|
||||||
|
| | | `-- docopt.py
|
||||||
|
| | |-- extract.py
|
||||||
|
| | |-- generate.py
|
||||||
|
| | |-- interpolate.py
|
||||||
|
| | |-- parse_rst.py
|
||||||
|
| | `-- parse_yaml.py
|
||||||
|
| |-- autocmake.yml
|
||||||
| `-- update.py
|
| `-- update.py
|
||||||
`-- src
|
`-- src
|
||||||
|-- feature1.F90
|
|-- feature1.F90
|
||||||
|-- feature2.c
|
|-- feature2.c
|
||||||
`-- main.F90
|
`-- main.F90
|
||||||
|
|
||||||
Now we edit ``cmake/autocmake.cfg`` to look like this::
|
Now we edit ``cmake/autocmake.yml`` to look like this::
|
||||||
|
|
||||||
[project]
|
|
||||||
name: hello
|
name: hello
|
||||||
|
|
||||||
min_cmake_version: 2.8
|
min_cmake_version: 2.8
|
||||||
|
|
||||||
[fc]
|
url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/fc.cmake
|
|
||||||
|
|
||||||
[cc]
|
modules:
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/cc.cmake
|
- compilers:
|
||||||
|
- source:
|
||||||
[src]
|
- '%(url_root)modules/fc.cmake'
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/src.cmake
|
- '%(url_root)modules/cc.cmake'
|
||||||
|
- src_support:
|
||||||
|
- source:
|
||||||
|
- '%(url_root)modules/src.cmake'
|
||||||
|
|
||||||
What we have specified here is the project name and that we wish Fortran and C
|
What we have specified here is the project name and that we wish Fortran and C
|
||||||
support. The ``src.cmake`` module tells CMake to include a ``src/CMakeLists.txt``.
|
support. The ``src.cmake`` module tells CMake to include a ``src/CMakeLists.txt``.
|
||||||
@ -76,20 +85,32 @@ Now we have everything to generate ``CMakeLists.txt`` and a setup script::
|
|||||||
$ cd cmake
|
$ cd cmake
|
||||||
$ python update ..
|
$ python update ..
|
||||||
|
|
||||||
|
- parsing autocmake.yml
|
||||||
|
- assembling modules: [##############################] (3/3)
|
||||||
|
- generating CMakeLists.txt
|
||||||
|
- generating setup script
|
||||||
|
|
||||||
And this is what we got::
|
And this is what we got::
|
||||||
|
|
||||||
.
|
.
|
||||||
|-- CMakeLists.txt
|
|-- CMakeLists.txt
|
||||||
|-- cmake
|
|-- cmake
|
||||||
| |-- autocmake.cfg
|
| |-- autocmake
|
||||||
|
| | |-- __init__.py
|
||||||
|
| | |-- configure.py
|
||||||
|
| | |-- external
|
||||||
|
| | | |-- __init__.py
|
||||||
|
| | | `-- docopt.py
|
||||||
|
| | |-- extract.py
|
||||||
|
| | |-- generate.py
|
||||||
|
| | |-- interpolate.py
|
||||||
|
| | |-- parse_rst.py
|
||||||
|
| | `-- parse_yaml.py
|
||||||
|
| |-- autocmake.yml
|
||||||
| |-- downloaded
|
| |-- downloaded
|
||||||
| | |-- autocmake_cc.cmake
|
| | |-- autocmake_cc.cmake
|
||||||
| | |-- autocmake_fc.cmake
|
| | |-- autocmake_fc.cmake
|
||||||
| | `-- autocmake_src.cmake
|
| | `-- autocmake_src.cmake
|
||||||
| |-- lib
|
|
||||||
| | |-- config.py
|
|
||||||
| | `-- docopt
|
|
||||||
| | `-- docopt.py
|
|
||||||
| `-- update.py
|
| `-- update.py
|
||||||
|-- setup
|
|-- setup
|
||||||
`-- src
|
`-- src
|
||||||
@ -100,12 +121,12 @@ And this is what we got::
|
|||||||
|
|
||||||
Now we are ready to build::
|
Now we are ready to build::
|
||||||
|
|
||||||
$ python setup --fc=gfortran --cc=gcc
|
$ ./setup --fc=gfortran --cc=gcc
|
||||||
|
|
||||||
FC=gfortran CC=gcc cmake -DEXTRA_FCFLAGS="''" -DENABLE_FC_SUPPORT="ON" -DEXTRA_CFLAGS="''" -DCMAKE_BUILD_TYPE=release -G "Unix Makefiles" None /home/user/example
|
FC=gfortran CC=gcc cmake -DEXTRA_FCFLAGS="''" -DEXTRA_CFLAGS="''" -DCMAKE_BUILD_TYPE=release -G "Unix Makefiles" /home/user/hello
|
||||||
|
|
||||||
-- The C compiler identification is GNU 4.9.2
|
-- The C compiler identification is GNU 6.1.1
|
||||||
-- The CXX compiler identification is GNU 4.9.2
|
-- The CXX compiler identification is GNU 6.1.1
|
||||||
-- Check for working C compiler: /usr/bin/gcc
|
-- Check for working C compiler: /usr/bin/gcc
|
||||||
-- Check for working C compiler: /usr/bin/gcc -- works
|
-- Check for working C compiler: /usr/bin/gcc -- works
|
||||||
-- Detecting C compiler ABI info
|
-- Detecting C compiler ABI info
|
||||||
@ -118,7 +139,7 @@ Now we are ready to build::
|
|||||||
-- Detecting CXX compiler ABI info - done
|
-- Detecting CXX compiler ABI info - done
|
||||||
-- Detecting CXX compile features
|
-- Detecting CXX compile features
|
||||||
-- Detecting CXX compile features - done
|
-- Detecting CXX compile features - done
|
||||||
-- The Fortran compiler identification is GNU 4.9.2
|
-- The Fortran compiler identification is GNU 6.1.1
|
||||||
-- Check for working Fortran compiler: /usr/bin/gfortran
|
-- Check for working Fortran compiler: /usr/bin/gfortran
|
||||||
-- Check for working Fortran compiler: /usr/bin/gfortran -- works
|
-- Check for working Fortran compiler: /usr/bin/gfortran -- works
|
||||||
-- Detecting Fortran compiler ABI info
|
-- Detecting Fortran compiler ABI info
|
||||||
@ -127,14 +148,14 @@ Now we are ready to build::
|
|||||||
-- Checking whether /usr/bin/gfortran supports Fortran 90 -- yes
|
-- Checking whether /usr/bin/gfortran supports Fortran 90 -- yes
|
||||||
-- Configuring done
|
-- Configuring done
|
||||||
-- Generating done
|
-- Generating done
|
||||||
-- Build files have been written to: /home/user/example/build
|
-- Build files have been written to: /home/user/hello/build
|
||||||
|
|
||||||
configure step is done
|
configure step is done
|
||||||
now you need to compile the sources:
|
now you need to compile the sources:
|
||||||
$ cd build
|
$ cd build
|
||||||
$ make
|
$ make
|
||||||
|
|
||||||
$ cd build/
|
$ cd build
|
||||||
$ make
|
$ make
|
||||||
|
|
||||||
Scanning dependencies of target hello.x
|
Scanning dependencies of target hello.x
|
||||||
|
@ -4,6 +4,18 @@ FAQ for developers
|
|||||||
==================
|
==================
|
||||||
|
|
||||||
|
|
||||||
|
Which files do I need to edit?
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Let us start with files which you normally never edit: ``CMakeLists.txt`` and
|
||||||
|
``setup`` - these are generated based on ``autocmake.yml``. Have a look in
|
||||||
|
``autocmake.yml`` and you will see all CMake files which are assembled into
|
||||||
|
``CMakeLists.txt``. You can edit those files. If you change the order of files
|
||||||
|
listed in ``autocmake.yml`` or if you add or remove CMake modules, then you
|
||||||
|
need to rerun the ``update.py`` script to refresh ``CMakeLists.txt`` and
|
||||||
|
``setup``.
|
||||||
|
|
||||||
|
|
||||||
Autocmake does not do feature X - I really need feature X and a setup flag --X
|
Autocmake does not do feature X - I really need feature X and a setup flag --X
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -19,18 +31,22 @@ naming)::
|
|||||||
|
|
||||||
cmake/custom/my_feature.cmake
|
cmake/custom/my_feature.cmake
|
||||||
|
|
||||||
And include this feature to the main ``CMakeLists.txt`` in ``autocmake.cfg``::
|
And include this feature to the main ``CMakeLists.txt`` in ``autocmake.yml``
|
||||||
|
under the ``modules`` section::
|
||||||
|
|
||||||
[my_feature]
|
modules:
|
||||||
source: custom/my_feature.cmake
|
- my_feature:
|
||||||
|
- source:
|
||||||
|
- custom/my_feature.cmake
|
||||||
|
|
||||||
Now your code is included in the main ``CMakeLists.txt``. Perhaps you also
|
Now your code is included in the main ``CMakeLists.txt``. Perhaps you also
|
||||||
want a setup script flag to toggle the feature::
|
want a setup script flag to toggle the feature::
|
||||||
|
|
||||||
[my_feature]
|
- my_feature:
|
||||||
source: custom/my_feature.cmake
|
- docopt: "--enable-my-feature Enable my feature [default: False]."
|
||||||
docopt: --my-feature Enable my feature [default: False].
|
- define: "'-DENABLE_MY_FEATURE={0}'.format(arguments['--enable-my-feature'])"
|
||||||
define: '-DENABLE_MY_FEATURE={0}'.format(arguments['--my-feature'])
|
- source:
|
||||||
|
- custom/my_feature.cmake
|
||||||
|
|
||||||
Implement your ideas, test them, and share them. If your module is portable,
|
Implement your ideas, test them, and share them. If your module is portable,
|
||||||
good code quality, and of general interest, you can suggest it to be part of
|
good code quality, and of general interest, you can suggest it to be part of
|
||||||
@ -43,17 +59,16 @@ How can I get a setup flag --X that toggles a CMake variable?
|
|||||||
The following will add a ``--something`` flag which toggles the CMake variable
|
The following will add a ``--something`` flag which toggles the CMake variable
|
||||||
``ENABLE_SOMETHING``::
|
``ENABLE_SOMETHING``::
|
||||||
|
|
||||||
[my_section]
|
- my_section:
|
||||||
docopt: --something Enable something [default: False].
|
- docopt: "--something Enable something [default: False]."
|
||||||
define: '-DENABLE_SOMETHING={0}'.format(arguments['--something'])
|
- define: "'-DENABLE_SOMETHING={0}'.format(arguments['--enable-something'])"
|
||||||
|
|
||||||
|
|
||||||
Can I change the name of the setup script?
|
Can I change the name of the setup script?
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
Yes you can do that in ``autocmake.cfg``. Here we for instance change the name to "configure"::
|
Yes you can do that in ``autocmake.yml``. Here we for instance change the name to "configure"::
|
||||||
|
|
||||||
[project]
|
|
||||||
name: myproject
|
name: myproject
|
||||||
min_cmake_version: 2.8
|
min_cmake_version: 2.8
|
||||||
setup_script: configure
|
setup_script: configure
|
||||||
@ -70,12 +85,13 @@ realized in Autocmake.
|
|||||||
Should I include and track also files generated by Autocmake in my repository?
|
Should I include and track also files generated by Autocmake in my repository?
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Yes, you probably want to do that. Autocmake generates a number of files which
|
Yes, you probably want to do that. Autocmake downloads and generates a number
|
||||||
in principle could be generated at configure- or build-time. However, you
|
of files which in principle could be generated at configure- or build-time.
|
||||||
probably do not want the users of your code to run any Autocmake scripts like
|
However, you probably do not want the users of your code to run any Autocmake
|
||||||
``update.py`` to generate the files they need to build the project. The users
|
scripts like ``update.py`` to generate the files they need to build the
|
||||||
of your code will run ``setup`` directly and expect everything to just work
|
project. The users of your code will run ``setup`` directly and typically expect
|
||||||
(TM).
|
everything to just work (TM). Note also that the users of your code will
|
||||||
|
not need to install the pyyaml package.
|
||||||
|
|
||||||
|
|
||||||
The update.py script is overwriting my CMakeLists.txt and setup, isn't this bad?
|
The update.py script is overwriting my CMakeLists.txt and setup, isn't this bad?
|
||||||
@ -93,7 +109,7 @@ But I need to manually edit and customize CMakeLists.txt and setup every time I
|
|||||||
-----------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
You typically never need to manually edit and customize ``CMakeLists.txt`` and
|
You typically never need to manually edit and customize ``CMakeLists.txt`` and
|
||||||
``setup`` directly. You can introduce customizations in ``autocmake.cfg``
|
``setup`` directly. You can introduce customizations in ``autocmake.yml``
|
||||||
which get assembled into the front-end scripts.
|
which get assembled into the front-end scripts.
|
||||||
|
|
||||||
|
|
||||||
@ -101,19 +117,21 @@ Where is a good place to list my sources and targets?
|
|||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
As mentioned above ``CMakeLists.txt`` is not a good place because this file is
|
As mentioned above ``CMakeLists.txt`` is not a good place because this file is
|
||||||
generated from ``autocmake.cfg`` and your modifications would become
|
generated from ``autocmake.yml`` and your modifications would become
|
||||||
overwritten at some point. A good standard is to organize your sources under
|
overwritten at some point. A good standard is to organize your sources under
|
||||||
``src/`` and to list your sources and targets in ``src/CMakeLists.txt``. You
|
``src/`` and to list your sources and targets in ``src/CMakeLists.txt``. You
|
||||||
can include the latter in ``autocmake.cfg`` using::
|
can include the latter in ``autocmake.yml`` using::
|
||||||
|
|
||||||
[src]
|
- my_sources:
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/src.cmake
|
- source:
|
||||||
|
- https://github.com/coderefinery/autocmake/raw/master/modules/src.cmake
|
||||||
|
|
||||||
If you really don't like to do it this way, you can describe your sources and
|
If you really do not like to do it this way, you can describe your sources and
|
||||||
targets in a custom module in a local file and include it like this::
|
targets in a custom module in a local file and include it like this::
|
||||||
|
|
||||||
[my_sources]
|
- my_sources:
|
||||||
source: custom/my_sources.cmake
|
- source:
|
||||||
|
- custom/my_sources.cmake
|
||||||
|
|
||||||
|
|
||||||
How can I do some more sophisticated validation of setup flags?
|
How can I do some more sophisticated validation of setup flags?
|
||||||
@ -121,7 +139,7 @@ How can I do some more sophisticated validation of setup flags?
|
|||||||
|
|
||||||
Sometimes you need to do more sophisticated validation and post-processing
|
Sometimes you need to do more sophisticated validation and post-processing
|
||||||
of setup flags. This can be done by placing a module called ``extensions.py``
|
of setup flags. This can be done by placing a module called ``extensions.py``
|
||||||
under ``cmake/`` (or wherever you have ``autocmake.cfg``).
|
under ``cmake/`` (or wherever you have ``autocmake.yml``).
|
||||||
This file should implement a function with the following signature:
|
This file should implement a function with the following signature:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
34
doc/developers/interpolation.rst
Normal file
34
doc/developers/interpolation.rst
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
.. _interpolation:
|
||||||
|
|
||||||
|
Interpolation
|
||||||
|
=============
|
||||||
|
|
||||||
|
In a custom extension to the YAML specification you can define and reuse
|
||||||
|
variables like this (observe how we interpolate ``url_root``, ``major``,
|
||||||
|
``minor``, ``patch``, and ``components`` in this example)::
|
||||||
|
|
||||||
|
url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
|
major: 1
|
||||||
|
minor: 48
|
||||||
|
patch: 0
|
||||||
|
components: ""
|
||||||
|
fetch:
|
||||||
|
- "%(url_root)modules/boost/boost_unpack.cmake"
|
||||||
|
- "%(url_root)modules/boost/boost_userconfig.cmake"
|
||||||
|
- "%(url_root)modules/boost/boost_configure.cmake"
|
||||||
|
- "%(url_root)modules/boost/boost_build.cmake"
|
||||||
|
- "%(url_root)modules/boost/boost_install.cmake"
|
||||||
|
- "%(url_root)modules/boost/boost_headers.cmake"
|
||||||
|
- "%(url_root)modules/boost/boost_cleanup.cmake"
|
||||||
|
- "http://sourceforge.net/projects/boost/files/boost/%(major).%(minor).%(patch)/boost_%(major)_%(minor)_%(patch).zip"
|
||||||
|
docopt:
|
||||||
|
- "--boost-headers=<BOOST_INCLUDEDIR> Include directories for Boost [default: '']."
|
||||||
|
- "--boost-libraries=<BOOST_LIBRARYDIR> Library directories for Boost [default: '']."
|
||||||
|
- "--build-boost=<FORCE_CUSTOM_BOOST> Deactivate Boost detection and build on-the-fly <ON/OFF> [default: OFF]."
|
||||||
|
define:
|
||||||
|
- "'-DBOOST_INCLUDEDIR=\"{0}\"'.format(arguments['--boost-headers'])"
|
||||||
|
- "'-DBOOST_LIBRARYDIR=\"{0}\"'.format(arguments['--boost-libraries'])"
|
||||||
|
- "'-DFORCE_CUSTOM_BOOST={0}'.format(arguments['--build-boost'])"
|
||||||
|
- "'-DBOOST_MINIMUM_REQUIRED=\"%(major).%(minor).%(patch)\"'"
|
||||||
|
- "'-DBOOST_COMPONENTS_REQUIRED=\"%(components)\"'"
|
@ -20,11 +20,11 @@ Sometimes you may want to avoid using the latest version of a CMake module and
|
|||||||
rather fetch an older version, for example with the hash ``abcd123``. To
|
rather fetch an older version, for example with the hash ``abcd123``. To
|
||||||
achieve this, instead of::
|
achieve this, instead of::
|
||||||
|
|
||||||
[foo]
|
- my_feature:
|
||||||
source: https://github.com/scisoft/autocmake/raw/master/modules/foo.cmake
|
- source: https://github.com/coderefinery/autocmake/raw/master/modules/foo.cmake
|
||||||
|
|
||||||
pin the version to ``abcd123`` (you do not need to specify the full Git hash, a unique
|
pin the version to ``abcd123`` (you do not need to specify the full Git hash, a unique
|
||||||
beginning will do)::
|
beginning will do)::
|
||||||
|
|
||||||
[foo]
|
- my_feature:
|
||||||
source: https://github.com/scisoft/autocmake/raw/abcd123/modules/foo.cmake
|
- source: https://github.com/coderefinery/autocmake/raw/abcd123/modules/foo.cmake
|
||||||
|
@ -73,7 +73,7 @@ def main():
|
|||||||
if s_out != '':
|
if s_out != '':
|
||||||
output.append('\n\n%s' % file_name)
|
output.append('\n\n%s' % file_name)
|
||||||
output.append('-'*len(file_name))
|
output.append('-'*len(file_name))
|
||||||
output.append('`[Source code] <https://github.com/scisoft/autocmake/blob/master/modules/%s>`__' % full_file_name)
|
output.append('`[Source code] <https://github.com/coderefinery/autocmake/blob/master/modules/%s>`__' % full_file_name)
|
||||||
output.append(s_out)
|
output.append(s_out)
|
||||||
|
|
||||||
with open(os.path.join(THIS_DIR, 'module-reference.rst'), 'w') as f:
|
with open(os.path.join(THIS_DIR, 'module-reference.rst'), 'w') as f:
|
||||||
|
@ -7,9 +7,10 @@ Building libraries and executables from sources can be a complex task. Several
|
|||||||
solutions exist to this problem: GNU Makefiles is the traditional approach.
|
solutions exist to this problem: GNU Makefiles is the traditional approach.
|
||||||
Today, CMake is one of the trendier alternatives which can generate Makefiles
|
Today, CMake is one of the trendier alternatives which can generate Makefiles
|
||||||
starting from a file called ``CMakeLists.txt``.
|
starting from a file called ``CMakeLists.txt``.
|
||||||
|
|
||||||
Autocmake composes CMake building blocks into a CMake project and generates
|
Autocmake composes CMake building blocks into a CMake project and generates
|
||||||
``CMakeLists.txt`` as well as a setup script, which serves as a front-end to
|
``CMakeLists.txt`` as well as a setup script, which serves as a front-end to
|
||||||
``CMakeLists.txt``. All this is done based on a lightweight ``autocmake.cfg``
|
``CMakeLists.txt``. All this is done based on a lightweight ``autocmake.yml``
|
||||||
file::
|
file::
|
||||||
|
|
||||||
python update.py --self
|
python update.py --self
|
||||||
@ -19,14 +20,14 @@ file::
|
|||||||
| and updates the update.py script |
|
| and updates the update.py script |
|
||||||
| |
|
| |
|
||||||
v Developer maintaining
|
v Developer maintaining
|
||||||
autocmake.cfg Autocmake
|
autocmake.yml Autocmake
|
||||||
| |
|
| |
|
||||||
| python update.py .. |
|
| python update.py .. |
|
||||||
| |
|
| |
|
||||||
v v
|
v v
|
||||||
CMakeLists.txt (and setup front-end)
|
CMakeLists.txt (and setup front-end)
|
||||||
| |
|
| |
|
||||||
| python setup |
|
| python setup or ./setup |
|
||||||
| which invokes CMake |
|
| which invokes CMake |
|
||||||
v User of the code
|
v User of the code
|
||||||
Makefile (or something else) |
|
Makefile (or something else) |
|
||||||
@ -37,7 +38,7 @@ file::
|
|||||||
Build/install/test targets
|
Build/install/test targets
|
||||||
|
|
||||||
Our main motivation to create Autocmake as a CMake framework library and
|
Our main motivation to create Autocmake as a CMake framework library and
|
||||||
CMake module composer was to simplify CMake code transfer between codes. We got
|
CMake module composer is to simplify CMake code transfer between programs. We got
|
||||||
tired of manually diffing and copy-pasting boiler-plate CMake code and watching
|
tired of manually diffing and copy-pasting boiler-plate CMake code and watching
|
||||||
it diverge while maintaining the CMake infrastructure in a growing number of
|
it diverge while maintaining the CMake infrastructure in a growing number of
|
||||||
scientific projects which typically have very similar requirements:
|
scientific projects which typically have very similar requirements:
|
||||||
|
@ -3,13 +3,11 @@
|
|||||||
Requirements and dependencies
|
Requirements and dependencies
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
Autocmake update and test scripts require Python 2.7 or higher. We try to also
|
Autocmake update and test scripts require Python 2.7 or higher. We also
|
||||||
support Python 3 (tested with Python 3.4). If the script fails with Python 3,
|
support Python 3 (we automatically test with 2.7 and 3.5).
|
||||||
consider this a bug and please file an issue.
|
|
||||||
|
|
||||||
The generated setup script runs with Python >= 2.7 (also tested with Python
|
The generated setup script runs with Python >= 2.6 (also tested with Python
|
||||||
3.4; probably also lower).
|
3.5).
|
||||||
|
|
||||||
.. todo::
|
To generate ``CMakeLists.txt`` and the ``setup`` script, Autocmake
|
||||||
|
requires the pyyaml package.
|
||||||
Figure out lower Python version bound for setup.
|
|
||||||
|
@ -27,6 +27,7 @@ For developers who use Autocmake
|
|||||||
developers/example.rst
|
developers/example.rst
|
||||||
developers/customizing-modules.rst
|
developers/customizing-modules.rst
|
||||||
developers/updating-modules.rst
|
developers/updating-modules.rst
|
||||||
|
developers/interpolation.rst
|
||||||
|
|
||||||
|
|
||||||
For users of projects which use Autocmake
|
For users of projects which use Autocmake
|
||||||
|
@ -47,4 +47,9 @@ How can I select CMake options via the setup script?
|
|||||||
|
|
||||||
Like this::
|
Like this::
|
||||||
|
|
||||||
$ python setup --cmake-options="-DTHIS_OPTION=ON -DTHAT_OPTION=OFF"
|
$ python setup --cmake-options='"-DTHIS_OPTION=ON -DTHAT_OPTION=OFF"'
|
||||||
|
|
||||||
|
We use two sets of quotes because the shell swallows one set of them before
|
||||||
|
passing the arguments to Python. Yeah that's not nice, but nothing we can do
|
||||||
|
about it on the Python side. If you do not use two sets of quotes then the
|
||||||
|
setup command may end up incorrectly saved in `build/setup_command`.
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
# CMakeLists.txt and setup script will be generated from this file
|
|
||||||
# see: http://autocmake.readthedocs.org/en/latest/developers/configuration.html
|
|
||||||
|
|
||||||
# uncomment the following three lines and set the project name
|
|
||||||
# [project]
|
|
||||||
# name: myproject
|
|
||||||
# min_cmake_version: 2.8
|
|
7
example/autocmake.yml
Normal file
7
example/autocmake.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# CMakeLists.txt and setup script will be generated from this file
|
||||||
|
# see: http://autocmake.readthedocs.io/en/latest/developers/configuration.html
|
||||||
|
# adapt the following lines and expand
|
||||||
|
|
||||||
|
name: myproject
|
||||||
|
|
||||||
|
min_cmake_version: 2.8
|
BIN
img/autocmake.png
Normal file
BIN
img/autocmake.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
90
img/autocmake.svg
Normal file
90
img/autocmake.svg
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210mm"
|
||||||
|
height="297mm"
|
||||||
|
viewBox="0 0 744.09448819 1052.3622047"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="autocmake.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.49497475"
|
||||||
|
inkscape:cx="255.71429"
|
||||||
|
inkscape:cy="520"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1001"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
id="g3411">
|
||||||
|
<rect
|
||||||
|
y="326.18109"
|
||||||
|
x="72.047241"
|
||||||
|
height="400"
|
||||||
|
width="600"
|
||||||
|
id="rect3407"
|
||||||
|
style="fill:#0e4089;fill-opacity:1" />
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path3401"
|
||||||
|
d="m 308.00113,650.73649 c 0,-0.42522 5.41704,-26.15959 12.03787,-57.1875 6.62083,-31.0279 12.97185,-60.80188 14.1134,-66.16438 l 2.07552,-9.75 15.3241,0 15.32411,0 0.19153,66.9375 0.19153,66.93751 -29.62903,0 c -19.84348,0 -29.62903,-0.25534 -29.62903,-0.77313 z m 71.0849,-51.16438 c -0.0908,-28.56562 -0.19938,-58.34999 -0.24129,-66.1875 -0.0419,-7.8375 0.0685,-14.67187 0.24533,-15.1875 0.24153,-0.70421 3.74313,-0.9375 14.07204,-0.9375 7.56277,0 13.90344,0.25313 14.09042,0.5625 0.33225,0.54975 29.7486,132.27474 29.7486,133.21275 0,0.26112 -12.99375,0.47476 -28.875,0.47476 l -28.875,0 -0.1651,-51.93751 z m 33.9151,-88.28869 0,-7.52381 -41.22185,0 -41.22186,0 -0.21564,6.9375 -0.21565,6.9375 -7.875,0 -7.875,0 -0.21565,-6.9375 -0.21564,-6.9375 -9.37402,0 -9.37401,0 0.21466,-7.3125 0.21466,-7.3125 76.5,0 76.5,0 0.21562,6.9375 c 0.1638,5.26821 -0.0165,6.9383 -0.75,6.94082 -5.8743,0.0202 -16.4307,0.58678 -16.74262,0.89865 -0.21953,0.21958 -0.55058,3.56584 -0.7356,7.43614 l -0.33638,7.03689 -8.63805,0.21131 -8.63797,0.2113 0,-7.5238 z m -36.7508,-29.8988 c -1.20169,-0.401 -1.01461,-80.3489 0.1883,-80.46723 2.44805,-0.24081 8.48431,0.23383 8.86144,0.6968 0.23316,0.28623 1.1451,4.40167 2.02652,9.14542 0.88143,4.74375 4.16729,22.41712 7.30192,39.27415 3.13463,16.85703 5.55114,30.79733 5.37002,30.97845 -0.38858,0.38858 -22.65342,0.73772 -23.7482,0.37241 z m -32.72028,-1.8842 c 0.24284,-0.96756 3.82423,-18.4238 7.95865,-38.79165 4.13442,-20.36785 7.70756,-37.63246 7.94032,-38.3658 0.34778,-1.09576 1.28287,-1.33336 5.24765,-1.33336 l 4.82446,0 0,40.125 0,40.125 -13.20631,0 -13.20631,0 0.44154,-1.75919 z"
|
||||||
|
style="fill:#ffffff" />
|
||||||
|
<rect
|
||||||
|
y="482.86636"
|
||||||
|
x="77.082703"
|
||||||
|
height="62.629459"
|
||||||
|
width="589.92908"
|
||||||
|
id="rect3409"
|
||||||
|
style="fill:#0e4089;fill-opacity:1" />
|
||||||
|
<text
|
||||||
|
sodipodi:linespacing="125%"
|
||||||
|
id="text3403"
|
||||||
|
y="531.68109"
|
||||||
|
x="192.04724"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
xml:space="preserve"><tspan
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-family:'Pet Me 64';-inkscape-font-specification:'Pet Me 64 Medium';fill:#ffffff"
|
||||||
|
y="531.68109"
|
||||||
|
x="192.04724"
|
||||||
|
id="tspan3405"
|
||||||
|
sodipodi:role="line">Autocmake</tspan></text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -5,11 +5,14 @@
|
|||||||
# Autocmake update time.
|
# Autocmake update time.
|
||||||
# Note that the build-up commands are not Windows-compatible!
|
# Note that the build-up commands are not Windows-compatible!
|
||||||
#
|
#
|
||||||
# Your autocmake.cfg should look like this::
|
# Your autocmake.yml should look like this::
|
||||||
#
|
#
|
||||||
# [boost]
|
# - boost:
|
||||||
# override: {'major': 1, 'minor': 59, 'patch': 0, 'components': 'chrono;timer;system'}
|
# - major: 1
|
||||||
# source: https://github.com/scisoft/autocmake/raw/master/modules/boost/boost.cmake
|
# - minor: 59
|
||||||
|
# - patch: 0
|
||||||
|
# - components: "chrono;timer;system"
|
||||||
|
# - source: "https://github.com/coderefinery/autocmake/raw/master/modules/boost/boost.cmake"
|
||||||
#
|
#
|
||||||
# Cross-dependencies between required components are not checked for.
|
# Cross-dependencies between required components are not checked for.
|
||||||
# For example, Boost.Timer depends on Boost.Chrono and Boost.System thus you
|
# For example, Boost.Timer depends on Boost.Chrono and Boost.System thus you
|
||||||
@ -43,39 +46,41 @@
|
|||||||
# MPI_FOUND
|
# MPI_FOUND
|
||||||
# BUILD_CUSTOM_BOOST
|
# BUILD_CUSTOM_BOOST
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# major=1
|
# url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
# minor=48
|
# major: 1
|
||||||
# patch=0
|
# minor: 48
|
||||||
# components=''
|
# patch: 0
|
||||||
# fetch: https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_unpack.cmake
|
# components: ""
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_userconfig.cmake
|
# fetch:
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_configure.cmake
|
# - "%(url_root)modules/boost/boost_unpack.cmake"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_build.cmake
|
# - "%(url_root)modules/boost/boost_userconfig.cmake"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_install.cmake
|
# - "%(url_root)modules/boost/boost_configure.cmake"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_headers.cmake
|
# - "%(url_root)modules/boost/boost_build.cmake"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/boost/boost_cleanup.cmake
|
# - "%(url_root)modules/boost/boost_install.cmake"
|
||||||
# http://sourceforge.net/projects/boost/files/boost/%(major)s.%(minor)s.%(patch)s/boost_%(major)s_%(minor)s_%(patch)s.zip
|
# - "%(url_root)modules/boost/boost_headers.cmake"
|
||||||
# docopt: --boost-headers=<BOOST_INCLUDEDIR> Include directories for Boost [default: ''].
|
# - "%(url_root)modules/boost/boost_cleanup.cmake"
|
||||||
# --boost-libraries=<BOOST_LIBRARYDIR> Library directories for Boost [default: ''].
|
# - "http://sourceforge.net/projects/boost/files/boost/%(major).%(minor).%(patch)/boost_%(major)_%(minor)_%(patch).zip"
|
||||||
# --build-boost=<FORCE_CUSTOM_BOOST> Deactivate Boost detection and build on-the-fly <ON/OFF> [default: OFF].
|
# docopt:
|
||||||
# define: '-DBOOST_INCLUDEDIR="{0}"'.format(arguments['--boost-headers'])
|
# - "--boost-headers=<BOOST_INCLUDEDIR> Include directories for Boost [default: '']."
|
||||||
# '-DBOOST_LIBRARYDIR="{0}"'.format(arguments['--boost-libraries'])
|
# - "--boost-libraries=<BOOST_LIBRARYDIR> Library directories for Boost [default: '']."
|
||||||
# '-DFORCE_CUSTOM_BOOST="{0}"'.format(arguments['--build-boost'])
|
# - "--build-boost=<FORCE_CUSTOM_BOOST> Deactivate Boost detection and build on-the-fly <ON/OFF> [default: OFF]."
|
||||||
# '-DBOOST_MINIMUM_REQUIRED="%(major)s.%(minor)s.%(patch)s"'
|
# define:
|
||||||
# '-DBOOST_COMPONENTS_REQUIRED="%(components)s"'
|
# - "'-DBOOST_INCLUDEDIR=\"{0}\"'.format(arguments['--boost-headers'])"
|
||||||
|
# - "'-DBOOST_LIBRARYDIR=\"{0}\"'.format(arguments['--boost-libraries'])"
|
||||||
|
# - "'-DFORCE_CUSTOM_BOOST={0}'.format(arguments['--build-boost'])"
|
||||||
|
# - "'-DBOOST_MINIMUM_REQUIRED=\"%(major).%(minor).%(patch)\"'"
|
||||||
|
# - "'-DBOOST_COMPONENTS_REQUIRED=\"%(components)\"'"
|
||||||
|
|
||||||
# FIXME Maintainer should be able to choose between fail (end-user has to satisfy dependency
|
# FIXME Maintainer should be able to choose between fail (end-user has to satisfy dependency
|
||||||
# on its own) and soft-fail (self-build of Boost)
|
# on its own) and soft-fail (self-build of Boost)
|
||||||
# Underscore-separated version number
|
# Underscore-separated version number
|
||||||
string(REGEX REPLACE "\\." "_" BOOSTVER ${BOOST_MINIMUM_REQUIRED})
|
string(REGEX REPLACE "\\." "_" BOOSTVER ${BOOST_MINIMUM_REQUIRED})
|
||||||
|
|
||||||
# Where the Boost .zip archive is located
|
# Where the Boost .zip archive is located
|
||||||
# CMAKE_CURRENT_LIST_DIR is undefined in CMake 2.8.2
|
set(BOOST_ARCHIVE_LOCATION ${PROJECT_SOURCE_DIR}/cmake/downloaded)
|
||||||
# see https://public.kitware.com/Bug/print_bug_page.php?bug_id=11675
|
|
||||||
# workaround: create CMAKE_CURRENT_LIST_DIR
|
|
||||||
get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
|
|
||||||
set(BOOST_ARCHIVE_LOCATION ${CMAKE_CURRENT_LIST_DIR})
|
|
||||||
set(BOOST_ARCHIVE boost_${BOOSTVER}.zip)
|
set(BOOST_ARCHIVE boost_${BOOSTVER}.zip)
|
||||||
|
|
||||||
# FIXME These are possibly not always good settings
|
# FIXME These are possibly not always good settings
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
#
|
#
|
||||||
# CFLAGS
|
# CFLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --cc=<CC> C compiler [default: gcc].
|
# docopt:
|
||||||
# --extra-cc-flags=<EXTRA_CFLAGS> Extra C compiler flags [default: ''].
|
# - "--cc=<CC> C compiler [default: gcc]."
|
||||||
# export: 'CC={0}'.format(arguments['--cc'])
|
# - "--extra-cc-flags=<EXTRA_CFLAGS> Extra C compiler flags [default: '']."
|
||||||
# define: '-DEXTRA_CFLAGS="{0}"'.format(arguments['--extra-cc-flags'])
|
# export: "'CC={0}'.format(arguments['--cc'])"
|
||||||
|
# define: "'-DEXTRA_CFLAGS=\"{0}\"'.format(arguments['--extra-cc-flags'])"
|
||||||
|
|
||||||
enable_language(C)
|
enable_language(C)
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
#
|
#
|
||||||
# CCACHE_FOUND
|
# CCACHE_FOUND
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --ccache=<USE_CCACHE> Toggle use of ccache <ON/OFF> [default: ON].
|
# docopt: "--ccache=<USE_CCACHE> Toggle use of ccache <ON/OFF> [default: ON]."
|
||||||
# define: '-DUSE_CCACHE="{0}"'.format(arguments['--ccache'])
|
# define: "'-DUSE_CCACHE={0}'.format(arguments['--ccache'])"
|
||||||
|
|
||||||
if(USE_CCACHE)
|
if(USE_CCACHE)
|
||||||
find_program(CCACHE_FOUND ccache)
|
find_program(CCACHE_FOUND ccache)
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
# CMAKE_C_FLAGS
|
# CMAKE_C_FLAGS
|
||||||
# CMAKE_CXX_FLAGS
|
# CMAKE_CXX_FLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --coverage Enable code coverage [default: False].
|
# docopt: "--coverage Enable code coverage [default: False]."
|
||||||
# define: '-DENABLE_CODE_COVERAGE=%s' % arguments['--coverage']
|
# define: "'-DENABLE_CODE_COVERAGE={0}'.format(arguments['--coverage'])"
|
||||||
|
|
||||||
option(ENABLE_CODE_COVERAGE "Enable code coverage" OFF)
|
option(ENABLE_CODE_COVERAGE "Enable code coverage" OFF)
|
||||||
|
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
#
|
#
|
||||||
# CXXFLAGS
|
# CXXFLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --cxx=<CXX> C++ compiler [default: g++].
|
# docopt:
|
||||||
# --extra-cxx-flags=<EXTRA_CXXFLAGS> Extra C++ compiler flags [default: ''].
|
# - "--cxx=<CXX> C++ compiler [default: g++]."
|
||||||
# export: 'CXX={0}'.format(arguments['--cxx'])
|
# - "--extra-cxx-flags=<EXTRA_CXXFLAGS> Extra C++ compiler flags [default: '']."
|
||||||
# define: '-DEXTRA_CXXFLAGS="{0}"'.format(arguments['--extra-cxx-flags'])
|
# export: "'CXX={0}'.format(arguments['--cxx'])"
|
||||||
|
# define: "'-DEXTRA_CXXFLAGS=\"{0}\"'.format(arguments['--extra-cxx-flags'])"
|
||||||
|
|
||||||
enable_language(CXX)
|
enable_language(CXX)
|
||||||
|
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
#
|
#
|
||||||
# PREPROCESSOR_DEFINITIONS
|
# PREPROCESSOR_DEFINITIONS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --add-definitions=<STRING> Add preprocesor definitions [default: ''].
|
# docopt: "--add-definitions=<STRING> Add preprocesor definitions [default: '']."
|
||||||
# define: '-DPREPROCESSOR_DEFINITIONS="%s"' % arguments['--add-definitions']
|
# define: "'-DPREPROCESSOR_DEFINITIONS=\"{0}\"'.format(arguments['--add-definitions'])"
|
||||||
|
|
||||||
if(NOT "${PREPROCESSOR_DEFINITIONS}" STREQUAL "")
|
if(NOT "${PREPROCESSOR_DEFINITIONS}" STREQUAL "")
|
||||||
add_definitions(${PREPROCESSOR_DEFINITIONS})
|
add_definitions(${PREPROCESSOR_DEFINITIONS})
|
||||||
|
@ -21,12 +21,13 @@
|
|||||||
#
|
#
|
||||||
# FCFLAGS
|
# FCFLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --fc=<FC> Fortran compiler [default: gfortran].
|
# docopt:
|
||||||
# --extra-fc-flags=<EXTRA_FCFLAGS> Extra Fortran compiler flags [default: ''].
|
# - "--fc=<FC> Fortran compiler [default: gfortran]."
|
||||||
# export: 'FC={0}'.format(arguments['--fc'])
|
# - "--extra-fc-flags=<EXTRA_FCFLAGS> Extra Fortran compiler flags [default: '']."
|
||||||
# define: '-DEXTRA_FCFLAGS="{0}"'.format(arguments['--extra-fc-flags'])
|
# export: "'FC={0}'.format(arguments['--fc'])"
|
||||||
|
# define: "'-DEXTRA_FCFLAGS=\"{0}\"'.format(arguments['--extra-fc-flags'])"
|
||||||
|
|
||||||
enable_language(Fortran)
|
enable_language(Fortran)
|
||||||
|
|
||||||
|
@ -26,14 +26,16 @@
|
|||||||
#
|
#
|
||||||
# FCFLAGS
|
# FCFLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --fc=<FC> Fortran compiler [default: gfortran].
|
# docopt:
|
||||||
# --extra-fc-flags=<EXTRA_FCFLAGS> Extra Fortran compiler flags [default: ''].
|
# - "--fc=<FC> Fortran compiler [default: gfortran]."
|
||||||
# --fc-support=<FC_SUPPORT> Toggle Fortran language support (ON/OFF) [default: ON].
|
# - "--extra-fc-flags=<EXTRA_FCFLAGS> Extra Fortran compiler flags [default: '']."
|
||||||
# export: 'FC={0}'.format(arguments['--fc'])
|
# - "--fc-support=<FC_SUPPORT> Toggle Fortran language support (ON/OFF) [default: ON]."
|
||||||
# define: '-DEXTRA_FCFLAGS="{0}"'.format(arguments['--extra-fc-flags'])
|
# export: "'FC={0}'.format(arguments['--fc'])"
|
||||||
# '-DENABLE_FC_SUPPORT="{0}"'.format(arguments['--fc-support'])
|
# define:
|
||||||
|
# - "'-DEXTRA_FCFLAGS=\"{0}\"'.format(arguments['--extra-fc-flags'])"
|
||||||
|
# - "'-DENABLE_FC_SUPPORT={0}'.format(arguments['--fc-support'])"
|
||||||
|
|
||||||
option(ENABLE_FC_SUPPORT "Enable Fortran language support" ON)
|
option(ENABLE_FC_SUPPORT "Enable Fortran language support" ON)
|
||||||
|
|
||||||
|
@ -65,6 +65,6 @@ function(generate_git_info_header _header_location _header_name)
|
|||||||
|
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
git_info
|
git_info
|
||||||
ALL DEPENDS ${_header_location}/${_header_name}
|
ALL DEPENDS ${PROJECT_BINARY_DIR}/git_info.h
|
||||||
)
|
)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
#
|
#
|
||||||
# GOOGLETEST_ROOT
|
# GOOGLETEST_ROOT
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# define: '-DGOOGLETEST_ROOT=external/googletest'
|
# define: "'-DGOOGLETEST_ROOT=external/googletest/googletest'"
|
||||||
|
|
||||||
set(GOOGLETEST_ROOT external/googletest CACHE STRING "Google Test source root")
|
set(GOOGLETEST_ROOT external/googletest/googletest CACHE STRING "Google Test source root")
|
||||||
|
|
||||||
message(STATUS "GOOGLETEST_ROOT set to ${GOOGLETEST_ROOT}")
|
message(STATUS "GOOGLETEST_ROOT set to ${GOOGLETEST_ROOT}")
|
||||||
|
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
#
|
#
|
||||||
# CMAKE_Fortran_FLAGS
|
# CMAKE_Fortran_FLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --int64 Enable 64bit integers [default: False].
|
# docopt: "--int64 Enable 64bit integers [default: False]."
|
||||||
# define: '-DENABLE_64BIT_INTEGERS=%s' % arguments['--int64']
|
# define: "'-DENABLE_64BIT_INTEGERS={0}'.format(arguments['--int64'])"
|
||||||
|
|
||||||
option(ENABLE_64BIT_INTEGERS "Enable 64-bit integers" OFF)
|
option(ENABLE_64BIT_INTEGERS "Enable 64-bit integers" OFF)
|
||||||
|
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
# ACCELERATE_LIBRARIES - describe me, uncached
|
# ACCELERATE_LIBRARIES - describe me, uncached
|
||||||
# ACCELERATE_INCLUDE_DIR - describe me, uncached
|
# ACCELERATE_INCLUDE_DIR - describe me, uncached
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --accelerate Find and link to ACCELERATE [default: False].
|
# url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
# define: '-DENABLE_ACCELERATE=%s' % arguments['--accelerate']
|
# docopt: "--accelerate Find and link to ACCELERATE [default: False]."
|
||||||
# fetch: https://github.com/scisoft/autocmake/raw/master/modules/find/find_libraries.cmake
|
# define: "'-DENABLE_ACCELERATE={0}'.format(arguments['--accelerate'])"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/find/find_include_files.cmake
|
# fetch:
|
||||||
|
# - "%(url_root)modules/find/find_libraries.cmake"
|
||||||
|
# - "%(url_root)modules/find/find_include_files.cmake"
|
||||||
|
|
||||||
option(ENABLE_ACCELERATE "Find and link to ACCELERATE" OFF)
|
option(ENABLE_ACCELERATE "Find and link to ACCELERATE" OFF)
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
# ACML_LIBRARIES
|
# ACML_LIBRARIES
|
||||||
# ACML_INCLUDE_DIR
|
# ACML_INCLUDE_DIR
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --acml Find and link to ACML [default: False].
|
# docopt: "--acml Find and link to ACML [default: False]."
|
||||||
# define: '-DENABLE_ACML=%s' % arguments['--acml']
|
# define: "'-DENABLE_ACML={0}'.format(arguments['--acml'])"
|
||||||
|
|
||||||
option(ENABLE_ACML "Find and link to ACML" OFF)
|
option(ENABLE_ACML "Find and link to ACML" OFF)
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
# ATLAS_LIBRARIES
|
# ATLAS_LIBRARIES
|
||||||
# ATLAS_INCLUDE_DIR
|
# ATLAS_INCLUDE_DIR
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --atlas Find and link to ATLAS [default: False].
|
# docopt: "--atlas Find and link to ATLAS [default: False]."
|
||||||
# define: '-DENABLE_ATLAS=%s' % arguments['--atlas']
|
# define: "'-DENABLE_ATLAS={0}'.format(arguments['--atlas'])"
|
||||||
|
|
||||||
option(ENABLE_ATLAS "Find and link to ATLAS" OFF)
|
option(ENABLE_ATLAS "Find and link to ATLAS" OFF)
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
# BLAS_LIBRARIES
|
# BLAS_LIBRARIES
|
||||||
# BLAS_INCLUDE_DIR
|
# BLAS_INCLUDE_DIR
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --blas Find and link to BLAS [default: False].
|
# docopt: "--blas Find and link to BLAS [default: False]."
|
||||||
# define: '-DENABLE_BLAS=%s' % arguments['--blas']
|
# define: "'-DENABLE_BLAS={0}'.format(arguments['--blas'])"
|
||||||
|
|
||||||
option(ENABLE_BLAS "Find and link to BLAS" OFF)
|
option(ENABLE_BLAS "Find and link to BLAS" OFF)
|
||||||
|
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
# CBLAS_LIBRARIES - describe me, uncached
|
# CBLAS_LIBRARIES - describe me, uncached
|
||||||
# CBLAS_INCLUDE_DIR - describe me, uncached
|
# CBLAS_INCLUDE_DIR - describe me, uncached
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --cblas Find and link to CBLAS [default: False].
|
# url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
# define: '-DENABLE_CBLAS=%s' % arguments['--cblas']
|
# docopt: "--cblas Find and link to CBLAS [default: False]."
|
||||||
# fetch: https://github.com/scisoft/autocmake/raw/master/modules/find/find_libraries.cmake
|
# define: "'-DENABLE_CBLAS={0}'.format(arguments['--cblas'])"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/find/find_include_files.cmake
|
# fetch:
|
||||||
|
# - "%(url_root)modules/find/find_libraries.cmake"
|
||||||
|
# - "%(url_root)modules/find/find_include_files.cmake"
|
||||||
|
|
||||||
option(ENABLE_CBLAS "Find and link to CBLAS" OFF)
|
option(ENABLE_CBLAS "Find and link to CBLAS" OFF)
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
# GOTO_LIBRARIES
|
# GOTO_LIBRARIES
|
||||||
# GOTO_INCLUDE_DIR
|
# GOTO_INCLUDE_DIR
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --goto Find and link to GOTO [default: False].
|
# docopt: "--goto Find and link to GOTO [default: False]."
|
||||||
# define: '-DENABLE_GOTO=%s' % arguments['--goto']
|
# define: "'-DENABLE_GOTO={0}'.format(arguments['--goto'])"
|
||||||
|
|
||||||
option(ENABLE_GOTO "Find and link to GOTO" OFF)
|
option(ENABLE_GOTO "Find and link to GOTO" OFF)
|
||||||
|
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
# LAPACK_LIBRARIES
|
# LAPACK_LIBRARIES
|
||||||
# LAPACK_INCLUDE_DIR
|
# LAPACK_INCLUDE_DIR
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --lapack Find and link to LAPACK [default: False].
|
# docopt: "--lapack Find and link to LAPACK [default: False]."
|
||||||
# define: '-DENABLE_LAPACK=%s' % arguments['--lapack']
|
# define: "'-DENABLE_LAPACK={0}'.format(arguments['--lapack'])"
|
||||||
|
|
||||||
option(ENABLE_LAPACK "Find and link to LAPACK" OFF)
|
option(ENABLE_LAPACK "Find and link to LAPACK" OFF)
|
||||||
|
|
||||||
|
@ -8,12 +8,14 @@
|
|||||||
# LAPACKE_LIBRARIES - describe me, uncached
|
# LAPACKE_LIBRARIES - describe me, uncached
|
||||||
# LAPACKE_INCLUDE_DIR - describe me, uncached
|
# LAPACKE_INCLUDE_DIR - describe me, uncached
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --lapacke Find and link to LAPACKE [default: False].
|
# url_root: https://github.com/coderefinery/autocmake/raw/master/
|
||||||
# define: '-DENABLE_LAPACKE=%s' % arguments['--lapacke']
|
# docopt: "--lapacke Find and link to LAPACKE [default: False]."
|
||||||
# fetch: https://github.com/scisoft/autocmake/raw/master/modules/find/find_libraries.cmake
|
# define: "'-DENABLE_LAPACKE={0}'.format(arguments['--lapacke'])"
|
||||||
# https://github.com/scisoft/autocmake/raw/master/modules/find/find_include_files.cmake
|
# fetch:
|
||||||
|
# - "%(url_root)modules/find/find_libraries.cmake"
|
||||||
|
# - "%(url_root)modules/find/find_include_files.cmake"
|
||||||
|
|
||||||
option(ENABLE_LAPACKE "Find and link to LAPACKE" OFF)
|
option(ENABLE_LAPACKE "Find and link to LAPACKE" OFF)
|
||||||
|
|
||||||
|
@ -37,18 +37,20 @@
|
|||||||
# MKL_ROOT
|
# MKL_ROOT
|
||||||
# MKLROOT
|
# MKLROOT
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --blas=<BLAS> Detect and link BLAS library (auto or off) [default: auto].
|
# docopt:
|
||||||
# --lapack=<LAPACK> Detect and link LAPACK library (auto or off) [default: auto].
|
# - "--blas=<BLAS> Detect and link BLAS library (auto or off) [default: auto]."
|
||||||
# --mkl=<MKL> Pass MKL flag to the Intel compiler and linker and skip BLAS/LAPACK detection (sequential, parallel, cluster, or off) [default: off].
|
# - "--lapack=<LAPACK> Detect and link LAPACK library (auto or off) [default: auto]."
|
||||||
# define: '-DENABLE_BLAS=%s' % arguments['--blas']
|
# - "--mkl=<MKL> Pass MKL flag to the Intel compiler and linker and skip BLAS/LAPACK detection (sequential, parallel, cluster, or off) [default: off]."
|
||||||
# '-DENABLE_LAPACK=%s' % arguments['--lapack']
|
# define:
|
||||||
# '-DMKL_FLAG=%s' % arguments['--mkl']
|
# - "'-DENABLE_BLAS={0}'.format(arguments['--blas'])"
|
||||||
# '-DMATH_LIB_SEARCH_ORDER="MKL;ESSL;OPENBLAS;ATLAS;ACML;SYSTEM_NATIVE"'
|
# - "'-DENABLE_LAPACK={0}'.format(arguments['--lapack'])"
|
||||||
# '-DBLAS_LANG=Fortran'
|
# - "'-DMKL_FLAG={0}'.format(arguments['--mkl'])"
|
||||||
# '-DLAPACK_LANG=Fortran'
|
# - "'-DMATH_LIB_SEARCH_ORDER=\"MKL;ESSL;OPENBLAS;ATLAS;ACML;SYSTEM_NATIVE\"'"
|
||||||
# warning: 'This module is deprecated and will be removed in future versions'
|
# - "'-DBLAS_LANG=Fortran'"
|
||||||
|
# - "'-DLAPACK_LANG=Fortran'"
|
||||||
|
# warning: "the math_libs.cmake module is deprecated and will be removed in future versions"
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# ENABLE_STATIC_LINKING
|
# ENABLE_STATIC_LINKING
|
||||||
@ -506,7 +508,7 @@ if (ENABLE_STATIC_LINKING)
|
|||||||
BLAS_TYPE MATCHES SYSTEM_NATIVE OR
|
BLAS_TYPE MATCHES SYSTEM_NATIVE OR
|
||||||
BLAS_TYPE MATCHES OPENBLAS)
|
BLAS_TYPE MATCHES OPENBLAS)
|
||||||
#cc_blas_static with ATLAS on travis-ci needs -lm
|
#cc_blas_static with ATLAS on travis-ci needs -lm
|
||||||
set(MATH_LIBS ${MATH_LIBS} -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -lm)
|
set(MATH_LIBS ${MATH_LIBS} -Wl,--whole-archive -lpthread -ldl -Wl,--no-whole-archive -lm)
|
||||||
endif()
|
endif()
|
||||||
if (LAPACK_TYPE MATCHES MKL OR
|
if (LAPACK_TYPE MATCHES MKL OR
|
||||||
BLAS_TYPE MATCHES MKL)
|
BLAS_TYPE MATCHES MKL)
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
# CMAKE_C_FLAGS
|
# CMAKE_C_FLAGS
|
||||||
# CMAKE_CXX_FLAGS
|
# CMAKE_CXX_FLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --mpi Enable MPI parallelization [default: False].
|
# docopt: "--mpi Enable MPI parallelization [default: False]."
|
||||||
# define: '-DENABLE_MPI=%s' % arguments['--mpi']
|
# define: "'-DENABLE_MPI={0}'.format(arguments['--mpi'])"
|
||||||
|
|
||||||
option(ENABLE_MPI "Enable MPI parallelization" OFF)
|
option(ENABLE_MPI "Enable MPI parallelization" OFF)
|
||||||
|
|
||||||
|
@ -13,33 +13,14 @@
|
|||||||
# CMAKE_C_FLAGS
|
# CMAKE_C_FLAGS
|
||||||
# CMAKE_CXX_FLAGS
|
# CMAKE_CXX_FLAGS
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --omp Enable OpenMP parallelization [default: False].
|
# docopt: "--omp Enable OpenMP parallelization [default: False]."
|
||||||
# define: '-DENABLE_OPENMP=%s' % arguments['--omp']
|
# define: "'-DENABLE_OPENMP={0}'.format(arguments['--omp'])"
|
||||||
|
|
||||||
option(ENABLE_OPENMP "Enable OpenMP parallelization" OFF)
|
option(ENABLE_OPENMP "Enable OpenMP parallelization" OFF)
|
||||||
|
|
||||||
if(ENABLE_OPENMP)
|
if(ENABLE_OPENMP)
|
||||||
if(DEFINED CMAKE_Fortran_COMPILER_ID)
|
|
||||||
# we do this in a pedestrian way because the Fortran support is relatively recent
|
|
||||||
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
|
|
||||||
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fopenmp")
|
|
||||||
endif()
|
|
||||||
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
|
|
||||||
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -openmp")
|
|
||||||
endif()
|
|
||||||
if(CMAKE_Fortran_COMPILER_ID MATCHES PGI)
|
|
||||||
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -mp")
|
|
||||||
endif()
|
|
||||||
if(CMAKE_Fortran_COMPILER_ID MATCHES XL)
|
|
||||||
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qsmp")
|
|
||||||
endif()
|
|
||||||
if(CMAKE_Fortran_COMPILER_ID MATCHES Cray)
|
|
||||||
# do nothing in this case
|
|
||||||
endif()
|
|
||||||
set(OPENMP_FOUND TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT OPENMP_FOUND)
|
if(NOT OPENMP_FOUND)
|
||||||
find_package(OpenMP)
|
find_package(OpenMP)
|
||||||
@ -53,5 +34,35 @@ if(ENABLE_OPENMP)
|
|||||||
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
if(DEFINED CMAKE_Fortran_COMPILER_ID)
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED CMAKE_Fortran_COMPILER_ID AND NOT DEFINED OpenMP_Fortran_FLAGS)
|
||||||
|
# we do this in a pedestrian way because the Fortran support is relatively recent
|
||||||
|
if(CMAKE_Fortran_COMPILER_ID MATCHES GNU)
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fopenmp")
|
||||||
|
endif()
|
||||||
|
if(CMAKE_Fortran_COMPILER_ID MATCHES Intel)
|
||||||
|
if(WIN32)
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Qopenmp")
|
||||||
|
elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" AND
|
||||||
|
"${CMAKE_Fortran_COMPILER_VERSION}" VERSION_LESS "15.0.0.20140528")
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -openmp")
|
||||||
|
else()
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qopenmp")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(CMAKE_Fortran_COMPILER_ID MATCHES PGI)
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -mp")
|
||||||
|
endif()
|
||||||
|
if(CMAKE_Fortran_COMPILER_ID MATCHES XL)
|
||||||
|
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -qsmp")
|
||||||
|
endif()
|
||||||
|
if(CMAKE_Fortran_COMPILER_ID MATCHES Cray)
|
||||||
|
# do nothing in this case
|
||||||
|
endif()
|
||||||
|
set(OPENMP_FOUND TRUE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
# PYTHON_VERSION_MINOR - Python minor version found e.g. 5
|
# PYTHON_VERSION_MINOR - Python minor version found e.g. 5
|
||||||
# PYTHON_VERSION_PATCH - Python patch version found e.g. 2
|
# PYTHON_VERSION_PATCH - Python patch version found e.g. 2
|
||||||
#
|
#
|
||||||
# autocmake.cfg configuration::
|
# autocmake.yml configuration::
|
||||||
#
|
#
|
||||||
# docopt: --python=<PYTHON_INTERPRETER> The Python interpreter (development version) to use. [default: ''].
|
# docopt: "--python=<PYTHON_INTERPRETER> The Python interpreter (development version) to use. [default: '']."
|
||||||
# define: '-DPYTHON_INTERPRETER="%s"' % arguments['--python']
|
# define: "'-DPYTHON_INTERPRETER=\"{0}\"'.format(arguments['--python'])"
|
||||||
|
|
||||||
if("${PYTHON_INTERPRETER}" STREQUAL "")
|
if("${PYTHON_INTERPRETER}" STREQUAL "")
|
||||||
find_package(PythonInterp REQUIRED)
|
find_package(PythonInterp REQUIRED)
|
||||||
|
43
modules/save_flags.cmake
Normal file
43
modules/save_flags.cmake
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#.rst:
|
||||||
|
#
|
||||||
|
# Take care of updating the cache for fresh configurations.
|
||||||
|
#
|
||||||
|
# Variables modified (provided the corresponding language is enabled)::
|
||||||
|
#
|
||||||
|
# DEFAULT_Fortran_FLAGS_SET
|
||||||
|
# DEFAULT_C_FLAGS_SET
|
||||||
|
# DEFAULT_CXX_FLAGS_SET
|
||||||
|
|
||||||
|
macro(save_compiler_flags lang)
|
||||||
|
if (NOT DEFINED DEFAULT_${lang}_FLAGS_SET)
|
||||||
|
mark_as_advanced(DEFAULT_${lang}_FLAGS_SET)
|
||||||
|
|
||||||
|
set (DEFAULT_${lang}_FLAGS_SET ON
|
||||||
|
CACHE INTERNAL
|
||||||
|
"Flag that the default ${lang} compiler flags have been set.")
|
||||||
|
|
||||||
|
set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}"
|
||||||
|
CACHE STRING
|
||||||
|
"Flags used by the compiler during all builds." FORCE)
|
||||||
|
|
||||||
|
set(CMAKE_${lang}_FLAGS_DEBUG "${CMAKE_${lang}_FLAGS_DEBUG}"
|
||||||
|
CACHE STRING
|
||||||
|
"Flags used by the compiler during debug builds." FORCE)
|
||||||
|
|
||||||
|
set(CMAKE_${lang}_FLAGS_RELEASE "${CMAKE_${lang}_FLAGS_RELEASE}"
|
||||||
|
CACHE STRING
|
||||||
|
"Flags used by the compiler during release builds." FORCE)
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
if(DEFINED CMAKE_Fortran_COMPILER_ID)
|
||||||
|
save_compiler_flags(Fortran)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED CMAKE_C_COMPILER_ID)
|
||||||
|
save_compiler_flags(C)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
||||||
|
save_compiler_flags(CXX)
|
||||||
|
endif()
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pep8
|
||||||
|
pytest
|
||||||
|
pyyaml
|
@ -1,16 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[boost]
|
|
||||||
override: {'major': 1, 'minor': 48, 'patch': 0}
|
|
||||||
source: ../../../modules/boost/boost.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
14
test/boost_header_only/cmake/autocmake.yml
Normal file
14
test/boost_header_only/cmake/autocmake.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- boost:
|
||||||
|
- major: 1
|
||||||
|
- minor: 48
|
||||||
|
- patch: 0
|
||||||
|
- source: ../../../modules/boost/boost.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,25 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[mpi]
|
|
||||||
source: ../../../modules/mpi.cmake
|
|
||||||
|
|
||||||
[python_interpreter]
|
|
||||||
source: ../../../modules/python_interpreter.cmake
|
|
||||||
|
|
||||||
[python_libs]
|
|
||||||
source: ../../../modules/python_libs.cmake
|
|
||||||
|
|
||||||
[boost]
|
|
||||||
override: {'major': 1, 'minor': 59, 'patch': 0, 'components': 'mpi;serialization;python'}
|
|
||||||
source: ../../../modules/boost/boost.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
21
test/boost_libs/cmake/autocmake.yml
Normal file
21
test/boost_libs/cmake/autocmake.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- mpi:
|
||||||
|
- source: ../../../modules/mpi.cmake
|
||||||
|
- python_interpreter:
|
||||||
|
- source: ../../../modules/python_interpreter.cmake
|
||||||
|
- python_libs:
|
||||||
|
- source: ../../../modules/python_libs.cmake
|
||||||
|
- boost:
|
||||||
|
- major: 1
|
||||||
|
- minor: 59
|
||||||
|
- patch: 0
|
||||||
|
- components: 'mpi;serialization;python'
|
||||||
|
- source: ../../../modules/boost/boost.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,12 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
9
test/cxx/cmake/autocmake.yml
Normal file
9
test/cxx/cmake/autocmake.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[math]
|
|
||||||
source: ../../../modules/math/accelerate.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/cxx_accelerate/cmake/autocmake.yml
Normal file
11
test/cxx_accelerate/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- math:
|
||||||
|
- source: ../../../modules/math/accelerate.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[math]
|
|
||||||
source: ../../../modules/math/cblas.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/cxx_cblas/cmake/autocmake.yml
Normal file
11
test/cxx_cblas/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- math:
|
||||||
|
- source: ../../../modules/math/cblas.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,12 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
9
test/extra_cmake_options/cmake/autocmake.yml
Normal file
9
test/extra_cmake_options/cmake/autocmake.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,12 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[fc]
|
|
||||||
source: ../../../modules/fc.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
9
test/fc/cmake/autocmake.yml
Normal file
9
test/fc/cmake/autocmake.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- fc:
|
||||||
|
- source: ../../../modules/fc.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[fc]
|
|
||||||
source: ../../../modules/fc.cmake
|
|
||||||
|
|
||||||
[math]
|
|
||||||
source: ../../../modules/math/blas.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/fc_blas/cmake/autocmake.yml
Normal file
11
test/fc_blas/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- fc:
|
||||||
|
- source: ../../../modules/fc.cmake
|
||||||
|
- math:
|
||||||
|
- source: ../../../modules/math/blas.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[fc]
|
|
||||||
source: ../../../modules/fc.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
||||||
|
|
||||||
[git_info]
|
|
||||||
source: ../../../modules/git_info/git_info.cmake
|
|
11
test/fc_git_info/cmake/autocmake.yml
Normal file
11
test/fc_git_info/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- fc:
|
||||||
|
- source: ../../../modules/fc.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
||||||
|
- git_info:
|
||||||
|
- source: ../../../modules/git_info/git_info.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[fc]
|
|
||||||
source: ../../../modules/fc.cmake
|
|
||||||
|
|
||||||
[int64]
|
|
||||||
source: ../../../modules/int64.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/fc_int64/cmake/autocmake.yml
Normal file
11
test/fc_int64/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- fc:
|
||||||
|
- source: ../../../modules/fc.cmake
|
||||||
|
- int64:
|
||||||
|
- source: ../../../modules/int64.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[fc]
|
|
||||||
source: ../../../modules/fc.cmake
|
|
||||||
|
|
||||||
[math]
|
|
||||||
source: ../../../modules/math/lapack.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/fc_lapack/cmake/autocmake.yml
Normal file
11
test/fc_lapack/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- fc:
|
||||||
|
- source: ../../../modules/fc.cmake
|
||||||
|
- math:
|
||||||
|
- source: ../../../modules/math/lapack.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[fc]
|
|
||||||
source: ../../../modules/fc.cmake
|
|
||||||
|
|
||||||
[omp]
|
|
||||||
source: ../../../modules/omp.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/fc_omp/cmake/autocmake.yml
Normal file
11
test/fc_omp/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- fc:
|
||||||
|
- source: ../../../modules/fc.cmake
|
||||||
|
- omp:
|
||||||
|
- source: ../../../modules/omp.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[python_interpreter]
|
|
||||||
source: ../../../modules/python_interpreter.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
13
test/python_interpreter/cmake/autocmake.yml
Normal file
13
test/python_interpreter/cmake/autocmake.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- python_interpreter:
|
||||||
|
- source: ../../../modules/python_interpreter.cmake
|
||||||
|
- python_libs:
|
||||||
|
- source: ../../../modules/python_libs.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,15 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[python_interpreter]
|
|
||||||
source: ../../../modules/python_interpreter.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
11
test/python_interpreter_custom/cmake/autocmake.yml
Normal file
11
test/python_interpreter_custom/cmake/autocmake.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- python_interpreter:
|
||||||
|
- source: ../../../modules/python_interpreter.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,18 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[python_interpreter]
|
|
||||||
source: ../../../modules/python_interpreter.cmake
|
|
||||||
|
|
||||||
[python_libs]
|
|
||||||
source: ../../../modules/python_libs.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
13
test/python_libs/cmake/autocmake.yml
Normal file
13
test/python_libs/cmake/autocmake.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- python_interpreter:
|
||||||
|
- source: ../../../modules/python_interpreter.cmake
|
||||||
|
- python_libs:
|
||||||
|
- source: ../../../modules/python_libs.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
@ -1,18 +0,0 @@
|
|||||||
[project]
|
|
||||||
name: example
|
|
||||||
min_cmake_version: 2.8
|
|
||||||
|
|
||||||
[cxx]
|
|
||||||
source: ../../../modules/cxx.cmake
|
|
||||||
|
|
||||||
[python_interpreter]
|
|
||||||
source: ../../../modules/python_interpreter.cmake
|
|
||||||
|
|
||||||
[python_libs]
|
|
||||||
source: ../../../modules/python_libs.cmake
|
|
||||||
|
|
||||||
[default_build_paths]
|
|
||||||
source: ../../../modules/default_build_paths.cmake
|
|
||||||
|
|
||||||
[src]
|
|
||||||
source: ../../../modules/src.cmake
|
|
13
test/python_libs_custom/cmake/autocmake.yml
Normal file
13
test/python_libs_custom/cmake/autocmake.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
name: example
|
||||||
|
min_cmake_version: 2.8
|
||||||
|
modules:
|
||||||
|
- cxx:
|
||||||
|
- source: ../../../modules/cxx.cmake
|
||||||
|
- python_interpreter:
|
||||||
|
- source: ../../../modules/python_interpreter.cmake
|
||||||
|
- python_libs:
|
||||||
|
- source: ../../../modules/python_libs.cmake
|
||||||
|
- default_build_paths:
|
||||||
|
- source: ../../../modules/default_build_paths.cmake
|
||||||
|
- src:
|
||||||
|
- source: ../../../modules/src.cmake
|
30
test/test.py
30
test/test.py
@ -10,15 +10,11 @@ import pytest
|
|||||||
|
|
||||||
HERE = os.path.abspath(os.path.dirname(__file__))
|
HERE = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
skip_on_windows = pytest.mark.skipif('sys.platform == "win32"', reason="not working on windows")
|
|
||||||
skip_on_osx = pytest.mark.skipif('sys.platform == "darwin"', reason="not working on osx")
|
skip_on_osx = pytest.mark.skipif('sys.platform == "darwin"', reason="not working on osx")
|
||||||
skip_on_linux = pytest.mark.skipif('sys.platform == "linux2"', reason="not working on linux")
|
skip_on_linux = pytest.mark.skipif('sys.platform == "linux2"', reason="not working on linux")
|
||||||
skip_always = pytest.mark.skipif('1 == 1', reason="tests are broken")
|
skip_always = pytest.mark.skipif('1 == 1', reason="tests are broken")
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def exe(command):
|
def exe(command):
|
||||||
"""
|
"""
|
||||||
Executes command and returns string representations of stdout and stderr captured from the console.
|
Executes command and returns string representations of stdout and stderr captured from the console.
|
||||||
@ -42,8 +38,6 @@ def exe(command):
|
|||||||
|
|
||||||
return stdout, stderr
|
return stdout, stderr
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def configure_build_and_exe(name, setup_command, launcher=None):
|
def configure_build_and_exe(name, setup_command, launcher=None):
|
||||||
|
|
||||||
@ -52,15 +46,9 @@ def configure_build_and_exe(name, setup_command, launcher=None):
|
|||||||
os.chdir(os.path.join(HERE, name, 'cmake'))
|
os.chdir(os.path.join(HERE, name, 'cmake'))
|
||||||
shutil.copy(os.path.join('..', '..', '..', 'update.py'), 'update.py')
|
shutil.copy(os.path.join('..', '..', '..', 'update.py'), 'update.py')
|
||||||
|
|
||||||
dst_dir = 'lib'
|
if os.path.exists('autocmake'):
|
||||||
if not os.path.exists(dst_dir):
|
shutil.rmtree('autocmake')
|
||||||
os.makedirs(dst_dir)
|
shutil.copytree(os.path.join('..', '..', '..', 'autocmake'), 'autocmake')
|
||||||
shutil.copy(os.path.join('..', '..', '..', dst_dir, 'config.py'), dst_dir)
|
|
||||||
|
|
||||||
dst_dir = os.path.join('lib', 'docopt')
|
|
||||||
if not os.path.exists(dst_dir):
|
|
||||||
os.makedirs(dst_dir)
|
|
||||||
shutil.copy(os.path.join('..', '..', '..', dst_dir, 'docopt.py'), dst_dir)
|
|
||||||
|
|
||||||
stdout, stderr = exe('python update.py ..')
|
stdout, stderr = exe('python update.py ..')
|
||||||
os.chdir(os.path.join(HERE, name))
|
os.chdir(os.path.join(HERE, name))
|
||||||
@ -90,8 +78,6 @@ def configure_build_and_exe(name, setup_command, launcher=None):
|
|||||||
|
|
||||||
assert 'PASSED' in stdout
|
assert 'PASSED' in stdout
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def test_extra_cmake_options():
|
def test_extra_cmake_options():
|
||||||
configure_build_and_exe('extra_cmake_options', 'python setup --cxx=g++ --cmake-options="-DENABLE_SOMETHING=OFF -DENABLE_FOO=ON"')
|
configure_build_and_exe('extra_cmake_options', 'python setup --cxx=g++ --cmake-options="-DENABLE_SOMETHING=OFF -DENABLE_FOO=ON"')
|
||||||
@ -119,24 +105,20 @@ def test_fc_omp():
|
|||||||
configure_build_and_exe('fc_omp', 'python setup --omp --fc=gfortran')
|
configure_build_and_exe('fc_omp', 'python setup --omp --fc=gfortran')
|
||||||
|
|
||||||
|
|
||||||
@skip_on_windows
|
|
||||||
def test_fc_blas():
|
def test_fc_blas():
|
||||||
configure_build_and_exe('fc_blas', 'python setup --fc=gfortran --blas')
|
configure_build_and_exe('fc_blas', 'python setup --fc=gfortran --blas')
|
||||||
|
|
||||||
|
|
||||||
@skip_on_windows
|
|
||||||
def test_fc_lapack():
|
def test_fc_lapack():
|
||||||
configure_build_and_exe('fc_lapack', 'python setup --fc=gfortran --lapack')
|
configure_build_and_exe('fc_lapack', 'python setup --fc=gfortran --lapack')
|
||||||
|
|
||||||
|
|
||||||
@skip_on_osx
|
@skip_on_osx
|
||||||
@skip_on_windows
|
|
||||||
def test_cxx_cblas():
|
def test_cxx_cblas():
|
||||||
configure_build_and_exe('cxx_cblas', 'python setup --cxx=g++ --cblas')
|
configure_build_and_exe('cxx_cblas', 'python setup --cxx=g++ --cblas')
|
||||||
|
|
||||||
|
|
||||||
@skip_on_linux
|
@skip_on_linux
|
||||||
@skip_on_windows
|
|
||||||
def test_cxx_accelerate():
|
def test_cxx_accelerate():
|
||||||
configure_build_and_exe('cxx_accelerate', 'python setup --cxx=g++ --accelerate')
|
configure_build_and_exe('cxx_accelerate', 'python setup --cxx=g++ --accelerate')
|
||||||
|
|
||||||
@ -150,23 +132,19 @@ def test_python_interpreter_custom():
|
|||||||
configure_build_and_exe('python_interpreter_custom', setup)
|
configure_build_and_exe('python_interpreter_custom', setup)
|
||||||
|
|
||||||
|
|
||||||
@skip_on_windows
|
|
||||||
def test_python_libs():
|
def test_python_libs():
|
||||||
configure_build_and_exe('python_libs', 'python setup --cxx=g++')
|
configure_build_and_exe('python_libs', 'python setup --cxx=g++')
|
||||||
|
|
||||||
|
|
||||||
@skip_on_windows
|
|
||||||
def test_python_libs_custom():
|
def test_python_libs_custom():
|
||||||
python_executable = sys.executable
|
python_executable = sys.executable
|
||||||
configure_build_and_exe('python_libs_custom', 'python setup --cxx=g++ --python={}'.format(python_executable))
|
configure_build_and_exe('python_libs_custom', 'python setup --cxx=g++ --python={0}'.format(python_executable))
|
||||||
|
|
||||||
|
|
||||||
@skip_on_windows
|
|
||||||
def test_boost_header_only():
|
def test_boost_header_only():
|
||||||
configure_build_and_exe('boost_header_only', 'python setup --cxx=g++')
|
configure_build_and_exe('boost_header_only', 'python setup --cxx=g++')
|
||||||
|
|
||||||
|
|
||||||
@skip_on_osx
|
@skip_on_osx
|
||||||
@skip_on_windows
|
|
||||||
def test_boost_libs():
|
def test_boost_libs():
|
||||||
configure_build_and_exe('boost_libs', 'python setup --cxx=g++ --mpi')
|
configure_build_and_exe('boost_libs', 'python setup --cxx=g++ --mpi')
|
||||||
|
789
update.py
789
update.py
@ -2,41 +2,278 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import datetime
|
|
||||||
import ast
|
|
||||||
import collections
|
|
||||||
|
|
||||||
# we do not use the nicer sys.version_info.major
|
|
||||||
# for compatibility with Python < 2.7
|
|
||||||
if sys.version_info[0] > 2:
|
|
||||||
from io import StringIO
|
|
||||||
from configparser import ConfigParser
|
|
||||||
import urllib.request
|
|
||||||
|
|
||||||
class URLopener(urllib.request.FancyURLopener):
|
|
||||||
def http_error_default(self, url, fp, errcode, errmsg, headers):
|
|
||||||
sys.stderr.write("ERROR: could not fetch %s\n" % url)
|
|
||||||
sys.exit(-1)
|
|
||||||
else:
|
|
||||||
from StringIO import StringIO
|
|
||||||
from ConfigParser import ConfigParser
|
|
||||||
import urllib
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
AUTOCMAKE_GITHUB_URL = 'https://github.com/scisoft/autocmake'
|
if sys.version_info[0] == 2 and sys.version_info[1] < 7:
|
||||||
|
sys.stderr.write("ERROR: update.py requires at least Python 2.7\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
AUTOCMAKE_GITHUB_URL = 'https://github.com/coderefinery/autocmake/raw/master/'
|
||||||
|
|
||||||
|
|
||||||
|
def check_for_yaml():
|
||||||
|
try:
|
||||||
|
import yaml
|
||||||
|
except:
|
||||||
|
sys.stderr.write("ERROR: you need to install the pyyaml package\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
def print_progress_bar(text, done, total, width):
|
||||||
|
"""
|
||||||
|
Print progress bar.
|
||||||
|
"""
|
||||||
|
if total > 0:
|
||||||
|
n = int(float(width) * float(done) / float(total))
|
||||||
|
sys.stdout.write("\r{0} [{1}{2}] ({3}/{4})".format(text, '#' * n, ' ' * (width - n), done, total))
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def flat_add(l, x):
|
||||||
|
if isinstance(x, int):
|
||||||
|
l.append(x)
|
||||||
|
return l
|
||||||
|
elif isinstance(x, str):
|
||||||
|
l.append(x)
|
||||||
|
return l
|
||||||
|
else:
|
||||||
|
return l + x
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_modules(config, relative_path, download_directory):
|
||||||
|
"""
|
||||||
|
Assemble modules which will
|
||||||
|
be included in CMakeLists.txt.
|
||||||
|
"""
|
||||||
|
from collections import Iterable, namedtuple, defaultdict
|
||||||
|
from autocmake.extract import extract_list, to_d, to_l
|
||||||
|
from autocmake.parse_rst import parse_cmake_module
|
||||||
|
|
||||||
|
cleaned_config = defaultdict(lambda: [])
|
||||||
|
|
||||||
|
modules = []
|
||||||
|
Module = namedtuple('Module', 'path name')
|
||||||
|
|
||||||
|
num_sources = len(extract_list(config, 'source'))
|
||||||
|
|
||||||
|
print_progress_bar(text='- assembling modules:',
|
||||||
|
done=0,
|
||||||
|
total=num_sources,
|
||||||
|
width=30)
|
||||||
|
|
||||||
|
if 'modules' in config:
|
||||||
|
i = 0
|
||||||
|
for t in config['modules']:
|
||||||
|
for k, v in t.items():
|
||||||
|
|
||||||
|
d = to_d(v)
|
||||||
|
for _k, _v in to_d(v).items():
|
||||||
|
cleaned_config[_k] = flat_add(cleaned_config[_k], _v)
|
||||||
|
|
||||||
|
# fetch sources and parse them
|
||||||
|
if 'source' in d:
|
||||||
|
for src in to_l(d['source']):
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# we download the file
|
||||||
|
module_name = os.path.basename(src)
|
||||||
|
if 'http' in src:
|
||||||
|
path = download_directory
|
||||||
|
name = 'autocmake_{0}'.format(module_name)
|
||||||
|
dst = os.path.join(download_directory, 'autocmake_{0}'.format(module_name))
|
||||||
|
fetch_url(src, dst)
|
||||||
|
file_name = dst
|
||||||
|
fetch_dst_directory = download_directory
|
||||||
|
else:
|
||||||
|
if os.path.exists(src):
|
||||||
|
path = os.path.dirname(src)
|
||||||
|
name = module_name
|
||||||
|
file_name = src
|
||||||
|
fetch_dst_directory = path
|
||||||
|
else:
|
||||||
|
sys.stderr.write("ERROR: {0} does not exist\n".format(src))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# we infer config from the module documentation
|
||||||
|
# dictionary d overrides the configuration in the module documentation
|
||||||
|
# this allows to override interpolation inside the module
|
||||||
|
with open(file_name, 'r') as f:
|
||||||
|
parsed_config = parse_cmake_module(f.read(), d)
|
||||||
|
for _k2, _v2 in parsed_config.items():
|
||||||
|
if _k2 not in to_d(v):
|
||||||
|
# we add to clean_config only if the entry does not exist
|
||||||
|
# in parent autocmake.yml already
|
||||||
|
# this allows to override
|
||||||
|
cleaned_config[_k2] = flat_add(cleaned_config[_k2], _v2)
|
||||||
|
|
||||||
|
modules.append(Module(path=path, name=name))
|
||||||
|
print_progress_bar(text='- assembling modules:',
|
||||||
|
done=i,
|
||||||
|
total=num_sources,
|
||||||
|
width=30)
|
||||||
|
print('')
|
||||||
|
|
||||||
|
return modules, cleaned_config
|
||||||
|
|
||||||
|
|
||||||
|
def process_yaml(argv):
|
||||||
|
from autocmake.parse_yaml import parse_yaml
|
||||||
|
from autocmake.generate import gen_cmakelists, gen_setup
|
||||||
|
from autocmake.extract import extract_list
|
||||||
|
|
||||||
|
project_root = argv[1]
|
||||||
|
if not os.path.isdir(project_root):
|
||||||
|
sys.stderr.write("ERROR: {0} is not a directory\n".format(project_root))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# read config file
|
||||||
|
print('- parsing autocmake.yml')
|
||||||
|
with open('autocmake.yml', 'r') as stream:
|
||||||
|
config = parse_yaml(stream)
|
||||||
|
|
||||||
|
if 'name' in config:
|
||||||
|
project_name = config['name']
|
||||||
|
else:
|
||||||
|
sys.stderr.write("ERROR: you have to specify the project name in autocmake.yml\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
if ' ' in project_name.rstrip():
|
||||||
|
sys.stderr.write("ERROR: project name contains a space\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if 'min_cmake_version' in config:
|
||||||
|
min_cmake_version = config['min_cmake_version']
|
||||||
|
else:
|
||||||
|
sys.stderr.write("ERROR: you have to specify min_cmake_version in autocmake.yml\n")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if 'setup_script' in config:
|
||||||
|
setup_script_name = config['setup_script']
|
||||||
|
else:
|
||||||
|
setup_script_name = 'setup'
|
||||||
|
|
||||||
|
# get relative path from setup script to this directory
|
||||||
|
relative_path = os.path.relpath(os.path.abspath('.'), project_root)
|
||||||
|
|
||||||
|
download_directory = 'downloaded'
|
||||||
|
if not os.path.exists(download_directory):
|
||||||
|
os.makedirs(download_directory)
|
||||||
|
|
||||||
|
# fetch modules from the web or from relative paths
|
||||||
|
modules, cleaned_config = fetch_modules(config, relative_path, download_directory)
|
||||||
|
|
||||||
|
# fetch files which are not parsed
|
||||||
|
for src in cleaned_config['fetch']:
|
||||||
|
dst = os.path.join(download_directory, os.path.basename(src))
|
||||||
|
fetch_url(src, dst)
|
||||||
|
|
||||||
|
# print warnings
|
||||||
|
for warning in cleaned_config['warning']:
|
||||||
|
print('- WARNING: {0}'.format(warning))
|
||||||
|
|
||||||
|
# create CMakeLists.txt
|
||||||
|
print('- generating CMakeLists.txt')
|
||||||
|
s = gen_cmakelists(project_name, min_cmake_version, relative_path, modules)
|
||||||
|
with open(os.path.join(project_root, 'CMakeLists.txt'), 'w') as f:
|
||||||
|
f.write('{0}\n'.format('\n'.join(s)))
|
||||||
|
|
||||||
|
# create setup script
|
||||||
|
print('- generating setup script')
|
||||||
|
s = gen_setup(cleaned_config, relative_path, setup_script_name)
|
||||||
|
file_path = os.path.join(project_root, setup_script_name)
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
f.write('{0}\n'.format('\n'.join(s)))
|
||||||
|
if sys.platform != 'win32':
|
||||||
|
make_executable(file_path)
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
"""
|
||||||
|
Main function.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if len(argv) != 2:
|
||||||
|
sys.stderr.write("\nYou can update a project in two steps.\n\n")
|
||||||
|
sys.stderr.write("Step 1: Update or create infrastructure files\n")
|
||||||
|
sys.stderr.write(" which will be needed to configure and build the project:\n")
|
||||||
|
sys.stderr.write(" $ {0} --self\n\n".format(argv[0]))
|
||||||
|
sys.stderr.write("Step 2: Create CMakeLists.txt and setup script in PROJECT_ROOT:\n")
|
||||||
|
sys.stderr.write(" $ {0} <PROJECT_ROOT>\n".format(argv[0]))
|
||||||
|
sys.stderr.write(" example:\n")
|
||||||
|
sys.stderr.write(" $ {0} ..\n".format(argv[0]))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if argv[1] in ['-h', '--help']:
|
||||||
|
print('Usage:')
|
||||||
|
for t, h in [('python update.py --self',
|
||||||
|
'Update this script and fetch or update infrastructure files under autocmake/.'),
|
||||||
|
('python update.py <builddir>',
|
||||||
|
'(Re)generate CMakeLists.txt and setup script and fetch or update CMake modules.'),
|
||||||
|
('python update.py (-h | --help)',
|
||||||
|
'Show this help text.')]:
|
||||||
|
print(' {0:30} {1}'.format(t, h))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if argv[1] == '--self':
|
||||||
|
# update self
|
||||||
|
if not os.path.isfile('autocmake.yml'):
|
||||||
|
print('- fetching example autocmake.yml')
|
||||||
|
fetch_url(
|
||||||
|
src='{0}example/autocmake.yml'.format(AUTOCMAKE_GITHUB_URL),
|
||||||
|
dst='autocmake.yml'
|
||||||
|
)
|
||||||
|
if not os.path.isfile('.gitignore'):
|
||||||
|
print('- creating .gitignore')
|
||||||
|
with open('.gitignore', 'w') as f:
|
||||||
|
f.write('*.pyc\n')
|
||||||
|
for f in ['autocmake/configure.py',
|
||||||
|
'autocmake/__init__.py',
|
||||||
|
'autocmake/external/docopt.py',
|
||||||
|
'autocmake/external/__init__.py',
|
||||||
|
'autocmake/generate.py',
|
||||||
|
'autocmake/extract.py',
|
||||||
|
'autocmake/interpolate.py',
|
||||||
|
'autocmake/parse_rst.py',
|
||||||
|
'autocmake/parse_yaml.py',
|
||||||
|
'update.py']:
|
||||||
|
print('- fetching {0}'.format(f))
|
||||||
|
fetch_url(
|
||||||
|
src='{0}{1}'.format(AUTOCMAKE_GITHUB_URL, f),
|
||||||
|
dst='{0}'.format(f)
|
||||||
|
)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
process_yaml(argv)
|
||||||
|
|
||||||
|
|
||||||
|
def make_executable(path):
|
||||||
|
# http://stackoverflow.com/a/30463972
|
||||||
|
mode = os.stat(path).st_mode
|
||||||
|
mode |= (mode & 0o444) >> 2 # copy R bits to X
|
||||||
|
os.chmod(path, mode)
|
||||||
|
|
||||||
|
|
||||||
def fetch_url(src, dst):
|
def fetch_url(src, dst):
|
||||||
"""
|
"""
|
||||||
Fetch file from URL src and save it to dst.
|
Fetch file from URL src and save it to dst.
|
||||||
"""
|
"""
|
||||||
|
# we do not use the nicer sys.version_info.major
|
||||||
|
# for compatibility with Python < 2.7
|
||||||
|
if sys.version_info[0] > 2:
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
class URLopener(urllib.request.FancyURLopener):
|
||||||
|
def http_error_default(self, url, fp, errcode, errmsg, headers):
|
||||||
|
sys.stderr.write("ERROR: could not fetch {0}\n".format(url))
|
||||||
|
sys.exit(-1)
|
||||||
|
else:
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
class URLopener(urllib.FancyURLopener):
|
||||||
|
def http_error_default(self, url, fp, errcode, errmsg, headers):
|
||||||
|
sys.stderr.write("ERROR: could not fetch {0}\n".format(url))
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
dirname = os.path.dirname(dst)
|
dirname = os.path.dirname(dst)
|
||||||
if dirname != '':
|
if dirname != '':
|
||||||
if not os.path.isdir(dirname):
|
if not os.path.isdir(dirname):
|
||||||
@ -45,505 +282,7 @@ def fetch_url(src, dst):
|
|||||||
opener = URLopener()
|
opener = URLopener()
|
||||||
opener.retrieve(src, dst)
|
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):
|
|
||||||
"""
|
|
||||||
Indents 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('%s' % arguments['--cmake-executable'])")
|
|
||||||
|
|
||||||
# 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(" command.append('-DCMAKE_BUILD_TYPE=%s' % arguments['--type'])")
|
|
||||||
s.append(" command.append('-G \"%s\"' % arguments['--generator'])")
|
|
||||||
s.append(" if arguments['--cmake-options'] != \"''\":")
|
|
||||||
s.append(" command.append('%s' % arguments['--cmake-options'])")
|
|
||||||
s.append(" if arguments['--prefix']:")
|
|
||||||
s.append(" command.append('-DCMAKE_INSTALL_PREFIX=\"{0}\"'.format(arguments['--prefix']))")
|
|
||||||
|
|
||||||
s.append("\n return ' '.join(command)")
|
|
||||||
|
|
||||||
return '\n'.join(s)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def autogenerated_notice():
|
|
||||||
start_year = 2015
|
|
||||||
year_range = str(start_year)
|
|
||||||
current_year = datetime.date.today().year
|
|
||||||
if current_year > start_year:
|
|
||||||
year_range += '-%s' % current_year
|
|
||||||
s = []
|
|
||||||
s.append('# This file is autogenerated by Autocmake http://autocmake.org')
|
|
||||||
s.append('# Copyright (c) %s by Radovan Bast and Jonas Juselius' % year_range)
|
|
||||||
return '\n'.join(s)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def gen_setup(config, relative_path, setup_script_name):
|
|
||||||
"""
|
|
||||||
Generate setup script.
|
|
||||||
"""
|
|
||||||
s = []
|
|
||||||
s.append('#!/usr/bin/env python')
|
|
||||||
s.append('\n%s' % autogenerated_notice())
|
|
||||||
s.append('\nimport os')
|
|
||||||
s.append('import sys')
|
|
||||||
|
|
||||||
s.append("\nsys.path.insert(0, '{0}')".format(relative_path))
|
|
||||||
s.append("sys.path.insert(0, '{0}')".format(os.path.join(relative_path, 'lib')))
|
|
||||||
s.append("sys.path.insert(0, '{0}')".format(os.path.join(relative_path, 'lib', 'docopt')))
|
|
||||||
|
|
||||||
s.append('import config')
|
|
||||||
s.append('import docopt')
|
|
||||||
|
|
||||||
s.append('\n\noptions = """')
|
|
||||||
s.append('Usage:')
|
|
||||||
s.append(' ./{0} [options] [<builddir>]'.format(setup_script_name))
|
|
||||||
s.append(' ./{0} (-h | --help)'.format(setup_script_name))
|
|
||||||
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(['--type=<TYPE>', 'Set the CMake build type (debug, release, or relwithdeb) [default: release].'])
|
|
||||||
options.append(['--generator=<STRING>', 'Set the CMake build system generator [default: Unix Makefiles].'])
|
|
||||||
options.append(['--show', 'Show CMake command and exit.'])
|
|
||||||
options.append(['--cmake-executable=<CMAKE_EXECUTABLE>', 'Set the CMake executable [default: cmake].'])
|
|
||||||
options.append(['--cmake-options=<STRING>', "Define options to CMake [default: '']."])
|
|
||||||
options.append(['--prefix=<PATH>', 'Set the install path for make install.'])
|
|
||||||
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")
|
|
||||||
s.append("# parse command line args")
|
|
||||||
s.append("try:")
|
|
||||||
s.append(" arguments = docopt.docopt(options, argv=None)")
|
|
||||||
s.append("except docopt.DocoptExit:")
|
|
||||||
s.append(r" sys.stderr.write('ERROR: bad input to %s\n' % sys.argv[0])")
|
|
||||||
s.append(" sys.stderr.write(options)")
|
|
||||||
s.append(" sys.exit(-1)")
|
|
||||||
s.append("\n")
|
|
||||||
s.append("# use extensions to validate/post-process args")
|
|
||||||
s.append("if config.module_exists('extensions'):")
|
|
||||||
s.append(" import extensions")
|
|
||||||
s.append(" arguments = extensions.postprocess_args(sys.argv, arguments)")
|
|
||||||
s.append("\n")
|
|
||||||
s.append("root_directory = os.path.dirname(os.path.realpath(__file__))")
|
|
||||||
s.append("\n")
|
|
||||||
s.append("build_path = arguments['<builddir>']")
|
|
||||||
s.append("\n")
|
|
||||||
s.append("# create cmake command")
|
|
||||||
s.append("cmake_command = '%s %s' % (gen_cmake_command(options, arguments), root_directory)")
|
|
||||||
s.append("\n")
|
|
||||||
s.append("# run cmake")
|
|
||||||
s.append("config.configure(root_directory, build_path, cmake_command, arguments['--show'])")
|
|
||||||
|
|
||||||
return s
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def gen_cmakelists(project_name, min_cmake_version, relative_path, modules):
|
|
||||||
"""
|
|
||||||
Generate CMakeLists.txt.
|
|
||||||
"""
|
|
||||||
s = []
|
|
||||||
|
|
||||||
s.append(autogenerated_notice())
|
|
||||||
|
|
||||||
s.append('\n# set minimum cmake version')
|
|
||||||
s.append('cmake_minimum_required(VERSION %s FATAL_ERROR)' % min_cmake_version)
|
|
||||||
|
|
||||||
s.append('\n# project name')
|
|
||||||
s.append('project(%s)' % project_name)
|
|
||||||
|
|
||||||
s.append('\n# do not rebuild if rules (compiler flags) change')
|
|
||||||
s.append('set(CMAKE_SKIP_RULE_DEPENDENCY TRUE)')
|
|
||||||
|
|
||||||
s.append('\n# if CMAKE_BUILD_TYPE undefined, we set it to Debug')
|
|
||||||
s.append('if(NOT CMAKE_BUILD_TYPE)')
|
|
||||||
s.append(' set(CMAKE_BUILD_TYPE "Debug")')
|
|
||||||
s.append('endif()')
|
|
||||||
|
|
||||||
if len(modules) > 0:
|
|
||||||
s.append('\n# directories which hold included cmake modules')
|
|
||||||
|
|
||||||
module_paths = [module.path for module in modules]
|
|
||||||
module_paths.append('downloaded') # this is done to be able to find fetched modules when testing
|
|
||||||
module_paths = list(set(module_paths))
|
|
||||||
module_paths.sort() # we do this to always get the same order and to minimize diffs
|
|
||||||
for directory in module_paths:
|
|
||||||
rel_cmake_module_path = os.path.join(relative_path, directory)
|
|
||||||
# on windows cmake corrects this so we have to make it wrong again
|
|
||||||
rel_cmake_module_path = rel_cmake_module_path.replace('\\', '/')
|
|
||||||
s.append('set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/%s)' % rel_cmake_module_path)
|
|
||||||
|
|
||||||
if len(modules) > 0:
|
|
||||||
s.append('\n# included cmake modules')
|
|
||||||
for module in modules:
|
|
||||||
s.append('include(%s)' % os.path.splitext(module.name)[0])
|
|
||||||
|
|
||||||
return s
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def prepend_or_set(config, section, option, value, defaults):
|
|
||||||
"""
|
|
||||||
If option is already set, then value is prepended.
|
|
||||||
If option is not set, then it is created and set to value.
|
|
||||||
This is used to prepend options with values which come from the module documentation.
|
|
||||||
"""
|
|
||||||
if value:
|
|
||||||
if config.has_option(section, option):
|
|
||||||
value += '\n%s' % config.get(section, option, 0, defaults)
|
|
||||||
config.set(section, option, value)
|
|
||||||
return config
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_modules(config, relative_path):
|
|
||||||
"""
|
|
||||||
Assemble modules which will
|
|
||||||
be included in CMakeLists.txt.
|
|
||||||
"""
|
|
||||||
|
|
||||||
download_directory = 'downloaded'
|
|
||||||
if not os.path.exists(download_directory):
|
|
||||||
os.makedirs(download_directory)
|
|
||||||
|
|
||||||
l = list(filter(lambda x: config.has_option(x, 'source'),
|
|
||||||
config.sections()))
|
|
||||||
n = len(l)
|
|
||||||
|
|
||||||
modules = []
|
|
||||||
Module = collections.namedtuple('Module', 'path name')
|
|
||||||
|
|
||||||
warnings = []
|
|
||||||
|
|
||||||
if n > 0: # otherwise division by zero in print_progress_bar
|
|
||||||
i = 0
|
|
||||||
print_progress_bar(text='- assembling modules:', done=0, total=n, width=30)
|
|
||||||
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)
|
|
||||||
if 'http' in src:
|
|
||||||
path = download_directory
|
|
||||||
name = 'autocmake_%s' % module_name
|
|
||||||
dst = os.path.join(download_directory, 'autocmake_%s' % module_name)
|
|
||||||
fetch_url(src, dst)
|
|
||||||
file_name = dst
|
|
||||||
fetch_dst_directory = download_directory
|
|
||||||
else:
|
|
||||||
if os.path.exists(src):
|
|
||||||
path = os.path.dirname(src)
|
|
||||||
name = module_name
|
|
||||||
file_name = src
|
|
||||||
fetch_dst_directory = path
|
|
||||||
else:
|
|
||||||
sys.stderr.write("ERROR: %s does not exist\n" % src)
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
if config.has_option(section, 'override'):
|
|
||||||
defaults = ast.literal_eval(config.get(section, 'override'))
|
|
||||||
else:
|
|
||||||
defaults = {}
|
|
||||||
|
|
||||||
# we infer config from the module documentation
|
|
||||||
with open(file_name, 'r') as f:
|
|
||||||
parsed_config = parse_cmake_module(f.read(), defaults)
|
|
||||||
if parsed_config['warning']:
|
|
||||||
warnings.append('WARNING from {0}: {1}'.format(module_name, parsed_config['warning']))
|
|
||||||
config = prepend_or_set(config, section, 'docopt', parsed_config['docopt'], defaults)
|
|
||||||
config = prepend_or_set(config, section, 'define', parsed_config['define'], defaults)
|
|
||||||
config = prepend_or_set(config, section, 'export', parsed_config['export'], defaults)
|
|
||||||
if parsed_config['fetch']:
|
|
||||||
for src in parsed_config['fetch'].split('\n'):
|
|
||||||
dst = os.path.join(fetch_dst_directory, os.path.basename(src))
|
|
||||||
fetch_url(src, dst)
|
|
||||||
|
|
||||||
modules.append(Module(path=path, name=name))
|
|
||||||
i += 1
|
|
||||||
print_progress_bar(
|
|
||||||
text='- assembling modules:',
|
|
||||||
done=i,
|
|
||||||
total=n,
|
|
||||||
width=30
|
|
||||||
)
|
|
||||||
if config.has_option(section, 'fetch'):
|
|
||||||
# when we fetch directly from autocmake.cfg
|
|
||||||
# we download into downloaded/
|
|
||||||
for src in config.get(section, 'fetch').split('\n'):
|
|
||||||
dst = os.path.join(download_directory, os.path.basename(src))
|
|
||||||
fetch_url(src, dst)
|
|
||||||
print('')
|
|
||||||
|
|
||||||
if warnings != []:
|
|
||||||
print('- %s' % '\n- '.join(warnings))
|
|
||||||
|
|
||||||
return modules
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
"""
|
|
||||||
Main function.
|
|
||||||
"""
|
|
||||||
if len(argv) != 2:
|
|
||||||
sys.stderr.write("\nYou can update a project in two steps.\n\n")
|
|
||||||
sys.stderr.write("Step 1: Update or create infrastructure files\n")
|
|
||||||
sys.stderr.write(" which will be needed to configure and build the project:\n")
|
|
||||||
sys.stderr.write(" $ %s --self\n\n" % argv[0])
|
|
||||||
sys.stderr.write("Step 2: Create CMakeLists.txt and setup script 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] in ['-h', '--help']:
|
|
||||||
print('Usage:')
|
|
||||||
print(' python update.py --self Update this script and fetch or update infrastructure files under lib/.')
|
|
||||||
print(' python update.py <builddir> (Re)generate CMakeLists.txt and setup script and fetch or update CMake modules.')
|
|
||||||
print(' python update.py (-h | --help) Show this help text.')
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if argv[1] == '--self':
|
|
||||||
# update self
|
|
||||||
if not os.path.isfile('autocmake.cfg'):
|
|
||||||
print('- fetching example autocmake.cfg')
|
|
||||||
fetch_url(
|
|
||||||
src='%s/raw/master/example/autocmake.cfg' % AUTOCMAKE_GITHUB_URL,
|
|
||||||
dst='autocmake.cfg'
|
|
||||||
)
|
|
||||||
if not os.path.isfile('.gitignore'):
|
|
||||||
print('- creating .gitignore')
|
|
||||||
with open('.gitignore', 'w') as f:
|
|
||||||
f.write('*.pyc\n')
|
|
||||||
print('- fetching lib/config.py')
|
|
||||||
fetch_url(
|
|
||||||
src='%s/raw/master/lib/config.py' % AUTOCMAKE_GITHUB_URL,
|
|
||||||
dst='lib/config.py'
|
|
||||||
)
|
|
||||||
print('- fetching lib/docopt/docopt.py')
|
|
||||||
fetch_url(
|
|
||||||
src='%s/raw/master/lib/docopt/docopt.py' % AUTOCMAKE_GITHUB_URL,
|
|
||||||
dst='lib/docopt/docopt.py'
|
|
||||||
)
|
|
||||||
print('- fetching update.py')
|
|
||||||
fetch_url(
|
|
||||||
src='%s/raw/master/update.py' % AUTOCMAKE_GITHUB_URL,
|
|
||||||
dst='update.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 autocmake.cfg')
|
|
||||||
config = ConfigParser(dict_type=collections.OrderedDict)
|
|
||||||
config.read('autocmake.cfg')
|
|
||||||
|
|
||||||
if not config.has_option('project', 'name'):
|
|
||||||
sys.stderr.write("ERROR: you have to specify the project name\n")
|
|
||||||
sys.stderr.write(" in autocmake.cfg under [project]\n")
|
|
||||||
sys.exit(-1)
|
|
||||||
project_name = config.get('project', 'name')
|
|
||||||
if ' ' in project_name.rstrip():
|
|
||||||
sys.stderr.write("ERROR: project name contains a space\n")
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
if not config.has_option('project', 'min_cmake_version'):
|
|
||||||
sys.stderr.write("ERROR: you have to specify the min_cmake_version for CMake\n")
|
|
||||||
sys.stderr.write(" in autocmake.cfg under [project]\n")
|
|
||||||
sys.exit(-1)
|
|
||||||
min_cmake_version = config.get('project', 'min_cmake_version')
|
|
||||||
|
|
||||||
if config.has_option('project', 'setup_script'):
|
|
||||||
setup_script_name = config.get('project', 'setup_script')
|
|
||||||
else:
|
|
||||||
setup_script_name = 'setup'
|
|
||||||
|
|
||||||
# get relative path from setup script to this directory
|
|
||||||
relative_path = os.path.relpath(os.path.abspath('.'), project_root)
|
|
||||||
|
|
||||||
# fetch modules from the web or from relative paths
|
|
||||||
modules = fetch_modules(config, relative_path)
|
|
||||||
|
|
||||||
# create CMakeLists.txt
|
|
||||||
print('- generating CMakeLists.txt')
|
|
||||||
s = gen_cmakelists(project_name, min_cmake_version, relative_path, modules)
|
|
||||||
with open(os.path.join(project_root, 'CMakeLists.txt'), 'w') as f:
|
|
||||||
f.write('%s\n' % '\n'.join(s))
|
|
||||||
|
|
||||||
# create setup script
|
|
||||||
print('- generating setup script')
|
|
||||||
s = gen_setup(config, relative_path, setup_script_name)
|
|
||||||
file_path = os.path.join(project_root, setup_script_name)
|
|
||||||
with open(file_path, 'w') as f:
|
|
||||||
f.write('%s\n' % '\n'.join(s))
|
|
||||||
if sys.platform != 'win32':
|
|
||||||
make_executable(file_path)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
# http://stackoverflow.com/a/30463972
|
|
||||||
def make_executable(path):
|
|
||||||
mode = os.stat(path).st_mode
|
|
||||||
mode |= (mode & 0o444) >> 2 # copy R bits to X
|
|
||||||
os.chmod(path, mode)
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def parse_cmake_module(s_in, defaults={}):
|
|
||||||
|
|
||||||
parsed_config = collections.defaultdict(lambda: None)
|
|
||||||
|
|
||||||
if 'autocmake.cfg configuration::' not in s_in:
|
|
||||||
return parsed_config
|
|
||||||
|
|
||||||
s_out = []
|
|
||||||
is_rst_line = False
|
|
||||||
for line in s_in.split('\n'):
|
|
||||||
if is_rst_line:
|
|
||||||
if len(line) > 0:
|
|
||||||
if line[0] != '#':
|
|
||||||
is_rst_line = False
|
|
||||||
else:
|
|
||||||
is_rst_line = False
|
|
||||||
if is_rst_line:
|
|
||||||
s_out.append(line[2:])
|
|
||||||
if '#.rst:' in line:
|
|
||||||
is_rst_line = True
|
|
||||||
|
|
||||||
autocmake_entry = '\n'.join(s_out).split('autocmake.cfg configuration::')[1]
|
|
||||||
autocmake_entry = autocmake_entry.replace('\n ', '\n')
|
|
||||||
|
|
||||||
# we prepend a fake section heading so that we can parse it with configparser
|
|
||||||
autocmake_entry = '[foo]\n' + autocmake_entry
|
|
||||||
|
|
||||||
buf = StringIO(autocmake_entry)
|
|
||||||
config = ConfigParser(dict_type=collections.OrderedDict)
|
|
||||||
config.readfp(buf)
|
|
||||||
|
|
||||||
for section in config.sections():
|
|
||||||
for s in ['docopt', 'define', 'export', 'fetch', 'warning']:
|
|
||||||
if config.has_option(section, s):
|
|
||||||
parsed_config[s] = config.get(section, s, 0, defaults)
|
|
||||||
|
|
||||||
return parsed_config
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
def test_parse_cmake_module():
|
|
||||||
|
|
||||||
s = '''#.rst:
|
|
||||||
#
|
|
||||||
# Foo ...
|
|
||||||
#
|
|
||||||
# autocmake.cfg configuration::
|
|
||||||
#
|
|
||||||
# docopt: --cxx=<CXX> C++ compiler [default: g++].
|
|
||||||
# --extra-cxx-flags=<EXTRA_CXXFLAGS> Extra C++ compiler flags [default: ''].
|
|
||||||
# export: 'CXX=%s' % arguments['--cxx']
|
|
||||||
# define: '-DEXTRA_CXXFLAGS="%s"' % arguments['--extra-cxx-flags']
|
|
||||||
|
|
||||||
enable_language(CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
|
||||||
message(FATAL_ERROR "CMAKE_C_COMPILER_ID variable is not defined!")
|
|
||||||
endif()'''
|
|
||||||
|
|
||||||
parsed_config = parse_cmake_module(s)
|
|
||||||
assert parsed_config['docopt'] == "--cxx=<CXX> C++ compiler [default: g++].\n--extra-cxx-flags=<EXTRA_CXXFLAGS> Extra C++ compiler flags [default: '']."
|
|
||||||
|
|
||||||
s = '''#.rst:
|
|
||||||
#
|
|
||||||
# Foo ...
|
|
||||||
#
|
|
||||||
# Bar ...
|
|
||||||
|
|
||||||
enable_language(CXX)
|
|
||||||
|
|
||||||
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
|
||||||
message(FATAL_ERROR "CMAKE_C_COMPILER_ID variable is not defined!")
|
|
||||||
endif()'''
|
|
||||||
|
|
||||||
parsed_config = parse_cmake_module(s)
|
|
||||||
assert parsed_config['docopt'] is None
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
check_for_yaml()
|
||||||
main(sys.argv)
|
main(sys.argv)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user