Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First step to using rustup. #33

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 6 additions & 27 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,16 @@ jobs:
# Check out pull request HEAD instead of merge commit.
ref: ${{ github.event.pull_request.head.sha }}
submodules: recursive

- name: "Set up nightly Rust" # https://github.com/rust-lang/rustup/issues/3409
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2024-08-28

- name: 'Set up tree for rust dependency'
run: make setup

- name: 'Cache smir_pretty and rustc'
uses: Swatinem/rust-cache@v2
with:
workspaces: |
.
deps/rust/src
cache-directories: |
target
deps/rust/src/build
deps/rust/src/target
toolchain: nightly-2024-11-29 # Hardcoded version, same as is in the build.rs

- name: 'Build smir_pretty and its rustc dependency'
run: | # rustc bootstrap checks this and refuses stage 1 in "CI"
export GITHUB_ACTIONS="in denial" && \
echo "GITHUB_ACTIONS = ${GITHUB_ACTIONS}" && \
make build_all

- name: 'Run smir integration tests'
- name: 'Build smir_pretty'
run: |
make integration-test
cargo build -vv

- name: 'Clean up toolchain'
if: always()
- name: 'Run smir integration tests'
run: |
make rustup-clear-toolchain
make integration-test
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@
name = "smir_pretty"
version = "0.1.0"
edition = "2021"
# rust-version = "1.78.0" # I think we get latest available rust by unsetting this and setting rust-toolchain.toml.toolchain.channel = nightly

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tracing = "0.1"
# serde = { version = "=1.0.202", features = ["derive"] }
# serde_cbor = "0.11"
# serde_json = "1.0"
# tar = "0.4"

[package.metadata.rust-analyzer]
# This package uses rustc crates.
rustc_private=true
rustc_private=true
106 changes: 2 additions & 104 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,115 +1,13 @@
TARGET ?= debug
STAGE ?= 1
ifneq (0, $(shell test "${STAGE}" -gt 0 2>/dev/null; echo "$$?"))
$(error STAGE must be set to a number greater than 0)
endif
ifneq (${TARGET}, $(filter ${TARGET},debug release))
$(error TARGET must be set to one of debug/release)
endif
RUST_DIR=${CURDIR}/deps/rust
STAGE_FILE=${RUST_DIR}/stage
RUST_SRC=${RUST_DIR}/src
RUST_ARCH=$(shell "${PWD}"/rustc_arch.sh)
RUST_BUILD_DIR=${RUST_SRC}/build/${RUST_ARCH}
RUST_INSTALL_DIR=${RUST_BUILD_DIR}/stage${STAGE}
RUST_LIB_DIR=${RUST_INSTALL_DIR}/lib
RUST_DEP_DIR=${RUST_BUILD_DIR}/stage1-rustc/${RUST_ARCH}/release/deps
TARGET_DEP_DIR=${CURDIR}/target/${TARGET}/deps
TEMP_DIR=${RUST_DIR}/temp
#############################################
# depend on the rust compiler
RUST_REPO=https://github.com/rust-lang/rust
# tip of the `beta` branch on 2025-01-14
RUST_BRANCH=beta
RUST_COMMIT=fe9b975
#############################################
TOOLCHAIN_NAME=smir_pretty
RELEASE_FLAG=
ifeq (${TARGET}, release)
RELEASE_FLAG=--release
endif

default: build

build_all: rust_build rust_set_toolchain build

setup: rust_clone

update: ${RUST_SRC}
cd "${RUST_SRC}"; git fetch origin; git checkout ${RUST_COMMIT}

build:
cargo build ${RELEASE_FLAG}

clean:
cd "${RUST_SRC}" && ./x.py clean
-rm -r "${TEMP_DIR}"
-rm -r "${RUST_DIR}"/tests
-rm -r ./target

distclean:
cd "${RUST_SRC}" && git clean -dffx
-rm -r "${TEMP_DIR}"
-rm -r "${RUST_DIR}"/tests
-rm -r ./target

# this clean removes old backup files which accumulate and lead to slow build times
prebuild_clean: ${RUST_SRC}
-find -name '*.old' -delete
-rm -r "${TEMP_DIR}"

# NOTE: a deeper clone depth is needed for the build process
rust_clone:
git clone --depth 70 --single-branch --branch "${RUST_BRANCH}" "${RUST_REPO}" "${RUST_SRC}" && \
cd "${RUST_SRC}" && \
git checkout ${RUST_COMMIT}


# rust_build for linking against custom rustc is involved
#
# 1. core rust compiler must be built via ./x.py build/install (we also build the test harness here)
# 2. rustc-dev component must be installed (./x.py build/install does _not_ handle, must be done manually)
# 3. HACK(only for ./x.py install) we copy required libraries to the libdir
# 4. finally, use rustup to create custom toolchain

rust_build: ${RUST_SRC} prebuild_clean
cd "${RUST_SRC}"; ./x.py build src/tools/compiletest
cd "${RUST_SRC}"; ./x.py build --stage ${STAGE} --set rust.debug-logging=true compiler/rustc library/std
cd "${RUST_SRC}"; ./x.py dist --set rust.debug-logging=true rustc-dev
mkdir -p "${TEMP_DIR}"
cd "${RUST_SRC}"; tar xf ./build/dist/rustc-dev*tar.gz -C "${TEMP_DIR}"
"${TEMP_DIR}"/rustc-dev*/install.sh --prefix="${RUST_INSTALL_DIR}" --sysconfdir="${RUST_INSTALL_DIR}" > "${RUST_DIR}"/rustc-dev-install.log 2>&1

rust_lib_copy:
cd "${RUST_LIB_DIR}"; cp libLLVM* rustlib/*/lib/

rust_set_toolchain: ${RUST_LIB_DIR}
rustup toolchain link "${TOOLCHAIN_NAME}" "${RUST_INSTALL_DIR}"
rustup override set "${TOOLCHAIN_NAME}"
echo ${STAGE} > ${STAGE_FILE}

.PHONY: rustup-clear-toolchain
rustup-clear-toolchain:
rustup override unset
rustup override unset --nonexistent
rustup toolchain uninstall "${TOOLCHAIN_NAME}"

generate_ui_tests:
mkdir -p "${RUST_DIR}"/tests
cd "${RUST_SRC}"; ./get_runpass.sh tests/ui > "${RUST_DIR}"/tests_ui_sources
-cd "${RUST_SRC}"; ./ui_compiletest.sh "${RUST_SRC}" "${RUST_DIR}"/tests/ui/upstream "${RUST_DIR}"/tests_ui_sources --pass check --force-rerun 2>&1 > "${RUST_DIR}"/tests_ui_upstream.log
-cd "${RUST_SRC}"; RUST_BIN="${PWD}"/run.sh ./ui_compiletest.sh "${RUST_SRC}" "${RUST_DIR}"/tests/ui/smir "${RUST_DIR}"/tests_ui_sources --pass check --force-rerun 2>&1 > "${RUST_DIR}"/tests_ui_smir.log

TESTDIR=$(CURDIR)/tests/integration/programs

.PHONY: integration-test
integration-test: TESTS ?= $(shell find $(TESTDIR) -type f -name "*.rs")
integration-test: SMIR ?= $(CURDIR)/run.sh -Z no-codegen
integration-test: SMIR ?= cargo run -- "-Zno-codegen"
# override this to tweak how expectations are formatted
integration-test: NORMALIZE ?= jq -S -e -f $(TESTDIR)/../normalise-filter.jq
# override this to re-make golden files
integration-test: DIFF ?= | diff -
integration-test: build
integration-test:
errors=""; \
report() { echo "$$1: $$2"; errors="$$errors\n$$1: $$2"; }; \
for rust in ${TESTS}; do \
Expand Down
38 changes: 5 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,16 @@
# Rust Stable MIR Pretty Printing

This package provides:

1. a library crate that provides:
- a `rustc` compiler wrapper which can access stable MIR APIs
- a pretty-printer for a large fragment of stable MIR
2. a `rustc` wrapper binary that uses (1)-(2) to pretty-print Rust source files as stable MIR using the `.smir.json` extension.

It is designed so that anyone can use this library crate as a jumping off point for their own tools which might use stable MIR APIs.
This package provides a program that will emit a JSON serialisation of the Stable MIR of a Rust program

## Building

For first-time builds, run:

```shell
make setup build_all
```

If the underlying `rustc` branch is updated and this crate needs to be rebuilt on top of it, run:

```shell
make update build_all
cargo build
```

If the source code changes locally for this crate only and it needs to be rebuilt, run:
NOTE: requries [rustup](https://www.rust-lang.org/tools/install)

```shell
make build
```
The `build.rs` script will ensure that the correct version of rust and the required components are installed and defaulted. What `rustup` commands are run can be seen by adding verbosity flag `-vv` to `cargo`.

## Usage

Expand All @@ -36,7 +19,7 @@ The options that this tool accepts are identical to `rustc`.
To generate stable MIR output without building a binary, you can invoke the tool as follows:

```shell
./run.sh -Z no-codegen <crate_root>
cargo run -- <rustc_flags> <path_from_crate_root>
```

There are a few environment variables that can be set to control the tools output:
Expand All @@ -45,17 +28,6 @@ There are a few environment variables that can be set to control the tools outpu
2. `LINK_INST` - use a richer key-structure for the link-time `functions` map which uses keys that are pairs of a function type (`Ty`) _and_ an function instance kind (`InstanceKind`)
3. `DEBUG` - serialize additional data in the JSON file and dump logs to stdout

### Invocation Details

We use an uncommon build process where we link against a patched rustc installed in this repo.
However, since `cargo build` does not set `rpath` for dynamic linking, we must manually point the program loader/dynamic linker at the required runtime libraries.
Note that the `cargo run` command appears to prepard the rustlib directories automatically to the dynamic link search path.
If you wish to run the tool manually, you will need to tell the program loader/dynamic linker where to find the missing libraries by:

1. setting `LD_LIBRARY_PATH`
2. setting the `rpath` attribute on the binary ELF file
3. manually invoking the loader (usually `/usr/lib/ld-linux.so.2`) with its specific options

## Tests

### Running the Tests
Expand Down
31 changes: 31 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::process::Command;

fn main() {
let status = Command::new("rustup")
.args(&["install", "nightly-2024-11-29"])
.status()
.expect("build.rs failed to install nightly-2024-11-29");

println!("Installed nightly-2024-11-29: {}", status);

let status = Command::new("rustup")
.args(&["default", "nightly-2024-11-29"])
.status()
.expect("build.rs failed to default nightly-2024-11-29");

println!("Defaulted nightly-2024-11-29: {}", status);

let status = Command::new("rustup")
.args(&["component", "add", "rustc-dev"])
.status()
.expect("build.rs failed to install rustc-dev");

println!("Added component rustc-dev: {}", status);

let status = Command::new("rustup")
.args(&["component", "add", "llvm-tools"])
.status()
.expect("build.rs failed to install llvm-tools");

println!("Added component llvm-tools: {}", status);
}
1 change: 0 additions & 1 deletion deps/rust/.gitignore

This file was deleted.

19 changes: 0 additions & 19 deletions run.sh

This file was deleted.

2 changes: 0 additions & 2 deletions rust-toolchain.toml

This file was deleted.

2 changes: 0 additions & 2 deletions rustc_arch.sh

This file was deleted.

Loading