userland: maybe it really works

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-05-05 00:00:00 +00:00
parent 0c9afcf9b6
commit bbdf6cdc06
5 changed files with 89 additions and 111 deletions

View File

@@ -40,14 +40,6 @@ Indicate that all packages from --has-package are available.
help='''\
Place build output inside soure tree to conveniently run it, especially when
building with the host toolchain.
''',
)
self.add_argument(
'--target-relative-cwd',
default=False,
help='''\
Treat targets as relative to the current working directory. If the current working
directory is outside of userland/, this has no effect.
''',
)
self.add_argument(
@@ -133,54 +125,35 @@ Default: build all examples that have their package dependencies met, e.g.:
)
return ret
def _get_cwd(self):
cwd = os.path.abspath(os.getcwd())
if cwd.startswith(self.env['userland_source_dir']):
return cwd
else:
return self.env['userland_source_dir']
def _walk_targets(self, exts):
'''
Resolve userland input targets, and walk them if directories.
def _get_targets(self):
Ignore the input extension of targets, and select only files
with the given extensions exts.
An empty extension indicates that directories will also be chosen.
'''
Resolve target_relative_cwd and default targets.
'''
if self.env['_args_given']['targets']:
if self.env['targets']:
targets = self.env['targets']
if self.env['target_relative_cwd']:
cwd = self._get_cwd()
for target in targets:
yield os.path.join(cwd, target)
else:
for target in targets:
yield target
else:
if self.env['target_relative_cwd']:
yield self._get_cwd()
else:
yield self.env['userland_source_dir']
def _walk_targets(self):
'''
Walk existing directories and files pointed to by the targets
from the command line from under the userland/ source tree.
This may include outputs of in-tree builds.
File extensions are ignored, e.g.:
c/hello
will find both:
c/hello.c
c/hello.out
'''
for target in self._get_targets():
target = self.resolve_userland_source(target)
noext, ext = os.path.splitext(filename)
for path, in_dirnames, in_filenames in self.sh.walk(target):
yield path, in_dirnames, in_filenames
targets = [self.env['userland_source_dir']]
for target in targets:
resolved_targets = self.resolve_source_tree(
target,
exts + [''],
self.env['userland_source_dir']
)
for resolved_target in resolved_targets:
for path, dirnames, filenames in self.sh.walk(resolved_target):
dirnames.sort()
filenames = [
filename for filename in filenames
if os.path.splitext(filename)[1] in exts
]
filenames.sort()
for filename in filenames:
yield path, dirnames, filenames
def build(self):
build_dir = self.get_build_dir()
@@ -260,9 +233,9 @@ Default: build all examples that have their package dependencies met, e.g.:
) as thread_pool:
class ExitLoop(Exception): pass
try:
for path, in_dirnames, in_filenames in self._walk_targets():
in_dirnames.sort()
in_filenames.sort()
for path, in_dirnames, in_filenames in self._walk_targets(
self.env['userland_in_exts']
):
path_abs = os.path.abspath(path)
dirpath_relative_root = path_abs[rootdir_abs_len + 1:]
dirpath_relative_root_components = dirpath_relative_root.split(os.sep)
@@ -377,6 +350,7 @@ Default: build all examples that have their package dependencies met, e.g.:
raise ExitLoop()
except ExitLoop:
pass
error = thread_pool.get_error()
if error is not None:
print(error)
return 1
@@ -390,15 +364,11 @@ Default: build all examples that have their package dependencies met, e.g.:
def clean(self):
if self.env['in_tree']:
for path, dirnames, filenames in self._walk_targets():
filenames.sort()
dirnames.sort()
for path, dirnames, filenames in self._walk_targets(
self.env['userland_out_exts']
):
for filename in filenames:
noext, ext = os.path.splitext(filename)
for out_ext in self.env['userland_out_exts']:
out_path = os.path.join(path, noext + out_ext)
if os.path.exists(out_path):
self.sh.rmrf(out_path)
self.sh.rmrf(os.path.join(path, filename))
else:
self.sh.rmrf(self.get_build_dir())

View File

@@ -24,7 +24,7 @@ https://github.com/cirosantilli/linux-kernel-module-cheat#userland-setup-getting
'gcc_which': 'host',
'has_all_packages': True,
'in_tree': True,
'target_relative_cwd': True,
'targets': ['.'],
}
)

View File

@@ -12,6 +12,7 @@ import json
import math
import os
import platform
import pathlib
import re
import shutil
import signal
@@ -1121,7 +1122,7 @@ lunch aosp_{}-eng
]
)
def resolve_source(self, in_path, magic_in_dir, exts):
def resolve_source_tree(self, in_path, exts, source_tree_root):
'''
Convert a convenient shorthand user input string to paths of existing files
in the source tree.
@@ -1162,24 +1163,24 @@ lunch aosp_{}-eng
files and directories: e.g. if you had both a file arch.c and a directory arch,
and exts=['', '.c'], then both would get matched.
'''
if os.path.isabs(in_path):
return in_path
else:
paths = [
os.path.join(magic_in_dir, in_path),
os.path.join(
magic_in_dir,
os.path.relpath(in_path, magic_in_dir),
in_path = os.path.abspath(in_path)
source_tree_root = os.path.abspath(source_tree_root)
if not in_path.startswith(source_tree_root):
raise Exception(
'The input path {} is not inside the source directory {}'.format(
in_path,
source_tree_root
)
]
for path in paths:
name, ext = os.path.splitext(path)
for try_ext in exts:
path = name + try_ext
if os.path.exists(path):
return path
if not self.env['dry_run']:
raise Exception('No file not found for input: ' + in_path)
)
result = []
name, ext = os.path.splitext(in_path)
for try_ext in exts:
try_path = name + try_ext
if os.path.exists(try_path):
result.append(try_path)
if not result:
raise Exception('No file not found for input: ' + in_path)
return result
def resolve_executable(self, in_path, magic_in_dir, magic_out_dir, out_exts):
if os.path.isabs(in_path):
@@ -1212,13 +1213,6 @@ lunch aosp_{}-eng
[self.env['userland_build_ext']],
)
def resolve_userland_source(self, path):
return self.resolve_source(
path,
self.env['userland_source_dir'],
self.env['userland_in_exts']
)
def setup(self):
'''
Similar to timed_main, but gets run only once for all --arch and --emulator,

View File

@@ -1,42 +1,52 @@
#!/usr/bin/env bash
# Quick sanity check that userland target resoltion at least does not blow up.
set -eux
./build-userland
./build-userland --clean
./build-userland c
./build-userland --clean
./build-userland userland/c
./build-userland --clean
./build-userland --clean userland/c
./build-userland userland/c/hello
./build-userland --clean
./build-userland --clean userland/c/hello
./build-userland userland/c/hello.
./build-userland --clean userland/c/hello.
./build-userland userland/c/hello.c
./build-userland --clean
./build-userland --clean userland/c/hello.c
./build-userland userland/c/hello.out
./build-userland --clean
./build-userland --clean userland/c/hello.out
./build-userland "$(pwd)/userland/c/hello.out"
./build-userland --clean "$(pwd)/userland/c/hello.out"
./build-userland --in-tree
./build-userland --in-tree --clean
./build-userland --in-tree c
./build-userland --in-tree --clean
./build-userland --in-tree userland/c
./build-userland --in-tree --clean
./build-userland --in-tree --clean userland/c
./build-userland --in-tree userland/c/hello
./build-userland --in-tree --clean
./build-userland --in-tree --clean userland/c/hello
./build-userland --in-tree userland/c/hello.
./build-userland --in-tree --clean userland/c/hello.
./build-userland --in-tree userland/c/hello.c
./build-userland --in-tree --clean
./build-userland --in-tree --clean userland/c/hello.c
./build-userland --in-tree userland/c/hello.out
./build-userland --in-tree --clean userland/c/hello.out
./build-userland --in-tree "$(pwd)/userland/c/hello.out"
./build-userland --in-tree --clean "$(pwd)/userland/c/hello.out"
./build-userland --in-tree --clean
cd userland
./build-userland --in-tree
./build-userland --in-tree --clean
./build-userland --in-tree c
./build-userland --in-tree --clean
./build-userland --in-tree c/hello
./build-userland --in-tree --clean
./build-userland --in-tree c/hello.c
./build-userland --in-tree --clean
./build-userland --in-tree c/hello.out
./build-userland --in-tree --clean
./build
./build --clean
./build c
./build --clean c
./build c/hello
./build --clean c/hello
./build c/hello.
./build --clean c/hello.
./build c/hello.c
./build --clean c/hello.c
./build c/hello.out
./build --clean c/hello.out
./build "$(pwd)/c/hello.out"
./build --clean "$(pwd)/c/hello.out"

View File

@@ -84,6 +84,9 @@ class ThreadPool:
def __exit__(self, type, value, traceback):
self.join()
def get_error(self):
return self.error_output
def submit(self, work):
'''
Submit work. Block if there is already enough work scheduled (~nthreads).
@@ -117,6 +120,7 @@ class ThreadPool:
out = self.func(**work)
except Exception as e:
exception = e
out = None
try:
handle_output_return = self.handle_output(work, out, exception)
except Exception as e: