def _create_shared_base()

in python/treelite/contrib/util.py [0:0]


def _create_shared_base(dirpath, recipe, nthread, verbose):
  # Fetch toolchain-specific commands
  obj_cmd = recipe['create_object_cmd']
  lib_cmd = recipe['create_library_cmd']
  create_log_cmd \
    = _create_log_cmd_windows if _is_windows() else _create_log_cmd_unix
  save_retcode_cmd \
    = _save_retcode_cmd_windows if _is_windows() else _save_retcode_cmd_unix

  # 1. Compile sources in parallel
  if verbose:
    log_info(__file__, lineno(),
             'Compiling sources files in directory {} '.format(dirpath) +\
             'into object files (*{})...'.format(recipe['object_ext']))
  ncore = cpu_count()
  ncpu = min(ncore, nthread) if nthread is not None else ncore
  workqueue = [{
      'tid': tid,
      'queue': [],
      'dirpath': os.path.abspath(dirpath),
      'init_cmd': recipe['initial_cmd'],
      'create_log_cmd': create_log_cmd,
      'save_retcode_cmd': save_retcode_cmd
  } for tid in range(ncpu)]
  for i, source in enumerate(recipe['sources']):
    workqueue[i % ncpu]['queue'].append(obj_cmd(source['name']))
  proc = [_enqueue(workqueue[tid]) for tid in range(ncpu)]
  result = []
  for tid in range(ncpu):
    result.append(_wait(proc[tid], workqueue[tid]))

  for tid in range(ncpu):
    if not all(x == 0 for x in result[tid]['retcode']):
      with open(os.path.join(dirpath, 'log_cpu{}.txt'.format(tid)), 'w') as f:
        f.write(result[tid]['stdout'] + '\n')
      raise TreeliteError('Error occured in worker #{}: '.format(tid) +\
                          '{}'.format(result[tid]['stdout']))

  # 2. Package objects into a dynamic shared library
  if verbose:
    log_info(__file__, lineno(),
             'Generating dynamic shared library {}...'\
              .format(
                  os.path.join(dirpath,
                               recipe['target'] + recipe['library_ext'])))
  objects = [x['name'] + recipe['object_ext'] for x in recipe['sources']] \
            + recipe.get('extra', [])
  workqueue = {
      'tid': 0,
      'queue': [lib_cmd(objects, recipe['target'])],
      'dirpath': os.path.abspath(dirpath),
      'init_cmd': recipe['initial_cmd'],
      'create_log_cmd': create_log_cmd,
      'save_retcode_cmd': save_retcode_cmd
  }
  proc = _enqueue(workqueue)
  result = _wait(proc, workqueue)

  if result['retcode'][0] != 0:
    with open(os.path.join(dirpath, 'log_cpu0.txt'), 'w') as f:
      f.write(result['stdout'] + '\n')
    raise TreeliteError('Error occured while creating dynamic library: ' +\
                        '{}'.format(result['stdout']))

  # 3. Clean up
  for tid in range(ncpu):
    os.remove(os.path.join(dirpath, 'retcode_cpu{}.txt').format(tid))

  # Return full path of shared library
  return os.path.join(os.path.abspath(dirpath),
                      recipe['target'] + recipe['library_ext'])