diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 0905bdae2..77b90a82b 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -20,6 +20,9 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v4 + with: + # Git history is needed for `git describe` in the build to work. + fetch-depth: 0 - name: Install packages (Linux) if: startsWith(matrix.os, 'ubuntu-') diff --git a/CMakeLists.txt b/CMakeLists.txt index 875aba775..d575b07f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,8 @@ if(POLICY CMP0135) cmake_policy(SET CMP0135 OLD) endif() -project(sail_riscv) +include(cmake/project_version.cmake) +project(sail_riscv VERSION ${sail_riscv_cmake_version}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) diff --git a/c_emulator/CMakeLists.txt b/c_emulator/CMakeLists.txt index f3c072dab..a05177a02 100644 --- a/c_emulator/CMakeLists.txt +++ b/c_emulator/CMakeLists.txt @@ -1,3 +1,6 @@ +# make version available to emulator +configure_file(version.h.in version.h @ONLY) + set(EMULATOR_COMMON_SRCS riscv_callbacks.cpp riscv_callbacks.h @@ -16,6 +19,7 @@ set(EMULATOR_COMMON_SRCS riscv_softfloat.h config_utils.h config_utils.cpp + version.h ) add_executable(sail_riscv_sim @@ -51,6 +55,8 @@ target_include_directories(sail_riscv_sim "${CMAKE_CURRENT_SOURCE_DIR}" # So `riscv_sail.h` can find `sail_riscv_model.h`. "${CMAKE_BINARY_DIR}" + # So `riscv_sim.cpp` can find `version.h`. + "${CMAKE_CURRENT_BINARY_DIR}" ) # TODO: Enable warnings when we use the #include trick diff --git a/c_emulator/riscv_sim.cpp b/c_emulator/riscv_sim.cpp index bb894a40f..351db000d 100644 --- a/c_emulator/riscv_sim.cpp +++ b/c_emulator/riscv_sim.cpp @@ -27,6 +27,7 @@ #include "rvfi_dii.h" #include "default_config.h" #include "config_utils.h" +#include "version.h" enum { OPT_TRACE_OUTPUT = 1000, @@ -34,6 +35,7 @@ enum { OPT_VALIDATE_CONFIG, OPT_SAILCOV, OPT_ENABLE_EXPERIMENTAL_EXTENSIONS, + OPT_PRINT_VERSION, OPT_PRINT_DTS, OPT_PRINT_ISA, }; @@ -111,6 +113,7 @@ static struct option options[] = { {"rvfi-dii", required_argument, 0, 'r' }, {"help", no_argument, 0, 'h' }, {"config", required_argument, 0, 'c' }, + {"version", no_argument, 0, OPT_PRINT_VERSION }, {"print-default-config", no_argument, 0, OPT_PRINT_CONFIG }, {"validate-config", no_argument, 0, OPT_VALIDATE_CONFIG}, {"trace", optional_argument, 0, 'v' }, @@ -270,6 +273,9 @@ static int process_args(int argc, char **argv) } break; } + case OPT_PRINT_VERSION: + printf("%s\n", SAIL_RISCV_VERSION); + exit(0); case OPT_PRINT_CONFIG: printf("%s", DEFAULT_JSON); exit(0); diff --git a/c_emulator/version.h.in b/c_emulator/version.h.in new file mode 100644 index 000000000..f88677dab --- /dev/null +++ b/c_emulator/version.h.in @@ -0,0 +1,3 @@ +#pragma once + +#define SAIL_RISCV_VERSION "@sail_riscv_git_version@" diff --git a/cmake/project_version.cmake b/cmake/project_version.cmake new file mode 100644 index 000000000..366531025 --- /dev/null +++ b/cmake/project_version.cmake @@ -0,0 +1,49 @@ +# Set a default version for archive builds that do not have +# git history. Increment this appropriately at tag-and-release time. +set(archive_build_version "0.7.0") + +# Sets GIT_EXECUTABLE +find_package(Git) + +if (Git_FOUND) + # We could remove --tags if we started annotating the release tags. + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags HEAD + RESULT_VARIABLE git_error + OUTPUT_VARIABLE git_describe + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +else() + set(git_error TRUE) +endif() + +if (git_error) + message(STATUS "Failed to run git describe: ${git_error}") + + set(sail_riscv_git_version ${archive_build_version}) + set(sail_riscv_cmake_version ${archive_build_version}) +else() + # `git describe` cannot directly be used as a CMake VERSION argument + # for project() due the trailing commit hash failing CMake's semver + # format check. + # + # We could directly set PROJECT_VERSION to ${git_describe}, but that + # makes it incompatible with CPack in case we decide to use it. + # https://gitlab.kitware.com/cmake/cmake/-/issues/16716#note_956803 + # + # Instead, parse the version components for CMake and CPack, and use + # git_describe for the simulator --version. + + if (git_describe MATCHES "^([0-9]+)\\.([0-9]+)(-.*)?$") + set(v_major ${CMAKE_MATCH_1}) + set(v_minor ${CMAKE_MATCH_2}) + else() + message(FATAL_ERROR "Cannot parse git describe output: ${git_describe}") + endif() + + set(sail_riscv_git_version ${git_describe}) + set(sail_riscv_cmake_version "${v_major}.${v_minor}") +endif() + +# Log versions in the build log. +message(STATUS "Building versions: ${sail_riscv_git_version} (git), ${sail_riscv_cmake_version} (cmake).")