Skip to content

Commit

Permalink
Implement CMake build system
Browse files Browse the repository at this point in the history
Switch from Makefiles to CMake. Some formal outputs are not yet fully supported by the CMake so the old Makefile is retained.

This also adds a manual Github actions workflow to generate the JSON doc bundle, to allow inclusion of Sail snippets in the ISA manual.
  • Loading branch information
Timmmm committed Jan 27, 2025
1 parent 7cb8042 commit f964407
Show file tree
Hide file tree
Showing 19 changed files with 808 additions and 329 deletions.
17 changes: 14 additions & 3 deletions .github/workflows/compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Install packages
run: sudo apt install -y --no-install-recommends zlib1g-dev pkg-config libgmp-dev curl
run: sudo apt install -y --no-install-recommends zlib1g-dev pkg-config libgmp-dev curl ninja-build
- name: Check out repository code
uses: actions/checkout@HEAD
with:
Expand All @@ -19,13 +19,24 @@ jobs:
sudo mkdir -p /usr/local
curl --location https://github.com/rems-project/sail/releases/download/0.18-linux-binary/sail.tar.gz | sudo tar xvz --directory=/usr/local --strip-components=1
- name: Build and test simulators
run: test/run_tests.sh
run: |
mkdir build
cd build
# Ninja is used because the CMake Makefile generator doesn't
# build top-level targets in parallel unfortunately.
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
# By default only the rv32d and rv64d emulators are build,
# but we want to build more targets here to ensure they
# can at least build without errors.
ninja all riscv_sim_rv32d_rvfi generated_smt_rv64f generated_docs_rv64d
# These targets do not work with Sail 0.18: generated_rmem_rv32d_rmem generated_coq_rv64f_coq
ctest --output-junit text.xml
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: tests.xml
path: test/tests.xml
path: build/tests.xml
- name: Upload event payload
if: always()
uses: actions/upload-artifact@v4
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/generate-json.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Generate Doc JSON

on: [workflow_dispatch]

jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Install packages
run: sudo apt install -y --no-install-recommends zlib1g-dev pkg-config libgmp-dev curl ninja-build
- name: Check out repository code
uses: actions/checkout@HEAD
with:
submodules: true
- name: Install sail from binary
run: |
sudo mkdir -p /usr/local
curl --location https://github.com/rems-project/sail/releases/download/0.18-linux-binary/sail.tar.gz | sudo tar xvz --directory=/usr/local --strip-components=1
- name: Build JSON doc bundle
run: |
mkdir build
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..
ninja generated_docs_rv64d
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: riscv_model_rv64d.json
path: build/model/riscv_model_rv64d.json
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ _build/
_sbuild/
*.o
*.a
/z3_problems
z3_problems

# Typical CMake build directory.
/build
# CMake build directories used by CLion.
/cmake-build-*
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: '^(prover_snapshots)|(generated_definitions)|(dependencies/softfloat/berkeley-softfloat-3)'
exclude: '^(prover_snapshots)|(generated_definitions)|(dependencies/[^/]+/)'
minimum_pre_commit_version: 2.10.0
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
Expand Down
95 changes: 95 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
cmake_minimum_required(VERSION 3.20)

project(sail_riscv)

# Make users explicitly pick a build type so they don't get
# surprised when the default gives a very slow emulator.
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(FATAL_ERROR "
No build type selected. You need to pass -DCMAKE_BUILD_TYPE=<type> in order to configure the build.
* -DCMAKE_BUILD_TYPE=Release - Optimized build with no debug info.
* -DCMAKE_BUILD_TYPE=RelWithDebInfo - Optimized build with debug info.
* -DCMAKE_BUILD_TYPE=Debug - Unoptimized build with debug info.
* -DCMAKE_BUILD_TYPE=MinSizeRel - Optimized for size instead of speed.")
endif()

# Enable CTest
enable_testing()

# Export compile_commands.json for IDE support.
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

# Always use Position Independent Code. By default it is only used for
# shared libraries (which require it), but you also need it for static
# libraries if you link them into shared libraries.
# Generally it just simplifies everything for a negligable performance cost.
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)

# Don't allow undefined symbols. This is generally a pain.
include(CheckLinkerFlag)

check_linker_flag(C "-Wl,--no-undefined" LINKER_SUPPORTS_NO_UNDEFINED)
if (LINKER_SUPPORTS_NO_UNDEFINED)
add_link_options("-Wl,--no-undefined")
endif()

# Extra CMake files.
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

# These are the main requirements.
# Don't use `REQUIRED` so that we can print custom help messages.
find_package(ZLIB)
if (NOT ZLIB_FOUND)
if (APPLE)
message(FATAL_ERROR "Zlib not found. Try 'brew install zlib'.")
elseif (UNIX)
message(FATAL_ERROR "Zlib not found. Try 'sudo apt install zlib1g-dev' or 'sudo dnf install zlib-devel'.")
else()
message(FATAL_ERROR "Zlib not found.")
endif()
endif()

find_package(GMP)
if (NOT GMP_FOUND)
if (APPLE)
message(FATAL_ERROR "GMP not found. Try 'brew install gmp'.")
elseif (UNIX)
message(FATAL_ERROR "GMP not found. Try 'sudo apt install libgmp-dev' or 'sudo dnf install gmp-devel'.")
else()
message(FATAL_ERROR "GMP not found.")
endif()
endif()

find_program(SAIL_BIN "sail")
if (NOT SAIL_BIN)
message(FATAL_ERROR "Sail not found. See README.md for installation instructions.")
endif()

set(DEFAULT_ARCHITECTURES "rv32d;rv64d" CACHE STRING "Architectures to build by default (rv32f|rv64f|rv32d|rv64d)(_rvfi)? " )

option(COVERAGE "Compile with Sail coverage collection enabled.")

# Softfloat support.
add_subdirectory("dependencies/softfloat")

# Sail C runtime.
add_subdirectory("sail_runtime")

# Sail model generated C code.
add_subdirectory("model")

# Emulator binary.
add_subdirectory("c_emulator")

# Old pre-compiled riscv-tests.
add_subdirectory("test/riscv-tests")

# Convenience targets.
add_custom_target(csim DEPENDS riscv_sim_rv32d riscv_sim_rv64d)
add_custom_target(check DEPENDS generated_model_rv32d generated_model_rv64d)

# TODO: Support static linking.
# TODO: Add `interpret` target.
# TODO: Add isabelle target.
# TODO: Add lem target.
# TODO: Add hol4 target.
26 changes: 16 additions & 10 deletions Makefile → Makefile.old
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# WARNING! This Makefile is deprecated and has been *mostly* replaced by CMake.
# There are some targets related to formal backends (Coq, Hol4, etc.) that have
# not been fully transitioned, so this is kept for posterity.
#
# To build the emulators you can use the usual CMake flow, or `./build_simulators.sh`.

# Select architecture: RV32 or RV64.
ARCH ?= RV64

Expand Down Expand Up @@ -220,7 +226,7 @@ all: c_emulator/riscv_sim_$(ARCH)
# break future builds if sail exits badly
.DELETE_ON_ERROR: generated_definitions/c/%.c

check: $(SAIL_SRCS) model/main.sail Makefile
check: $(SAIL_SRCS) model/main.sail Makefile.old
$(SAIL) $(SAIL_FLAGS) $(SAIL_SRCS) model/main.sail

interpret: $(SAIL_SRCS) model/main.sail
Expand All @@ -230,15 +236,15 @@ sail_doc/riscv_$(ARCH).json: $(SAIL_SRCS) model/main.sail
$(SAIL) -doc -doc_bundle riscv_$(ARCH).json -o sail_doc $(SAIL_FLAGS) $(SAIL_DOC_FLAGS) $(SAIL_SRCS) model/main.sail

riscv.smt_model: $(SAIL_SRCS)
$(SAIL) -smt_serialize $(SAIL_FLAGS) $(SAIL_SRCS) -o riscv
$(SAIL) -smt $(SAIL_FLAGS) $(SAIL_SRCS) -o riscv

cloc:
cloc --by-file --force-lang C,sail $(SAIL_SRCS)

gcovr:
gcovr -r . --html --html-detail -o index.html

generated_definitions/c/riscv_model_$(ARCH).c: $(SAIL_SRCS) model/main.sail Makefile
generated_definitions/c/riscv_model_$(ARCH).c: $(SAIL_SRCS) model/main.sail Makefile.old
mkdir -p generated_definitions/c
$(SAIL) $(SAIL_FLAGS) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_SRCS) model/main.sail -o $(basename $@)

Expand All @@ -251,7 +257,7 @@ csim: c_emulator/riscv_sim_$(ARCH)
.PHONY: rvfi
rvfi: c_emulator/riscv_rvfi_$(ARCH)

c_emulator/riscv_sim_$(ARCH): generated_definitions/c/riscv_model_$(ARCH).c $(C_INCS) $(C_SRCS) $(SOFTFLOAT_LIBS) Makefile
c_emulator/riscv_sim_$(ARCH): generated_definitions/c/riscv_model_$(ARCH).c $(C_INCS) $(C_SRCS) $(SOFTFLOAT_LIBS) Makefile.old
$(CC) -g $(C_WARNINGS) $(C_FLAGS) $< $(C_SRCS) $(SAIL_LIB_DIR)/*.c $(C_LIBS_WRAPPED) -o $@

# Note: We have to add -c_preserve since the functions might be optimized out otherwise
Expand All @@ -270,16 +276,16 @@ rvfi_preserve_fns=-c_preserve rvfi_set_instr_packet \
-c_preserve print_rvfi_exec

# sed -i isn't posix compliant, unfortunately
generated_definitions/c/riscv_rvfi_model_$(ARCH).c: $(SAIL_RVFI_SRCS) model/main.sail Makefile
generated_definitions/c/riscv_rvfi_model_$(ARCH).c: $(SAIL_RVFI_SRCS) model/main.sail Makefile.old
mkdir -p generated_definitions/c
$(SAIL) $(rvfi_preserve_fns) $(SAIL_FLAGS) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_RVFI_SRCS) model/main.sail -o $(basename $@)
sed -e '/^[[:space:]]*$$/d' $@ > [email protected]
mv [email protected] $@

c_emulator/riscv_rvfi_$(ARCH): generated_definitions/c/riscv_rvfi_model_$(ARCH).c $(C_INCS) $(C_SRCS) $(SOFTFLOAT_LIBS) Makefile
c_emulator/riscv_rvfi_$(ARCH): generated_definitions/c/riscv_rvfi_model_$(ARCH).c $(C_INCS) $(C_SRCS) $(SOFTFLOAT_LIBS) Makefile.old
$(CC) -g $(C_WARNINGS) $(C_FLAGS) $< -DRVFI_DII $(C_SRCS) $(SAIL_LIB_DIR)/*.c $(C_LIBS_WRAPPED) -o $@

latex: $(SAIL_SRCS) Makefile
latex: $(SAIL_SRCS) Makefile.old
mkdir -p generated_definitions/latex
$(SAIL) -latex -latex_prefix sail -o generated_definitions/latex $(SAIL_SRCS)

Expand All @@ -299,13 +305,13 @@ endif

.PHONY: riscv_isa riscv_isa_build

generated_definitions/lem/$(ARCH)/riscv.lem: $(SAIL_SRCS) Makefile
generated_definitions/lem/$(ARCH)/riscv.lem: $(SAIL_SRCS) Makefile.old
mkdir -p generated_definitions/lem/$(ARCH) generated_definitions/isabelle/$(ARCH)
$(SAIL) $(SAIL_FLAGS) -lem -lem_output_dir generated_definitions/lem/$(ARCH) -isa_output_dir generated_definitions/isabelle/$(ARCH) -o riscv -lem_lib Riscv_extras -lem_lib Riscv_extras_fdext -lem_lib Mem_metadata $(SAIL_SRCS)
echo "declare {isabelle} rename field sync_exception_ext = sync_exception_ext_exception" >> generated_definitions/lem/$(ARCH)/riscv_types.lem

# sed -i isn't posix compliant, unfortunately
generated_definitions/isabelle/$(ARCH)/Riscv.thy: generated_definitions/isabelle/$(ARCH)/ROOT generated_definitions/lem/$(ARCH)/riscv.lem $(RISCV_EXTRAS_LEM) Makefile
generated_definitions/isabelle/$(ARCH)/Riscv.thy: generated_definitions/isabelle/$(ARCH)/ROOT generated_definitions/lem/$(ARCH)/riscv.lem $(RISCV_EXTRAS_LEM) Makefile.old
lem -wl ign -isa -outdir generated_definitions/isabelle/$(ARCH) -lib Sail=$(SAIL_SRC_DIR)/lem_interp -lib Sail=$(SAIL_SRC_DIR)/gen_lib \
$(RISCV_EXTRAS_LEM) \
generated_definitions/lem/$(ARCH)/riscv_types.lem \
Expand Down Expand Up @@ -348,7 +354,7 @@ riscv_coq: $(addprefix generated_definitions/coq/$(ARCH)/,riscv.v riscv_types.v)
riscv_coq_build: generated_definitions/coq/$(ARCH)/riscv.vo
.PHONY: riscv_coq riscv_coq_build

$(addprefix generated_definitions/coq/$(ARCH)/,riscv.v riscv_types.v): $(SAIL_COQ_SRCS) Makefile
$(addprefix generated_definitions/coq/$(ARCH)/,riscv.v riscv_types.v): $(SAIL_COQ_SRCS) Makefile.old
mkdir -p generated_definitions/coq/$(ARCH)
$(SAIL) $(SAIL_FLAGS) -dcoq_undef_axioms -coq -coq_output_dir generated_definitions/coq/$(ARCH) -o riscv -coq_lib riscv_extras -coq_lib mem_metadata $(SAIL_COQ_SRCS)

Expand Down
44 changes: 9 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,53 +47,38 @@ Getting started
Install [Sail](https://github.com/rems-project/sail/). On Linux you can download a [binary release](https://github.com/rems-project/sail/releases) (strongly recommended), or you can install from source [using opam](https://github.com/rems-project/sail/blob/sail2/INSTALL.md). Then:

```
$ make
$ ./build_simulators.sh
```

will build the simulator in `c_emulator/riscv_sim_RV64`.
will build the simulators in `build/c_emulator/riscv_sim_rv{32,64}d`.

If you get an error message saying `sail: unknown option '--require-version'.` it's because your Sail compiler is too old. You need version 0.18 or later.

One can build either the RV32 or the RV64 model by specifying
`ARCH=RV32` or `ARCH=RV64` on the `make` line, and using the matching
target suffix. RV64 is built by default, but the RV32 model can be
built using:
By default the RV32D and RV64D emulators are built, without RVFI-DII support.
You can see a complete list of targets by running `make help` in the
build directory, then e.g.

```
$ ARCH=RV32 make
$ make -C build riscv_sim_rv64f_rvfi
```

which creates the simulator in `c_emulator/riscv_sim_RV32`.

The Makefile targets `riscv_isa_build`, `riscv_coq_build`, and
`riscv_hol_build` invoke the respective prover to process the
definitions and produce the Isabelle model in
`generated_definitions/isabelle/RV64/Riscv.thy`, the Coq model in
`generated_definitions/coq/RV64/riscv.v`, or the HOL4 model in
`generated_definitions/hol4/RV64/riscvScript.sml` respectively.
We have tested Isabelle 2018, Coq 8.8.1, and HOL4
Kananaskis-12. When building these targets, please make sure the
corresponding prover libraries in the Sail directory
(`$SAIL_DIR/lib/$prover`) are up-to-date and built, e.g. by running
`make` in those directories.

### Executing test binaries

The simulator can be used to execute small test binaries.

```
$ ./c_emulator/riscv_sim_<arch> <elf-file>
$ build/c_emulator/riscv_sim_<arch> <elf-file>
```

A suite of RV32 and RV64 test programs derived from the
[`riscv-tests`](https://github.com/riscv/riscv-tests) test-suite is
included under [test/riscv-tests/](test/riscv-tests/). The test-suite
can be run using `test/run_tests.sh`.
can be run using `make test` or `ctest` in the build directory.

### Configuring platform options

Information on configuration options for the simulator is available from
`./c_emulator/riscv_sim_<arch> -h`.
`./riscv_sim_<arch> -h`.

Some useful options are: configuring whether misaligned accesses trap
(`--enable-misaligned`), and
Expand All @@ -104,10 +89,6 @@ whether page-table walks update PTE bits (`--enable-dirty-update`).
For booting operating system images, see the information under the
[os-boot/](os-boot/) subdirectory.

### Using development versions of Sail

Rarely, the release version of Sail may not meet your needs. This could happen if you need a bug fix or new feature not yet in the released Sail version, or you are actively working on Sail. In this case you can tell the `sail-riscv` `Makefile` to use a local copy of Sail by setting `SAIL_DIR` to the root of a checkout of the Sail repo when you invoke `make`. Alternatively, you can use `opam pin` to install Sail from a local checkout of the Sail repo as described in the Sail installation instructions.

Supported RISC-V ISA features
-----------------------------
#### The Sail specification currently captures the following ISA extensions and features:
Expand Down Expand Up @@ -330,13 +311,6 @@ Directory Structure
```
sail-riscv
- model // Sail specification modules
- generated_definitions // files generated by Sail, in RV32 and RV64 subdirectories
- c
- lem
- isabelle
- coq
- hol4
- latex
- prover_snapshots // snapshots of generated theorem prover definitions
- handwritten_support // prover support files
- c_emulator // supporting platform files for C emulator
Expand Down
16 changes: 5 additions & 11 deletions build_simulators.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
#!/bin/bash

function test_build () {
declare -i rc=0
eval $*
rc=$?
if [ $rc -ne 0 ]; then
echo "Failure to execute: $*"
exit $rc
fi
}
set -e

test_build make ARCH=RV32 c_emulator/riscv_sim_RV32
test_build make ARCH=RV64 c_emulator/riscv_sim_RV64
mkdir -p build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j2 csim
Loading

0 comments on commit f964407

Please sign in to comment.