userland: convert make to python

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-03-11 00:00:00 +00:00
parent 0deab8f8f7
commit 1a0d15ca86
19 changed files with 445 additions and 290 deletions

View File

@@ -4,6 +4,7 @@ import os
import shlex
import common
import subprocess
from shell_helpers import LF
class Main(common.BuildCliFunction):
@@ -22,18 +23,6 @@ Indicate that a given package is present in the root filesystem, which
allows us to build examples that rely on it.
''',
)
self.add_argument(
'--host',
default=False,
help='''\
Build the userland programs for the host instead of guest.
Use the host packaged cross toolchain.
''',
)
self.add_argument(
'--make-args',
default='',
)
self.add_argument(
'targets',
default=[],
@@ -46,43 +35,196 @@ has the OpenBLAS libraries and headers installed.
nargs='*',
)
def _build_one(
self,
in_path,
out_path,
ccflags,
extra_deps=None,
link=True,
extra_objs=None,
std=None,
ccflags_after=None,
):
if extra_deps is None:
extra_deps = []
if extra_objs is None:
extra_objs = []
if ccflags_after is None:
ccflags_after = []
if self.need_rebuild([in_path] + extra_objs + extra_deps, out_path):
ccflags = ccflags.copy()
if not link:
ccflags.extend(['-c', LF])
in_ext = os.path.splitext(in_path)[1]
if in_ext == self.env['c_ext']:
cc = self.env['gcc']
if std is None:
std = 'c11'
ccflags.extend([
'-fopenmp', LF,
])
elif in_ext == self.env['cxx_ext']:
cc = self.env['gxx']
if std is None:
std = 'c++17'
else:
return
self.sh.run_cmd(
[
cc, LF,
] +
ccflags +
[
'-std={}'.format(std), LF,
'-o', out_path, LF,
in_path, LF,
] +
extra_objs +
[
'-lm', LF,
'-pthread', LF,
] +
ccflags_after
)
def build(self):
build_dir = self.get_build_dir()
os.makedirs(build_dir, exist_ok=True)
make_args = shlex.split(self.env['make_args'])
has_packages = set(self.env['has_package'])
ccflags = [
'-I', self.env['root_dir'], LF,
'-I', self.env['userland_source_dir'], LF,
'-O0', LF,
'-Wall', LF,
'-Werror', LF,
'-Wextra', LF,
'-Wno-unused-function', LF,
'-pedantic', LF,
'-ggdb3', LF,
]
if self.env['static']:
make_args.extend(['CCFLAGS_EXTRA=-static', LF])
self.sh.run_cmd(
(
[
'make', LF,
'-j', str(self.env['nproc']), LF,
'ARCH={}'.format(self.env['arch']), LF,
'CCFLAGS_SCRIPT={} {}'.format('-I', self.env['userland_source_dir']), LF,
'COMMON_DIR={}'.format(self.env['root_dir']), LF,
'CC={}'.format(self.get_toolchain_tool('gcc')), LF,
'CXX={}'.format(self.get_toolchain_tool('g++')), LF,
'PKG_CONFIG={}'.format(self.env['buildroot_pkg_config']), LF,
'STAGING_DIR={}'.format(self.env['buildroot_staging_dir']), LF,
'OUT_DIR={}'.format(build_dir), LF,
] +
self.sh.add_newlines([
'HAS_{}=y'.format(package.upper())
for package in
self.env['has_package']
]) +
make_args +
self.sh.add_newlines([
os.path.join(
build_dir,
os.path.splitext(os.path.split(target)[1])[0]
) + self.env['userland_build_ext']
for target in self.env['targets']
])
),
cwd=self.env['userland_source_dir'],
extra_paths=[self.env['ccache_dir']],
ccflags.extend(['-static', LF])
common_obj = os.path.join(
build_dir,
self.env['common_basename_noext'] + self.env['obj_ext']
)
self._build_one(
in_path=self.env['common_c'],
out_path=common_obj,
ccflags=ccflags,
extra_deps=[self.env['common_h']],
link=False,
)
pkgs = {
'eigen': {
# TODO: was failing with:
# fatal error: Eigen/Dense: No such file or directory as of
# 975ce0723ee3fa1fea1766e6683e2f3acb8558d6
# http://lists.busybox.net/pipermail/buildroot/2018-June/222914.html
'ccflags': [
'-I',
os.path.join(
self.env['buildroot_staging_dir'],
'usr',
'include',
'eigen3'
),
LF
],
# Header only.
'ccflags_after': [],
},
'libdrm': {},
'openblas': {},
}
rootdir_abs_len = len(self.env['userland_source_dir'])
for path, in_dirnames, in_filenames in os.walk(self.env['userland_source_dir']):
in_dirnames.sort()
dirpath_relative_root = path[rootdir_abs_len + 1:]
dirpath_relative_root_components = dirpath_relative_root.split(os.sep)
if (
len(dirpath_relative_root_components) < 2 or
dirpath_relative_root_components[0] != 'arch' or
dirpath_relative_root_components[1] == self.env['arch']
):
out_dir = os.path.join(
self.env['userland_build_dir'],
dirpath_relative_root
)
os.makedirs(out_dir, exist_ok=True)
for in_filename in in_filenames:
in_path = os.path.join(path, in_filename)
in_name, in_ext = os.path.splitext(in_filename)
out_path = os.path.join(
out_dir,
in_name + self.env['userland_build_ext']
)
pkg_key = in_name.split('_')[0]
ccflags_file = ccflags.copy()
ccflags_after = []
if pkg_key in pkgs:
if pkg_key not in has_packages:
continue
pkg = pkgs[pkg_key]
if 'ccflags' in pkg:
ccflags_file.extend(pkg['ccflags'])
else:
pkg_config_output = subprocess.check_output([
self.env['buildroot_pkg_config'],
'--cflags',
pkg_key
]).decode()
ccflags_file.extend(self.sh.shlex_split(pkg_config_output))
if 'ccflags_after' in pkg:
ccflags_file.extend(pkg['ccflags_after'])
else:
pkg_config_output = subprocess.check_output([
self.env['buildroot_pkg_config'],
'--libs',
pkg_key
]).decode()
ccflags_after.extend(self.sh.shlex_split(pkg_config_output))
self._build_one(
in_path=in_path,
out_path=out_path,
ccflags=ccflags_file,
extra_objs=[common_obj],
ccflags_after=ccflags_after,
)
#self.sh.run_cmd(
# (
# [
# 'make', LF,
# '-j', str(self.env['nproc']), LF,
# 'ARCH={}'.format(self.env['arch']), LF,
# 'CCFLAGS_SCRIPT={} {}'.format('-I', self.env['userland_source_dir']), LF,
# 'COMMON_DIR={}'.format(self.env['root_dir']), LF,
# 'CC={}'.format(self.env['gcc']), LF,
# 'CXX={}'.format(self.env['gxx']), LF,
# 'PKG_CONFIG={}'.format(self.env['buildroot_pkg_config']), LF,
# 'STAGING_DIR={}'.format(self.env['buildroot_staging_dir']), LF,
# 'OUT_DIR={}'.format(build_dir), LF,
# ] +
# self.sh.add_newlines([
# 'HAS_{}=y'.format(package.upper())
# for package in
# self.env['has_package']
# ]) +
# make_args +
# self.sh.add_newlines([
# os.path.join(
# build_dir,
# os.path.splitext(os.path.split(target)[1])[0]
# ) + self.env['userland_build_ext']
# for target in self.env['targets']
# ])
# ),
# cwd=self.env['userland_source_dir'],
# extra_paths=[self.env['ccache_dir']],
#)
self.sh.copy_dir_if_update(
srcdir=build_dir,
destdir=self.env['out_rootfs_overlay_dir'],