Skip to content

Commit

Permalink
Update for Clang
Browse files Browse the repository at this point in the history
 - Correct test cases for clang vs gcc
 - Add documentation for each project setup
  • Loading branch information
ahfriedman committed Jan 2, 2025
1 parent 8cc1d23 commit 0789b91
Show file tree
Hide file tree
Showing 45 changed files with 13,019 additions and 259 deletions.
10 changes: 5 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,32 @@ include(platform_settings) # Platform specific variables

add_subdirectory(src bin)

set (CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR})
install(
TARGETS
bismuthc
DESTINATION install
DESTINATION bin
)
install(
TARGETS
bismuth_runtime_archive
DESTINATION install/build/bin/runtime
DESTINATION bin/build/bin/runtime
)
install(
FILES
./bdwgc/libgc.a
./bdwgc/libgccpp.a
DESTINATION install
DESTINATION bin
)
install(
DIRECTORY
bsl
DESTINATION install
DESTINATION bin
FILES_MATCHING PATTERN "*.bismuth"
)

# include(Install)


### Testing with CTEST
enable_testing()

Expand Down
28 changes: 2 additions & 26 deletions DockerSetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ docker pull ahfriedman/cs544-cs4533-docker


```sh
docker run -it -v <location of repository>:/home/shared ahfriedman/cs544-cs4533-docker
source ./docker.sh
```

Once you have run the docker image with the shared folder, you should be prompted with a terminal. The terminal will start in the working directory of /home/. The project files (the shared folder) is located at /home/shared.
Expand All @@ -32,32 +32,8 @@ The first time you open the project in the docker image, you'll want to do is co
```sh
cd /home
cp libantlr4-runtime.a shared/antlr/lib/
cd shared
```

## Step 3. Build the code

Once in the `/home/shared` directory (assuming that it is also the top-level directory of your project), running `./makeBuild.sh` will build the codebase. In very rare circumstances (ie, a change to the docker image's libraries) you may have to delete previously built files (`rm -rf ./build`) prior to running `./makeBuild.sh`

## Step 3. Running tests

From the `/home/shared` directory, running `./runTests.sh` will run all the test cases.

## Step 4. Running a specific file

From `/home/shared`, running `./tester.sh <.bismuth file without extension>` will compile the program and run it (if compiling was successful).

For example, to run `./programs/example.bismuth`, one could run the command `./tester.sh ./programs/example` .

## Step 5. Generating code coverage
*Note: This process may take a while to run*

From the `/home/shared` directory, running `./coverage.sh` will:
1. Delete the `./cov` folder
2. Build the code into the `./cov` folder
3. Run all tests *(Note: all tests must pass for coverage to generate!)*
4. Output html files displaying code coverage to `./cov/coverage` *(Note: you may have to run `sudo chown -R $USER ./cov` from a terminal on your host to be able to view the files in a browser)*

You can then `cd /home/shared` and proceed with the rest of the development steps in the README file. **NOTE: You will have to cd into the `/home/shared` folder each time you start the image.


# Common Issues
Expand Down
59 changes: 54 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,64 @@
Implementation of the [bismuth](https://bismuth-lang.org) programming language.


## Prerequisites
## Step 1: Setup

* The project's [docker image](https://github.com/ahfriedman/cs544-cs4533-docker)
* OR an equivalent llvm-12 environment (not recommended)
Most dependencies for compiling and running Bismuth are automatically handled via the
CMake build process; however, there are a few steps that need to be taken manually to
get up and running so that CMake can handle the rest. Currently, the options are:
1. (Recommended) The project's [docker image](https://github.com/bismuthlang/bismuth-dev-docker)
2. The project's nix flake (limited support for testing + debugging)
3. An equivalent llvm-19 environment (not recommended)

### Docker Setup
The instructions for getting started with the Bismuth development image can be found in
[DockerSetup.md](./DockerSetup.md)

## Setting up, Running Code, Tests, & Coverage
### Nix Setup
A development shell for Bismuth can be created using Nix. This has been
tested with both Nix package manager standalone (v2.23.3+) and NixOS (v24.05+).
Running `nix develop` in the top level directory of this project will automatically setup everything
for you and leave your shell in an environment where Bismuth can be compiled.

### Manual Setup
Manually setting up your computer's environment to compile Bismuth is not recommended.
The main challenge with such an approach is that various different C/C++ compilers are
not easily interchangeable (i.e., if you use one compiler for one component of a project,
you tend to need to use the same compiler for all other portions of the project).
For Bismuth, this means that the LLVM IR dev library, ANTLR library, and the Bismuth source code
all need to be compiled with the same compiler. The challenge, however, is that LLVM is typically pre-packaged and
installed system-wide. As such, you'll need to use the same compiler for Bismuth as whatever was used to pre-package
LLVM. For systems using `apt` (Debian, Ubuntu, etc), this means that you'll typically need to use Clang despite
the OS defaulting your C and C++ compiler to GCC (hence, the docker image and nix flake to help
ensure no environment conflicts). If you do wish to proceed with a manual setup, the Docker file and nix flake
should be a great starting place for seeing what dependencies you'll need and how to configure your environment.



## Step 2: Build the code
Running `./makeBuild.sh` will build the codebase. In very rare circumstances (ie, a change to the docker image's libraries) you may have to delete previously built files (`rm -rf ./build`) prior to running `./makeBuild.sh`

## Step 3. Running tests

Running `./runTests.sh` will run all the test cases and print a report of the successes and failures.

## Step 4. Compiling a Bismuth program

Running `./tester.sh <.bismuth file without extension>` will compile the program and run it (if compiling was successful).

For example, to run `./programs/example.bismuth`, one could run the command `./tester.sh ./programs/example`.

To compile a program with the Bismuth standard library, use `./compileBSL.sh` instead of `./tester.sh`.

## Step 5. Generating code coverage
*Note: This process may take a while to run*

Running `./coverage.sh` will:
1. Delete the `./cov` folder
2. Build the code into the `./cov` folder
3. Run all tests *(Note: all tests must pass for coverage to generate!)*
4. Output html files displaying code coverage to `./cov/coverage` *(Note: you may have to run `sudo chown -R $USER ./cov` from a terminal on your host to be able to view the files in a browser)*

Instructions for how to set up the repository using docker can be found in [DockerSetup.md](./DockerSetup.md). While it is possible to get the code running without docker, the process is much more involved and fairly system dependent. In addition, without docker, test cases may fail to run as they expect the `/programs` directory to be located in `/home/shared/`.



Expand Down
Binary file modified antlr/lib/libantlr4-runtime.a
Binary file not shown.
41 changes: 41 additions & 0 deletions cmake/CPM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors

# Lines 5--21 are from the below link (see their license);
# This heuristic allows us to pull CPM from nix locally or
# download it when we don't have CPM installed and are thus outside of a
# nix build.
# https://github.com/OlivierLDff/QOlm/blob/4aad491596987c2acf7be06e880173c27bab8a51/cmake/CPM.cmake
message(STATUS "Looking for local CPM.cmake")
find_file(CPM_LOCAL_FILE
CPM.cmake
PATH_SUFFIXES share/cpm/
)

if(EXISTS ${CPM_LOCAL_FILE})
message(STATUS "Using local CPM.cmake: ${CPM_LOCAL_FILE}")
include(${CPM_LOCAL_FILE})
return()
endif()

set(CPM_DOWNLOAD_VERSION 0.40.4)
set(CPM_HASH_SUM "67dcc1deb6e12a2f0705647ccc5f7023e3d15746b944e14352b82373e09b8a0a")

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()

# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)

file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)

include(${CPM_DOWNLOAD_LOCATION})
26 changes: 17 additions & 9 deletions cmake/Testing.cmake
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
include(FetchContent)
FetchContent_Declare (
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.3.0
set(CPM_USE_LOCAL_PACKAGES ON)
message(STATUS "Catch2?: $ENV{Catch2_SOURCE_DIR}")
# CPMAddPackage("gh:catchorg/Catch2@3.7.1")
CPMAddPackage(
NAME Catch2
GITHUB_REPOSITORY catchorg/Catch2
VERSION 3.7.1
)

FetchContent_MakeAvailable(Catch2)
if(DEFINED ENV{Catch2_SOURCE_DIR})
include("$ENV{Catch2_SOURCE_DIR}/extras/Catch.cmake")
list(APPEND CMAKE_MODULE_PATH $ENV{catch2_SOURCE_DIR}/extras)
else()
message(STATUS "Catch2?: ${Catch2_SOURCE_DIR}")
include("${Catch2_SOURCE_DIR}/extras/Catch.cmake")
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
endif()

include(CTest)
include(Catch)
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
# include(Catch)


# Comment out the next line to change the command line options
# See: https://github.com/catchorg/Catch2/blob/devel/docs/command-line.md
Expand Down
34 changes: 22 additions & 12 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
};

outputs = { self, nixpkgs }:
outputs = { self, nixpkgs, ... }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
llvmPkgs = nixpkgs.legacyPackages.${system}.pkgsLLVM;
llvm = pkgs.llvmPackages_19;
libllvm = llvm.libllvm.override {
pkgsBuildBuild.targetPackages.stdenv.cc = pkgs.llvm.libcxxClang;
Expand All @@ -17,26 +18,35 @@
# inherit (pkgs.llvmPackages_19) bintools;
# });
in {
devShell.${system} = pkgs.stdenv.mkDerivation {
# devShell.${system}
#packages.${system}.default
# devShell.${system}
packages.${system}.default = pkgs.stdenv.mkDerivation {
name = "bismuth";
nativeBuildInputs = [
# pkgs.clang-tools_12
src = self;

out = [ "install" ];


Catch2_SOURCE_DIR = "${pkgs.catch2_3.src}";

nativeBuildInputs = [
pkgs.cmake
pkgs.cpm-cmake
pkgs.pkg-config
pkgs.jdk17
pkgs.unzip
];
buildInputs = [
# pkgs.llvmPackages_19.libcxxClang
pkgs.catch2_3
pkgs.lcov
];
buildInputs = [
pkgs.git
pkgs.llvmPackages_19.libllvm
pkgs.libossp_uuid
pkgs.libxml2.dev
pkgs.zlib.static
pkgs.libffi
]; # ++ (pkgs.lib.optional pkgs.stdenv.isLinux [ pkgs.glibc.dev pkgs.glibc.static ]);
# LLVM_SYS_190_PREFIX = "${pkgs.llvmPackages_19.llvm.dev}";
# LD_LIBRARY_PATH = "${llvmEnv.cc.cc.lib}/lib";
pkgs.libffi
];
};
};

}
14 changes: 7 additions & 7 deletions programs/TArray.bismuth.expected.ll
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,9 @@ entry:
br label %loop-cond

loop-cond: ; preds = %loop, %entry
%2 = load i32, ptr %len, align 4
%3 = load i32, ptr %idx, align 4
%4 = icmp slt i32 %3, %2
%2 = load i32, ptr %idx, align 4
%3 = load i32, ptr %len, align 4
%4 = icmp slt i32 %2, %3
br i1 %4, label %loop, label %rest

loop: ; preds = %loop-cond
Expand Down Expand Up @@ -402,11 +402,11 @@ then: ; preds = %entry
br label %if-cont

else: ; preds = %entry
%6 = load ptr, ptr %m, align 8
%7 = load ptr, ptr %v, align 8
%8 = load i32, ptr %7, align 4
%6 = load ptr, ptr %v, align 8
%7 = load i32, ptr %6, align 4
%8 = load ptr, ptr %m, align 8
%9 = call ptr @GC_malloc(i64 8)
store i32 %8, ptr %9, align 4
store i32 %7, ptr %9, align 4
%10 = load ptr, ptr %m, align 8
%11 = call %Unit @_address_map_put(ptr %10, ptr %2, ptr %9)
br label %if-cont
Expand Down
22 changes: 11 additions & 11 deletions programs/TArray2.bismuth.expected.ll
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,9 @@ entry:
br label %loop-cond

loop-cond: ; preds = %loop, %entry
%2 = load i32, ptr %len, align 4
%3 = load i32, ptr %idx, align 4
%4 = icmp slt i32 %3, %2
%2 = load i32, ptr %idx, align 4
%3 = load i32, ptr %len, align 4
%4 = icmp slt i32 %2, %3
br i1 %4, label %loop, label %rest

loop: ; preds = %loop-cond
Expand Down Expand Up @@ -411,10 +411,10 @@ then: ; preds = %entry
br label %if-cont

else: ; preds = %entry
%6 = load ptr, ptr %m, align 8
%7 = load ptr, ptr %v, align 8
%8 = load ptr, ptr %7, align 8
%9 = call ptr @"_clone_Box<int>"(ptr %8, ptr %6)
%6 = load ptr, ptr %v, align 8
%7 = load ptr, ptr %6, align 8
%8 = load ptr, ptr %m, align 8
%9 = call ptr @"_clone_Box<int>"(ptr %7, ptr %8)
%10 = call ptr @GC_malloc(i64 8)
store ptr %9, ptr %10, align 8
%11 = load ptr, ptr %m, align 8
Expand Down Expand Up @@ -444,11 +444,11 @@ then: ; preds = %entry
br label %if-cont

else: ; preds = %entry
%6 = load ptr, ptr %m, align 8
%7 = load ptr, ptr %v, align 8
%8 = load i32, ptr %7, align 4
%6 = load ptr, ptr %v, align 8
%7 = load i32, ptr %6, align 4
%8 = load ptr, ptr %m, align 8
%9 = call ptr @GC_malloc(i64 8)
store i32 %8, ptr %9, align 4
store i32 %7, ptr %9, align 4
%10 = load ptr, ptr %m, align 8
%11 = call %Unit @_address_map_put(ptr %10, ptr %2, ptr %9)
br label %if-cont
Expand Down
16 changes: 8 additions & 8 deletions programs/TBox.bismuth.expected.ll
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ then: ; preds = %entry
br label %if-cont

else: ; preds = %entry
%6 = load ptr, ptr %m, align 8
%7 = load ptr, ptr %v, align 8
%8 = load ptr, ptr %7, align 8
%9 = call ptr @"_clone_Box<int>"(ptr %8, ptr %6)
%6 = load ptr, ptr %v, align 8
%7 = load ptr, ptr %6, align 8
%8 = load ptr, ptr %m, align 8
%9 = call ptr @"_clone_Box<int>"(ptr %7, ptr %8)
%10 = call ptr @GC_malloc(i64 8)
store ptr %9, ptr %10, align 8
%11 = load ptr, ptr %m, align 8
Expand Down Expand Up @@ -199,11 +199,11 @@ then: ; preds = %entry
br label %if-cont

else: ; preds = %entry
%6 = load ptr, ptr %m, align 8
%7 = load ptr, ptr %v, align 8
%8 = load i32, ptr %7, align 4
%6 = load ptr, ptr %v, align 8
%7 = load i32, ptr %6, align 4
%8 = load ptr, ptr %m, align 8
%9 = call ptr @GC_malloc(i64 8)
store i32 %8, ptr %9, align 4
store i32 %7, ptr %9, align 4
%10 = load ptr, ptr %m, align 8
%11 = call %Unit @_address_map_put(ptr %10, ptr %2, ptr %9)
br label %if-cont
Expand Down
Loading

0 comments on commit 0789b91

Please sign in to comment.