in python/treelite/contrib/__init__.py [0:0]
def generate_makefile(dirpath, platform, toolchain, options=None):
"""
Generate a Makefile for a given directory of headers and sources. The
resulting Makefile will be stored in the directory. This function is useful
for deploying a model on a different machine.
Parameters
----------
dirpath : :py:class:`str <python:str>`
directory containing the header and source files previously generated
by :py:meth:`Model.compile`. The directory must contain recipe.json
which specifies build dependencies.
platform : :py:class:`str <python:str>`
name of the operating system on which the headers and sources shall be
compiled. Must be one of the following: 'windows' (Microsoft Windows),
'osx' (Mac OS X), 'unix' (Linux and other UNIX-like systems)
toolchain : :py:class:`str <python:str>`
which toolchain to use. You may choose one of 'msvc', 'clang', and 'gcc'.
You may also specify a specific variation of clang or gcc (e.g. 'gcc-7')
options : :py:class:`list <python:list>` of :py:class:`str <python:str>`, \
optional
Additional options to pass to toolchain
"""
if not os.path.isdir(dirpath):
raise TreeliteError('Directory {} does not exist'.format(dirpath))
try:
with open(os.path.join(dirpath, 'recipe.json')) as f:
recipe = json.load(f)
except IOError:
raise TreeliteError('Failed to open recipe.json')
if 'sources' not in recipe or 'target' not in recipe:
raise TreeliteError('Malformed recipe.json')
if options is not None:
try:
_ = iter(options)
options = [str(x) for x in options]
except TypeError:
raise TreeliteError('options must be a list of string')
else:
options = []
# Determine file extensions for object and library files
if platform == 'windows':
lib_ext = '.dll'
elif platform == 'osx':
lib_ext = '.dylib'
elif platform == 'unix':
lib_ext = '.so'
else:
raise ValueError('Unknown platform: must be one of {windows, osx, unix}')
_toolchain_exist_check(toolchain)
if toolchain == 'msvc':
if platform != 'windows':
raise ValueError('Visual C++ is compatible only with Windows; ' + \
'set platform=\'windows\'')
from .msvc import _obj_ext, _obj_cmd, _lib_cmd
else:
from .gcc import _obj_ext, _obj_cmd, _lib_cmd
obj_ext = _obj_ext()
with open(os.path.join(dirpath, 'Makefile'), 'w') as f:
objects = [x['name'] + obj_ext for x in recipe['sources']] \
+ recipe.get('extra', [])
f.write('{}: {}\n'.format(recipe['target'] + lib_ext, ' '.join(objects)))
f.write('\t{}\n'.format(_lib_cmd(objects=objects,
target=recipe['target'],
lib_ext=lib_ext,
toolchain=toolchain,
options=options)))
for source in recipe['sources']:
f.write('{}: {}\n'.format(source['name'] + obj_ext,
source['name'] + '.c'))
f.write('\t{}\n'.format(_obj_cmd(source=source['name'],
toolchain=toolchain,
options=options)))