-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add pybuilder script in preparation to publish on PyPi. Fully backward compatible. Installation instructions changed!
- Loading branch information
Showing
18 changed files
with
1,436 additions
and
1,138 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
�}q(U collectorqUcoverage v3.7.1qUlinesq}u. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
language: python | ||
|
||
python: | ||
- "2.7.8" | ||
#- "3.4.1" | ||
|
||
install: | ||
- pip install pybuilder | ||
- pyb install_dependencies --verbose | ||
- pip install python-coveralls | ||
|
||
script: | ||
- pyb --verbose | ||
|
||
after_success: | ||
- coveralls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include *.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#!/usr/bin/env python | ||
"""Build script for MaTiSSe.py""" | ||
import os | ||
from pybuilder.core import Author,init,task,use_plugin | ||
from shutil import copyfile | ||
import re | ||
|
||
#use_plugin('copy_resources') | ||
use_plugin('python.core') | ||
use_plugin('python.coverage') | ||
use_plugin('python.install_dependencies') | ||
#use_plugin('python.pylint') | ||
use_plugin('python.unittest') | ||
|
||
__source__ = open('src/main/python/fobis/config.py').read() | ||
|
||
authors = [Author(re.search(r'^__author__\s*=\s*"(.*)"', __source__, re.M).group(1), | ||
re.search(r'^__author_email__\s*=\s*"(.*)"', __source__, re.M).group(1))] | ||
version = re.search(r'^__version__\s*=\s*"(.*)"', __source__, re.M).group(1) | ||
license = re.search(r'^__license__\s*=\s*"(.*)"', __source__, re.M).group(1) | ||
description = re.search(r'^__description__\s*=\s*"(.*)"', __source__, re.M).group(1) | ||
url = re.search(r'^__url__\s*=\s*"(.*)"', __source__, re.M).group(1) | ||
|
||
@init | ||
def initialize(project): | ||
"""Initializing the building class.""" | ||
project.version = version | ||
project.build_depends_on('coverage') | ||
project.build_depends_on('pylint') | ||
project.depends_on('markdown') | ||
project.depends_on('yattag') | ||
|
||
project.set_property('verbose', True) | ||
|
||
project.set_property('coverage_break_build',False) | ||
project.set_property('coverage_threshold_warn',90) | ||
|
||
project.set_property('dir_target','release') | ||
project.set_property('dir_dist','release/'+project.name+'-'+project.version) | ||
project.set_property('dir_reports','release/reports-'+project.name+'-'+project.version) | ||
#project.set_property('copy_resources_target','$dir_dist') | ||
#project.get_property('copy_resources_glob').append('MANIFEST.in') | ||
|
||
project.default_task = ['analyze','publish','copy_resources'] | ||
return | ||
|
||
@task | ||
def copy_resources(project): | ||
"""Copy non source resource files.""" | ||
copyfile('MANIFEST.in','release/'+project.name+'-'+project.version+'/MANIFEST.in') | ||
for mdf in os.listdir('.'): | ||
if mdf.endswith('.md'): | ||
copyfile(mdf,'release/'+project.name+'-'+project.version+'/'+mdf) | ||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env python | ||
"""Wrapper of FoBiS.py program extracted from fobis package""" | ||
from fobis.fobis import main | ||
if __name__ == '__main__' : | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,315 @@ | ||
#!/usr/bin/env python | ||
""" | ||
Builder.py, module definition of Builder class. | ||
This is a class designed for controlling the building phase. | ||
""" | ||
try: | ||
from multiprocessing import Pool | ||
__parallel__=True | ||
except ImportError: | ||
print("Module 'multiprocessing' not found: parallel compilation disabled") | ||
__parallel__=False | ||
import operator | ||
import os | ||
import sys | ||
from .Colors import Colors | ||
from .utils import syswork | ||
class Builder(object): | ||
"""Builder is an object that handles the building system, its attributes and methods.""" | ||
def __init__(self, | ||
compiler = "Intel", | ||
fc = "", | ||
modsw = "", | ||
mpi = False, | ||
cflags = "", | ||
lflags = "", | ||
libs = None, | ||
dinc = None, | ||
preproc = "", | ||
build_dir = "./", | ||
mod_dir = "./", | ||
obj_dir = "./", | ||
quiet = False, | ||
colors = False, | ||
jobs = 1, | ||
preform = False, | ||
pfm_dir = None, | ||
pfm_ext = []): | ||
""" | ||
Parameters | ||
---------- | ||
compiler : {"Intel"} | ||
compiler used | ||
fc : {""} | ||
custom compiler statement | ||
modsw : {""} | ||
custom compiler switch for modules searching path | ||
mpi : {False} | ||
use MPI enabled version of compiler | ||
cflags : {""} | ||
compilation flags | ||
lflags : {""} | ||
linking flags | ||
libs : {None} | ||
list of external libraries | ||
dinc : {None} | ||
list of directories for searching included files | ||
preproc : {""} | ||
preprocessor flags | ||
build_dir : {"./"} | ||
directory containing built files | ||
mod_dir : {"./"} | ||
directory containing .mod files | ||
obj_dir : {"./"} | ||
directory containing compiled object files | ||
quiet : {False} | ||
make printings less verbose than default | ||
colors : {False} | ||
make printings colored | ||
jobs : {1} | ||
concurrent compiling jobs | ||
preform : {False} | ||
activate PreForM.py pre-processing | ||
pfm_dir : {None} | ||
directory containing sources processed by PreForm.py; by default are removed after used | ||
pfm_ext : {[]} | ||
list of file extensions to be processed by PreForm.py; by default all files are preprocessed if PreForM.py is used | ||
Attributes | ||
---------- | ||
""" | ||
self.compiler = compiler | ||
self.fcs = fc | ||
self.modsw = modsw | ||
self.mpi = mpi | ||
self.cflags = cflags | ||
self.lflags = lflags | ||
if libs is None: | ||
self.libs = [] | ||
else: | ||
self.libs = libs | ||
if dinc is None: | ||
self.dinc = [] | ||
else: | ||
self.dinc = dinc | ||
self.preproc = preproc | ||
self.build_dir = build_dir | ||
self.mod_dir = build_dir+mod_dir | ||
self.obj_dir = build_dir+obj_dir | ||
self.quiet = quiet | ||
self.colors = Colors() | ||
self.jobs = jobs | ||
self.preform = preform | ||
self.pfm_ext = pfm_ext | ||
self.pfm_dir = pfm_dir | ||
if self.pfm_dir: | ||
self.pfm_dir = build_dir+self.pfm_dir | ||
if not colors: | ||
self.colors.disable() | ||
if self.preform: | ||
pfm_exist = False | ||
for path in os.environ["PATH"].split(os.pathsep): | ||
pfm_exist = os.path.exists(os.path.join(path, 'PreForM.py')) | ||
if pfm_exist: | ||
if self.pfm_dir: | ||
if not os.path.exists(self.pfm_dir): | ||
os.makedirs(self.pfm_dir) | ||
break | ||
if not pfm_exist: | ||
print(self.colors.red+'Error: PreForM.py is not in your PATH! You cannot use --preform or -pfm switches.'+self.colors.end) | ||
sys.exit(1) | ||
if mpi: | ||
self.fcs = 'mpif90' | ||
if compiler.lower() == 'gnu': | ||
if not mpi: | ||
self.fcs = 'gfortran' | ||
self.modsw = '-J' | ||
elif compiler.lower() == 'intel': | ||
if not mpi: | ||
self.fcs = 'ifort' | ||
self.modsw = '-module' | ||
elif compiler.lower() == 'g95': | ||
if not mpi: | ||
self.fcs = 'g95' | ||
self.modsw = '-fmod=' | ||
elif compiler.lower() == 'custom': | ||
pass # all is set from CLI | ||
if self.modsw[-1]!='=': # check necessary for g95 CLI trapping error | ||
self.modsw += ' ' | ||
self.cmd_comp = self.fcs+' '+self.cflags+' '+self.modsw+self.mod_dir+' '+self.preproc | ||
self.cmd_link = self.fcs+' '+self.lflags+' '+self.modsw+self.mod_dir | ||
# checking paths integrity | ||
if not os.path.exists(self.mod_dir): | ||
os.makedirs(self.mod_dir) | ||
if not os.path.exists(self.obj_dir): | ||
os.makedirs(self.obj_dir) | ||
if not os.path.exists(self.build_dir): | ||
os.makedirs(self.build_dir) | ||
|
||
def compile_command(self,file_to_compile): | ||
""" | ||
The method compile_command returns the OS command for compiling file_to_compile. | ||
Parameters | ||
---------- | ||
file_to_compile : ParsedFile object | ||
file to be compiled | ||
Returns | ||
------- | ||
str | ||
string containing the compile command | ||
""" | ||
if self.preform: | ||
if len(self.pfm_ext)>0: | ||
if file_to_compile.extension in self.pfm_ext: | ||
if self.pfm_dir: | ||
if len(self.dinc)>0: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+self.pfm_dir+file_to_compile.basename+'.pfm.f90'+' ; '+self.cmd_comp+' '+''.join(['-I'+s+' ' for s in self.dinc])+self.pfm_dir+file_to_compile.basename+'.pfm.f90'+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+self.pfm_dir+file_to_compile.basename+'.pfm.f90'+' ; '+self.cmd_comp+' '+ self.pfm_dir+file_to_compile.basename+'.pfm.f90'+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
if len(self.dinc)>0: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+file_to_compile.basename+'.pfm.f90'+' ; '+self.cmd_comp+' '+''.join(['-I'+s+' ' for s in self.dinc])+file_to_compile.basename+'.pfm.f90'+' -o '+self.obj_dir+file_to_compile.basename+'.o'+' ; rm -f '+file_to_compile.basename+'.pfm.f90' | ||
else: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+file_to_compile.basename+'.pfm.f90'+' ; '+self.cmd_comp+' '+ file_to_compile.basename+'.pfm.f90'+' -o '+self.obj_dir+file_to_compile.basename+'.o'+' ; rm -f '+file_to_compile.basename+'.pfm.f90' | ||
else: | ||
if len(self.dinc)>0: | ||
comp_cmd = self.cmd_comp+' '+''.join(['-I'+s+' ' for s in self.dinc])+file_to_compile.name+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
comp_cmd = self.cmd_comp+' ' +file_to_compile.name+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
if self.pfm_dir: | ||
if len(self.dinc)>0: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+self.pfm_dir+file_to_compile.basename+'.pfm'+file_to_compile.extension+' ; '+self.cmd_comp+' '+''.join(['-I'+s+' ' for s in self.dinc])+self.pfm_dir+file_to_compile.basename+'.pfm'+file_to_compile.extension+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+self.pfm_dir+file_to_compile.basename+'.pfm'+file_to_compile.extension+' ; '+self.cmd_comp+' '+ self.pfm_dir+file_to_compile.basename+'.pfm'+file_to_compile.extension+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
if len(self.dinc)>0: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+file_to_compile.basename+'.pfm'+file_to_compile.extension+' ; '+self.cmd_comp+' '+''.join(['-I'+s+' ' for s in self.dinc])+file_to_compile.basename+'.pfm'+file_to_compile.extension+' -o '+self.obj_dir+file_to_compile.basename+'.o'+' ; rm -f '+file_to_compile.basename+'.pfm'+file_to_compile.extension | ||
else: | ||
comp_cmd = 'PreForM.py '+file_to_compile.name+' -o '+file_to_compile.basename+'.pfm'+file_to_compile.extension+' ; '+self.cmd_comp+' '+ file_to_compile.basename+'.pfm'+file_to_compile.extension+' -o '+self.obj_dir+file_to_compile.basename+'.o'+' ; rm -f '+file_to_compile.basename+'.pfm'+file_to_compile.extension | ||
else: | ||
if len(self.dinc)>0: | ||
comp_cmd = self.cmd_comp+' '+''.join(['-I'+s+' ' for s in self.dinc])+file_to_compile.name+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
else: | ||
comp_cmd = self.cmd_comp+' ' +file_to_compile.name+' -o '+self.obj_dir+file_to_compile.basename+'.o' | ||
return comp_cmd | ||
|
||
def build(self,file_to_build,output=None,nomodlibs=None,mklib=None): | ||
""" | ||
Method for building file. | ||
Parameters | ||
---------- | ||
file_to_build : ParsedFile | ||
output : | ||
nomodlibs : {None} | ||
list of old-Fortran style libraries objects | ||
mklib : {None} | ||
""" | ||
print(self.colors.bld+'Building '+file_to_build.name+self.colors.end) | ||
# correct the list ordering accordingly to indirect dependency | ||
for dep in file_to_build.pfile_dep_all: | ||
for other_dep in file_to_build.pfile_dep_all: | ||
if other_dep != dep: | ||
if dep in other_dep.pfile_dep_all: | ||
dep.order+=1 | ||
file_to_build.pfile_dep_all.sort(key=operator.attrgetter('order'),reverse=True) | ||
# creating a hierarchy list of compiling commands accordingly to the order of all dependencies | ||
if len([p for p in file_to_build.pfile_dep_all if not p.include and p.to_compile])>0: | ||
order_max = max([p for p in file_to_build.pfile_dep_all if not p.include and p.to_compile],key=operator.attrgetter('order')).order + 1 | ||
hierarchy = [[] for i in range(order_max)] | ||
for dep in file_to_build.pfile_dep_all: | ||
if dep.to_compile and not dep.include: | ||
hierarchy[dep.order].append([dep.name,self.compile_command(file_to_compile=dep)]) | ||
dep.to_compile = False | ||
hierarchy = [h for h in hierarchy if len(h)>0] | ||
for deps in reversed(hierarchy): | ||
files_to_compile = '' | ||
cmds = [] | ||
for dep in deps: | ||
files_to_compile = files_to_compile+" "+dep[0] | ||
cmds.append(dep[1]) | ||
if len(deps)>1 and self.jobs>1 and __parallel__: | ||
jobs = min(len(deps),self.jobs) | ||
print(self.colors.bld+"Compiling"+files_to_compile+" using "+str(jobs)+" concurrent processes"+self.colors.end) | ||
pool = Pool(processes=jobs) | ||
results = pool.map(syswork,cmds) | ||
pool.close() | ||
pool.join() | ||
if not all(v[0] == 0 for v in results): | ||
for result in results: | ||
if result[0] != 0: | ||
print(self.colors.red+result[1]+self.colors.end) | ||
sys.exit(1) | ||
if not all(v[1] == '' for v in results): | ||
for result in results: | ||
if result[1] != '': | ||
print(self.colors.red+result[1]+self.colors.end) | ||
else: | ||
print(self.colors.bld+"Compiling"+files_to_compile+" serially "+self.colors.end) | ||
for cmd in cmds: | ||
result = syswork(cmd) | ||
if result[0] != 0: | ||
print(self.colors.red+result[1]+self.colors.end) | ||
sys.exit(1) | ||
else: | ||
print(self.colors.bld+'Nothing to compile, all objects are up-to-date'+self.colors.end) | ||
if file_to_build.program: | ||
if nomodlibs is not None: | ||
objs = nomodlibs + file_to_build.obj_dependencies() | ||
else: | ||
objs = file_to_build.obj_dependencies() | ||
if output: | ||
exe=self.build_dir+output | ||
else: | ||
exe=self.build_dir+file_to_build.basename | ||
link_cmd = self.cmd_link+" "+"".join([self.obj_dir+s+" " for s in objs])+"".join([s+" " for s in self.libs])+"-o "+exe | ||
print(self.colors.bld+"Linking "+exe+self.colors.end) | ||
result = syswork(link_cmd) | ||
if result[0] != 0: | ||
print(self.colors.red+result[1]+self.colors.end) | ||
sys.exit(1) | ||
print(self.colors.bld+'Target '+file_to_build.name+' has been successfully built'+self.colors.end) | ||
elif mklib: | ||
if output: | ||
lib=self.build_dir+output | ||
else: | ||
if mklib.lower()=='shared': | ||
lib=self.build_dir+file_to_build.basename+'.so' | ||
elif mklib.lower()=='static': | ||
lib=self.build_dir+file_to_build.basename+'.a' | ||
if mklib.lower()=='shared': | ||
link_cmd = self.cmd_link+" "+"".join([s+" " for s in self.libs])+self.obj_dir+file_to_build.basename+".o -o "+lib | ||
elif mklib.lower()=='static': | ||
link_cmd = "ar -rcs "+lib+" "+self.obj_dir+file_to_build.basename+".o ; ranlib "+lib | ||
print(self.colors.bld+"Linking "+lib+self.colors.end) | ||
result = syswork(link_cmd) | ||
if result[0] != 0: | ||
print(self.colors.red+result[1]+self.colors.end) | ||
sys.exit(1) | ||
print(self.colors.bld+'Target '+file_to_build.name+' has been successfully built'+self.colors.end) | ||
|
||
def verbose(self): | ||
""" | ||
The method verbose returns a verbose message containing builder infos. | ||
""" | ||
message = '' | ||
if not self.quiet: | ||
message = "Builder options"+"\n" | ||
message+= " Compiled-objects .o directory: "+self.obj_dir+"\n" | ||
message+= " Compiled-objects .mod directory: "+self.mod_dir+"\n" | ||
message+= " Building directory: "+self.build_dir+"\n" | ||
message+= " Included paths: "+"".join([s+" " for s in self.dinc])+"\n" | ||
message+= " Linked libraries: "+"".join([s+" " for s in self.libs])+"\n" | ||
message+= " Compiler class: "+self.compiler+"\n" | ||
message+= " Compiler: "+self.fcs+"\n" | ||
message+= " Compiler module switch: "+self.modsw+"\n" | ||
message+= " Compilation flags: "+self.cflags+"\n" | ||
message+= " Linking flags: "+self.lflags+"\n" | ||
message+= " Preprocessing flags: "+self.preproc+"\n" | ||
message+= " PreForM.py used: "+str(self.preform)+"\n" | ||
message+= " PreForM.py output directory: "+str(self.pfm_dir)+"\n" | ||
message+= " PreForM.py extensions processed: "+str(self.pfm_ext)+"\n" | ||
return message |
Oops, something went wrong.