avoid code duplication with local cmake modules; fixes #32

the directory for downloaded modules is renamed from modules/ to downloaded/
This commit is contained in:
Radovan Bast 2015-07-17 10:37:01 +02:00
parent 6e97708f50
commit bafae8ab61
5 changed files with 44 additions and 39 deletions

4
.gitignore vendored
View File

@ -4,9 +4,9 @@ __pycache__/
# generated by unit tests # generated by unit tests
test/*/CMakeLists.txt test/*/CMakeLists.txt
test/*/build*/ test/*/build*/
test/*/cmake/update.py* test/*/cmake/update.py
test/*/cmake/lib/ test/*/cmake/lib/
test/*/cmake/modules/ test/*/cmake/downloaded/
test/*/setup.py test/*/setup.py
# generated by doc/extract_rst.py # generated by doc/extract_rst.py

View File

@ -3,15 +3,16 @@
Customizing CMake modules Customizing CMake modules
========================= =========================
The ``update.py`` script assembles modules listed in ``autocmake.cfg`` and The ``update.py`` script assembles modules listed in ``autocmake.cfg`` into
places them inside ``modules/``. You have at least four options to customize ``CMakeLists.txt``. Those that are fetched from the web are placed inside
CMake modules: ``downloaded/``. You have at least four options to customize downloaded CMake
modules:
Directly inside the generated modules directory Directly inside the generated directory
----------------------------------------------- ---------------------------------------
The CMake modules can be customized directly inside ``modules/`` but this is The CMake modules can be customized directly inside ``downloaded/`` but this is
the least elegant solution since the customizations may be overwritten by the the least elegant solution since the customizations may be overwritten by the
``update.py`` script (use version control). ``update.py`` script (use version control).

View File

@ -37,8 +37,8 @@ creates ``CMakeLists.txt`` and ``setup.py`` in the build path::
python update.py .. python update.py ..
The script also copies or downloads CMake modules specified in ``autocmake.cfg`` to a directory The script also downloads remote CMake modules specified in ``autocmake.cfg`` to a directory
called ``modules/``:: called ``downloaded/``::
cmake/ cmake/
update.py update.py
@ -46,7 +46,7 @@ called ``modules/``::
lib/ lib/
config.py config.py
docopt.py docopt.py
modules/ # CMakeLists.txt includes CMake modules from this directory downloaded/ # contains CMake modules fetched from the web
Building the project Building the project

View File

@ -3,7 +3,7 @@
Updating CMake modules Updating CMake modules
====================== ======================
To update CMake modules you need to run the ``update.py`` script:: To update CMake modules fetched from the web you need to run the ``update.py`` script::
cd cmake cd cmake
python update.py .. python update.py ..

View File

@ -2,8 +2,7 @@
import os import os
import sys import sys
import shutil from collections import OrderedDict, namedtuple
from collections import OrderedDict
# we do not use the nicer sys.version_info.major # we do not use the nicer sys.version_info.major
# for compatibility with Python < 2.7 # for compatibility with Python < 2.7
@ -155,7 +154,7 @@ def gen_setup(config, relative_path):
return s return s
def gen_cmakelists(config, relative_path, list_of_modules): def gen_cmakelists(config, relative_path, modules):
""" """
Generate CMakeLists.txt. Generate CMakeLists.txt.
""" """
@ -181,62 +180,67 @@ def gen_cmakelists(config, relative_path, list_of_modules):
s.append(' set(CMAKE_BUILD_TYPE "Debug")') s.append(' set(CMAKE_BUILD_TYPE "Debug")')
s.append('endif()') s.append('endif()')
s.append('\n# directory which holds enabled cmake modules') s.append('\n# directories which hold enabled cmake modules')
s.append('set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}') for directory in set([module.path for module in modules]):
rel_cmake_module_path = os.path.join(relative_path, directory)
# we need the same separator since CMake apparently corrects for it # on windows cmake corrects this so we have to make it wrong again
# therefore we do not use os.path.join rel_cmake_module_path.replace('\\', '/')
s.append(' ${PROJECT_SOURCE_DIR}/%s/modules)' % relative_path) s.append('set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/%s)' % rel_cmake_module_path)
s.append('\n# included cmake modules') s.append('\n# included cmake modules')
for m in list_of_modules: for module in modules:
s.append('include(autocmake_%s)' % os.path.splitext(m)[0]) s.append('include(%s)' % os.path.splitext(module.name)[0])
return s return s
def fetch_modules(config, module_directory): def fetch_modules(config, relative_path):
""" """
Fetch modules either from remote URLs or from relative paths Assemble modules which will
and save them to module_directory from which they will
be included in CMakeLists.txt. be included in CMakeLists.txt.
""" """
if not os.path.exists(module_directory):
os.makedirs(module_directory) download_directory = 'downloaded'
if not os.path.exists(download_directory):
os.makedirs(download_directory)
l = list(filter(lambda x: config.has_option(x, 'source'), l = list(filter(lambda x: config.has_option(x, 'source'),
config.sections())) config.sections()))
n = len(l) n = len(l)
list_of_modules = [] modules = []
Module = namedtuple('Module', 'path name')
if n > 0: # otherwise division by zero in print_progress_bar if n > 0: # otherwise division by zero in print_progress_bar
i = 0 i = 0
print_progress_bar(text='- fetching modules:', done=0, total=n, width=30) print_progress_bar(text='- assembling modules:', done=0, total=n, width=30)
for section in config.sections(): for section in config.sections():
if config.has_option(section, 'source'): if config.has_option(section, 'source'):
for src in config.get(section, 'source').split('\n'): for src in config.get(section, 'source').split('\n'):
module_name = os.path.basename(src) module_name = os.path.basename(src)
list_of_modules.append(module_name)
dst = os.path.join(module_directory, 'autocmake_%s' % module_name)
if 'http' in 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) fetch_url(src, dst)
else: else:
if os.path.exists(src): if os.path.exists(src):
shutil.copyfile(src, dst) path = os.path.dirname(src)
name = module_name
else: else:
sys.stderr.write("ERROR: %s does not exist\n" % src) sys.stderr.write("ERROR: %s does not exist\n" % src)
sys.exit(-1) sys.exit(-1)
modules.append(Module(path=path, name=name))
i += 1 i += 1
print_progress_bar( print_progress_bar(
text='- fetching modules:', text='- assembling modules:',
done=i, done=i,
total=n, total=n,
width=30 width=30
) )
print('') print('')
return list_of_modules return modules
def main(argv): def main(argv):
@ -289,15 +293,15 @@ def main(argv):
config = RawConfigParser(dict_type=OrderedDict) config = RawConfigParser(dict_type=OrderedDict)
config.read('autocmake.cfg') config.read('autocmake.cfg')
# fetch modules from the web or from relative paths
list_of_modules = fetch_modules(config, module_directory='modules')
# get relative path from setup.py script to this directory # get relative path from setup.py script to this directory
relative_path = os.path.relpath(os.path.abspath('.'), project_root) 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 # create CMakeLists.txt
print('- generating CMakeLists.txt') print('- generating CMakeLists.txt')
s = gen_cmakelists(config, relative_path, list_of_modules) s = gen_cmakelists(config, relative_path, modules)
with open(os.path.join(project_root, 'CMakeLists.txt'), 'w') as f: with open(os.path.join(project_root, 'CMakeLists.txt'), 'w') as f:
f.write('%s\n' % '\n'.join(s)) f.write('%s\n' % '\n'.join(s))