[toolchain] Added `--dest-dir` switch
- Changed `--target-dir` to `--install-dir`
- Updated references in other files.
- Added `--dest-dir` switch to allow a staged installation
- Added `--latest-available-version` switch to return the latest version
- This will be used to construct the `--install-dir` path when
performing the staged installation.
- Fixes #4219
Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 1a5f881..120075b 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -271,7 +271,7 @@
- bash: |
set -x
sudo util/get-toolchain.py \
- --target-dir="$TOOLCHAIN_PATH" \
+ --install-dir="$TOOLCHAIN_PATH" \
--release-version="$TOOLCHAIN_VERSION" \
--update
displayName: Install toolchain
@@ -302,7 +302,7 @@
- bash: |
set -x
sudo util/get-toolchain.py \
- --target-dir="$TOOLCHAIN_PATH" \
+ --install-dir="$TOOLCHAIN_PATH" \
--release-version="$TOOLCHAIN_VERSION" \
--update
displayName: Install toolchain
@@ -400,7 +400,7 @@
- bash: |
set -x
sudo util/get-toolchain.py \
- --target-dir="$TOOLCHAIN_PATH" \
+ --install-dir="$TOOLCHAIN_PATH" \
--release-version="$TOOLCHAIN_VERSION" \
--update
echo "##vso[task.prependpath]$TOOLCHAIN_PATH/bin"
diff --git a/ci/run-riscv-compliance.yml b/ci/run-riscv-compliance.yml
index 4f4d8bb..4e15474 100644
--- a/ci/run-riscv-compliance.yml
+++ b/ci/run-riscv-compliance.yml
@@ -22,7 +22,7 @@
- bash: |
set -x
sudo util/get-toolchain.py \
- --target-dir="${TOOLCHAIN_PATH}" \
+ --install-dir="${TOOLCHAIN_PATH}" \
--release-version="${TOOLCHAIN_VERSION}" \
--update
displayName: Install toolchain
diff --git a/doc/ug/install_instructions/index.md b/doc/ug/install_instructions/index.md
index 4d26b0a..0876624 100644
--- a/doc/ug/install_instructions/index.md
+++ b/doc/ug/install_instructions/index.md
@@ -149,8 +149,9 @@
$ ./util/get-toolchain.py
```
-This tool will automatically adjust the toolchain configuration if you override the installation directory (by using the `--target-dir` option).
-Alternatively, manually download the file starting with `lowrisc-toolchain-rv32imc-` from [GitHub releases](https://github.com/lowRISC/lowrisc-toolchains/releases/latest) and unpack it to `/tools/riscv`.
+This tool will automatically adjust the toolchain configuration if you override the installation directory (by using the `--install-dir` option).
+It also provides the ability to perform a staged installation (by supplying a `--dest-dir` option), if the toolchain needs to be unpacked first at a temporary staging directory, before it can be moved to the final installation directory.
+Alternatively, manually download the file starting with `lowrisc-toolchain-rv32imc-` from [GitHub releases](https://github.com/lowRISC/lowrisc-toolchains/releases/latest) and unpack it to the desired installation directory.
#### Option 2: Compile your own GCC toolchain
diff --git a/util/get-toolchain.py b/util/get-toolchain.py
index 305484e..11ed46c 100755
--- a/util/get-toolchain.py
+++ b/util/get-toolchain.py
@@ -25,7 +25,7 @@
ASSET_SUFFIX = ".tar.xz"
RELEASES_URL_BASE = 'https://api.github.com/repos/lowRISC/lowrisc-toolchains/releases'
-TARGET_DIR = '/tools/riscv'
+INSTALL_DIR = '/tools/riscv'
TOOLCHAIN_VERSION = 'latest'
TOOLCHAIN_KIND = 'combined'
@@ -62,12 +62,12 @@
raise SystemExit(1)
-def get_installed_toolchain_info(install_path):
+def get_installed_toolchain_info(unpack_dir):
# Try new-style buildinfo.json first
try:
buildinfo = {}
- with open(str(install_path / 'buildinfo.json'), 'r') as f:
+ with open(str(unpack_dir / 'buildinfo.json'), 'r') as f:
buildinfo = json.loads(f.read())
# Toolchains before 20200602-4 contained a `buildinfo.json` without a
@@ -84,7 +84,7 @@
# If that wasn't successful, try old-style plaintext buildinfo
version_re = r"(lowRISC toolchain version|Version):\s*\n?(?P<version>[^\n\s]+)"
- buildinfo_txt_path = install_path / 'buildinfo'
+ buildinfo_txt_path = unpack_dir / 'buildinfo'
try:
with open(str(buildinfo_txt_path), 'r') as f:
match = re.match(version_re, f.read(), re.M)
@@ -106,43 +106,63 @@
return Path(tmpfile)
-def install(archive_file, target_dir):
- target_dir.mkdir(parents=True, exist_ok=True)
+def install(archive_file, unpack_dir):
+ unpack_dir.mkdir(parents=True, exist_ok=True)
cmd = [
- 'tar', '-x', '-f', str(archive_file), '--strip-components=1', '-C', str(target_dir),
+ 'tar', '-x', '-f', str(archive_file), '--strip-components=1', '-C', str(unpack_dir),
]
subprocess.run(cmd, check=True)
-def postinstall_rewrite_configs(install_path):
- """This rewrites the toolchain configuration files to point to install_path"""
- if str(install_path) == TARGET_DIR:
+def postinstall_rewrite_configs(unpack_dir, install_dir):
+ """Rewrites the toolchain configuration files to point to install_dir.
+
+ 'unpack_dir' is where the toolchain is unpacked by this script.
+ 'install_dir' is where the toolchain is eventually invoked from. Typically,
+ these are the same, unless a staged installation is being performed by
+ supplying both, --install-dir and --dest-dir switches. Regardless, if the
+ 'install_dir' is different from the default, the config files need to be
+ updated to reflect the correct paths.
+ """
+ if str(install_dir) == INSTALL_DIR:
return
for file_pattern in FILE_PATTERNS_TO_REWRITE:
- for config_file_path in install_path.glob(file_pattern):
- # Rewrite TARGET_DIR to the requested target dir.
+ for config_file_path in unpack_dir.glob(file_pattern):
+ # Rewrite INSTALL_DIR to the requested target dir.
log.info("Updating toolchain paths in %s",
str(config_file_path))
with open(str(config_file_path)) as f:
original = f.read()
with open(str(config_file_path), "w") as f:
- f.write(original.replace(TARGET_DIR, str(install_path)))
+ f.write(original.replace(INSTALL_DIR, str(install_dir)))
def main():
parser = argparse.ArgumentParser()
- parser.add_argument('--target-dir',
- '-t',
+ parser.add_argument('--install-dir',
+ '-i',
required=False,
- default=TARGET_DIR,
- help="Target directory (default: %(default)s)")
+ default=INSTALL_DIR,
+ help="Installation directory (default: %(default)s)")
+ parser.add_argument('--dest-dir',
+ '-d',
+ required=False,
+ help="""Destination directory if performing a staged
+ installation. This is the staging directory where the
+ toolchain is unpacked.""")
parser.add_argument('--release-version',
'-r',
required=False,
default=TOOLCHAIN_VERSION,
help="Toolchain version (default: %(default)s)")
+ parser.add_argument('--latest-available-version',
+ '-l',
+ required=False,
+ default=False,
+ action='store_true',
+ help="Return the latest available toolchain version.")
parser.add_argument('--kind',
required=False,
default=TOOLCHAIN_KIND,
@@ -157,20 +177,29 @@
help="Update to target version if needed (default: %(default)s)")
args = parser.parse_args()
- target_dir = Path(args.target_dir)
-
available_toolchain = get_available_toolchain_info(args.release_version,
args.kind)
+
+ if args.latest_available_version:
+ print(available_toolchain['version'])
+ sys.exit(0)
+
log.info("Found available %s toolchain version %s, %s",
available_toolchain['kind'], available_toolchain['version'],
available_toolchain['name'])
- if args.update and target_dir.is_dir():
- installed_toolchain = get_installed_toolchain_info(target_dir)
+ install_dir = Path(args.install_dir)
+ if args.dest_dir is None:
+ unpack_dir = install_dir
+ else:
+ unpack_dir = Path(args.dest_dir)
+
+ if args.update and unpack_dir.is_dir():
+ installed_toolchain = get_installed_toolchain_info(unpack_dir)
if installed_toolchain is None:
sys.exit('Unable to extract current toolchain version. '
'Delete target directory %s and try again.' %
- str(target_dir))
+ str(unpack_dir))
version_matches = available_toolchain['version'] == installed_toolchain['version']
kind_matches = available_toolchain['kind'] == installed_toolchain['kind']
@@ -181,7 +210,7 @@
'same as the %s toolchain installed at %s (version %s).',
available_toolchain['kind'], available_toolchain['version'],
installed_toolchain['kind'], installed_toolchain['version'],
- str(target_dir))
+ str(unpack_dir))
log.warning("Skipping install.")
sys.exit(0)
@@ -190,28 +219,28 @@
installed_toolchain['kind'], installed_toolchain['version'],
available_toolchain['kind'], available_toolchain['version'])
else:
- if target_dir.exists():
+ if unpack_dir.exists():
sys.exit('Target directory %s already exists. '
- 'Delete it first, or use --update.' % str(target_dir))
+ 'Delete it first, or use --update.' % str(unpack_dir))
archive_file = None
try:
archive_file = download(available_toolchain['download_url'])
- if args.update and target_dir.exists():
- # We only reach this point if |target_dir| contained a toolchain
+ if args.update and unpack_dir.exists():
+ # We only reach this point if |unpack_dir| contained a toolchain
# before, so removing it is reasonably safe.
- shutil.rmtree(str(target_dir))
+ shutil.rmtree(str(unpack_dir))
- install(archive_file, target_dir)
- postinstall_rewrite_configs(target_dir.resolve())
+ install(archive_file, unpack_dir)
+ postinstall_rewrite_configs(unpack_dir.resolve(), install_dir.resolve())
finally:
if archive_file:
archive_file.unlink()
log.info('Installed %s toolchain version %s to %s.',
available_toolchain['kind'], available_toolchain['version'],
- str(target_dir))
+ str(unpack_dir))
if __name__ == "__main__":