<<

Masaryk University Faculty of Informatics

Procedurally Generated Landscape as a Visualization of # Code

Bachelor’ Thesis

Adam Štěpánek

Brno, Spring 2020 This is where a copy of the official signed thesis assignment and a copy ofthe Statement of an Author is located in the printed version of the document. Declaration

Hereby I declare that this paper is my original authorial work, which I have worked out on my own. All sources, references, and literature used or excerpted during elaboration of this work are properly cited and listed in complete reference to the due source.

Adam Štěpánek

Advisor: Mgr. David Kuťák

i Acknowledgements

I thank my advisor, Mgr. David Kuťák, for patience and invaluable feedback. I also thank my colleagues at Riganti for their input and for letting me use their hardware to deploy Helveg. Last but not least, I thank my &D group for their encouragement, and everyone who supported me, while working on this project, in any way.

ii Abstract

Software visualization helps programmers better understand code through visual means. This thesis presents a visualization tool, named Helveg, that maps the structure of C# code, along with diagnostics, onto a procedurally generated landscape. This is achieved in three stages (code analysis, landscape genera- tion, and rendering), which the thesis describes in detail. Presented are also case studies involving open-source codebases. Results of these case studies show that Helveg can be used to visualize the structure of a C# codebase in a visually appealing way. Also, analysis of these outputs helps to pinpoint the drawbacks of the current visualization thus providing ideas for future work.

iii Keywords software visualization, procedural generation, C#, , Vulkan, L-system, force-directed graph drawing, .NET Core Tool

iv Contents

1 Introduction 1

2 Related Work 2 2.1 Graphs and Diagrams ...... 3 2.2 Code Cities ...... 5 2.3 Islands ...... 7

3 Overview of Helveg 9 3.1 Requirements ...... 9 3.2 The Metaphor ...... 11 3.3 Pipeline ...... 15 3.4 Architecture ...... 16 3.5 The Debug Command ...... 17

4 Code Analysis 19 4.1 A Brief History of .NET ...... 19 4.2 Project Loading ...... 20 4.3 Semantic Model ...... 21

5 Landscape Generation 24 5.1 Layout ...... 24 5.2 Terrain ...... 28 5.3 Structures ...... 30 5.3.1 L-systems ...... 30 5.3.2 Spruce Trees ...... 32

6 Rendering 34 6.1 Layers of Vku ...... 34 6.2 WorldRender ...... 36 6.3 The Camera ...... 38

7 Distribution 39 7.1 A .NET Core Tool ...... 39 7.2 Continuous Deployment ...... 40

8 Case Studies 42

v 8.1 Sample Projects ...... 42 8.2 DotVVM Academy ...... 45 8.3 Roslyn ...... 46

9 Conclusion 47

Bibliography 49

A Electronic Attachments 56

B Build Instructions 57

vi List of Tables

4.1 Weights of type relationships. 23 5.1 Turtle drawing commands. 31 5.2 Additional symbols of the spruce L-system. 32 6.1 Keyboard control scheme. 38

vii List of Figures

2.1 Visualizations with different levels of abstraction. 2 2.2 A flame graph [12]. 4 2.3 A Gource visualization of a repository log [14]. 4 2.4 The software galaxy of Go packages [16]. 5 2.5 An isolated district of a code city [18]. 6 2.6 IslandViz [4]. 7 3.1 The mapping from C# code to a landscape. 12 3.2 The effects of compiler errors and warnings. 14 3.3 The Helveg pipeline. 15 3.4 Helveg’s architecture viewed through the file system. 16 3.5 Invocation of a debug subcommand. 17 3.6 Sample outputs of debug subcommands. 17 4.1 The layers of Roslyn . 21 4.2 A visualizer of Roslyn’s syntax trees [39]. 22 5.1 The simulation of gravity in an FDG step. 25 5.2 Attractive and repulsive forces of FDG. 26 5.3 Computation of adaptive speed in an iteration of FDG. 27 5.4 The heightmap of an island. 28 5.5 The terrain of an island. 29 5.6 Orientation of Helveg’s “turtle”. 32 5.7 L-system production rules for the growing of spruce trees. 33 6.1 The layers of Vku’s framework. 35 6.2 The graphics pipeline [47]. 36 7.1 Typical Helveg installation process. 39 8.1 A visualization of a tidy project. 42 8.2 A project that breaks coding conventions. 43 8.3 A project with compiler errors. 44 8.4 A detail of the visualization of DotVVM Academy. 45 8.5 The islands of DotVVM Academy. 46 9.1 Helveg’s visualization of its own C# codebase. 47 A.1 Notable files and directories of the Helveg repository. 56

viii 1 Introduction

Programming is not merely about writing code. A large portion of a programmer’s time is spent trying to understand the structure of the program. Therefore, anything that helps the programmer understand code faster and better is a welcome addition to their toolbox. One way to aid code comprehension is through software visualization. The field of software visualization concerns itself with giving in- sights into programs that would otherwise be difficult to gain just by reading the . Software visualization tools convey information about, for instance, process memory, program performance, or code structure. The subject of this work is Helveg, a tool that visualizes the struc- ture of a C# codebase as well as errors and warnings reported by the C# compiler. Helveg maps units of code structure, such as classes and MSBuild projects, to objects found in a natural landscape like trees and islands. The purpose of this metaphor is to make Helveg not only informative but also compelling. At its core, Helveg is a cross-platform console application, which uses the Vulkan graphics API1 to render the landscape. The following chapter describes the field of software visualization and existing tools. Chapter 3 contains an overview of Helveg, which is later described in detail in Chapters 4 through 7 focusing on the code analysis, landscape generation, rendering, and distribution aspects of the tool, respectively. Case studies of Helveg’s outputs are contained within Chapter 8. The thesis concludes in Chapter 9 with a summary and discussion of future work.

1. Application Programming Interface

1 2 Related Work

The purpose of visualization is to gain insight into complex data by presenting it in a more understandable form. Since people are used to the processing of visual inputs, visualization strives to present infor- mation in an aesthetically pleasing manner that is easy to understand. Good visualization seeks to be both expressive — present only the data and nothing more — and effective — be interpretable at a glance and quickly rendered. As a subfield of visualization, software visualization deals with presenting various aspects of software artifacts (such as source code or compiled binaries) through visual means. It helps programmers un- derstand the static structure of the source code as well as the dynamic behavior of the compiled program. Existing approaches to software visualization differ in many char- acteristics. The input data is generally obtained either through static analysis of a software artifact or collected during a particular execu- tion of the analyzed program. Some approaches also operate on a higher level of abstraction than others. They are more “aware” of the program. Figure 2.1 illustrates this concept. On the left is the htop program whose CPU1 meters measure the amount of computational work currently performed, on the right is an animation of sorting algo- rithms. While both visualize the execution of programs, the animation is more “aware” of what the program is doing.

(a) The htop program. (b) An animation of sorts [1].

Figure 2.1: Visualizations with different levels of abstraction.

1. Central Processing Unit

2 2. Related Work

The format of the resulting visualization is a differentiating factor as well. A software visualization tool might present 2D or 3D graph- ics, provide multiple views, or be in virtual reality (VR) [2, 3, 4]. A visualization can also be passive (once generated, it does not change), or interactive (allowing the user to change its parameters). A tool can implement a software visualization metaphor, which is a mapping between the analyzed program and an environment that should feel intuitive to the user. The rest of this chapter deals with several metaphors that are related to Helveg. However, software visualization is a broad field, and there are approaches besides those mentioned in this chapter. Hence, I recommend An Overview of 3D Software Visualization by Teyseyre et al. [5].

2.1 Graphs and Diagrams

While graphs and diagrams are abstract and usually lack a real-life metaphor, they are omnipresent and often underlie more “metaphori- cal” approaches. They are also an old method of software visualiza- tion predating themselves, for example, in a diagram by [6]. There are guidelines on how to draw diagrams of software. Chen’s Entity-Relationship Model (ER model) and the class diagrams of the Unified Modelling Language (UML) are among the more popular ones [7, 8]. Both focus on data modelling, but whereas the ER model is used in database design, the UML class diagrams play their role in object-oriented programming. Both are also frequently incorpo- rated into IDEs2. For instance, SQL Server Management Studio has its Database Designer, which displays diagrams similar to the ER model, Visual Studio has its Class Designer, and IntelliJ Idea has a UML plu- gin [9, 10, 11]. While the ER model and the UML class diagrams capture static structural information, other diagrams focus on the dynamic behavior of programs instead. For instance, the Flame Graph shown in Fig- ure 2.2 is a flame-like visualization of function calls and the time spent in them [12]. Naturally, it is useful for profiling performance.

2. Integrated Development Environment

3 2. Related Work

It also integrates nicely with existing profilers such as ’s PerfView [13].

Figure 2.2: A flame graph [12].

A visualization can also entertain. That is the case of Gource. Gource is a visualizer of code repositories with version control. It displays an animated graph, as depicted in Figure 2.3, illustrating the evolution of a code repository over time [14]. The files and directories of the code repository are represented by the nodes and edges of the graph, respectively. Videos showing the history of software projects like the kernel are a proof of its entertainment value [15].

Figure 2.3: A Gource visualization of a repository log [14].

4 2. Related Work

Similarly to Gource, Kashcha’s Software Galaxies are more of a toy than a practical a tool. Figure 2.4 shows its visualization of the de- pendencies between Go packages. This visualization is implemented using a force-directed graph drawing and the WebGL API, which makes it easily accessible from a web browser [16].

Figure 2.4: The software galaxy of Go packages [16].

In summary, graphs and diagrams are versatile, cheap to gener- ate, undemanding in terms of hardware, and can both inform and entertain. However, they do not take advantage of the activities and environments that humans encounter daily, which is a virtue of alter- native approaches.

2.2 Code Cities

The city metaphor refers to a 3D software visualization approach showing aspects of analyzed programs as a city with districts and buildings of different sizes. One of the first implementations of this metaphor is Software World by Knight and Munro [17]. This tools transforms Java classes into dis- tricts, and methods within those classes into buildings. The height of a building corresponds to the number of lines of code within the respective method. Even this early implementation targeted VR. Often referenced is also CodeCity by Wettel et al. [18, 3, 2, 19]. Fig- ure 2.5 shows an isolated district that CodeCity generated. The district represents a package whose classes map to the buildings. Compared

5 2. Related Work

to Software World, the height of a building is not determined by mere lines of code but by the number of methods inside the class. Thus, CodeCity must “understand” what a method is and therefore it works on a higher level of abstraction than Software World.

Figure 2.5: An isolated district of a code city [18].

From the dynamic side of software analysis comes SynchroVis, a tool by Waller et al. visualizing program traces for concurrency analysis [3]. It maps classes to buildings as well. However, the size of a building depends on the number of recorded instances of the class. Furthermore, Khaloo et al. developed Code Park, which is inspired in part by CodeCity [19]. It is a VR environment where each room represents a C# class with walls covered in source code as if it were wallpaper. The size of these rooms depends on the size of the class. It is one of the few tools that supports the C# language. The city metaphor is a powerful way to visualize both static and dynamic aspects of programs. It scales well because it uses three dimensions and the familiar setting of a city. However, there is no implementation of this analogy that integrates itself into an IDE or an SDK3 or does not require specialized VR hardware. For a more comprehensive overview of this approach, I suggest Jeffery’s The City Metaphor in Software Visualization [20].

3. Software Development Kit

6 2. Related Work 2.3 Islands

Cities are only one example of a landscape used as software visual- ization metaphor. Other landscapes, such as islands, are a subject of research as well. Kuhn et al. proposed a consistent layout for software visualization based on a cartography metaphor and implemented it in a proof- of-concept tool SoftwareCartographer [2]. Their approach relies on Latent Semantic Indexing (LSI), a method used in natural language processing. The LSI method is, theoretically, language agnostic. It does not require an understanding of the analyzed code or access to a com- piler, while still producing meaningful output. However, it also puts less value on significant relationships such as type inheritance and composition since it does not “know” what they are.

Figure 2.6: IslandViz [4].

7 2. Related Work

Schreiber and Misiak chose an island metaphor for their software visualization tool IslandViz [4]. As shown in Figure 2.6, this tool turns an OSGi bundle4 into an island with cargo containers in place of its dependencies. Java packages from inside the bundle are depicted as regions of the island. Buildings in each region represent Java classes. IslandViz utilizes a force-directed graph algorithm to create a lay- out of the bundle-islands in the ocean of software. The distances be- tween islands are shorter when there is a dependency between them. However, proximity of buildings signifies only what package a class belongs to. Islands are a promising but not very well explored metaphor of soft- ware visualization. There is currently no tool supporting this analogy that one could download and readily use. IslandViz is, nevertheless, the closest tool to Helveg there is. As described in Section 3.2, Helveg even borrows some ideas from IslandViz.

4. A group of Java components.

8 3 Overview of Helveg

Helveg is a software visualization tool that turns C# source code into a 3D landscape. It strives to fulfil a set of requirements based on the thesis assignment and my personal preferences. Furthermore, it implements a software visualization metaphor inspired by natural landscapes with a pipeline written in both C# and C++. It also has features that are unrelated to the main pipeline but are useful for . The name comes from Norse mythology where Helveg is the road to Hel — the underworld [21]. The idea behind it is that the landscape of a problematic codebase should look rather hellish, thus at least for some codebases Helveg really is the road to Hell.

3.1 Requirements

Helveg must satisfy the assignment of this thesis but it should also adhere to my personal beliefs about what makes a tool practical. Hence, the following list contains these requirements and beliefs along with a description of the consequences they had on Helveg’s development. Visualized information Helveg must visualize the structure of C# projects: the types they contain, their dependencies, and their compiler diagnos- tics. Additionally, the visualization should include violations of coding conventions if the project follows any. To accomplish this, Helveg maps projects to islands, types to vari- ous structures, and compiler diagnostics to intuitively damaging effects such as a fire. Cross-platform support A .NET developer can program in C# on any major . Therefore, Helveg should support as many operating systems as possible so that it does not limit its user base. As a consequence, Helveg depends only on APIs and libraries that are cross-platform. It also relies on the .NET Core SDK as a means of distribution since its tool model is platform-independent.

9 3. Overview of Helveg

Consistency The transformation from the code to the landscape should be consistent. The visualization of a codebase should not change unless that codebase changes. Purely cosmetic changes like a change in indentation should not influence Helveg’s output at all. Thus, Helveg bases the seeds of pseudo-random number gener- ators on the names of projects and types. In places where their order is significant, Helveg orders projects and types alphabeti- cally.

Visual appeal The better-looking the environment, the more time the user spends in it and therefore learns more about the structure of the codebase. Also, good-looking environments make for eye- catching pictures, which are more likely to be shared with col- leagues and thus attract more users to the tool. Helveg’s world is composed of colored blocks. While this was my artistic choice, it also simplifies landscape generation and rendering.

Ease of use The target audience of Helveg is .NET developers. Still, the tool should not require any explanation to be used. For this reason, Helveg does not have any mandatory arguments. Instead, it tries to figure out what code it should visualize based on its current working directory.

Convenient distribution Many of the tools mentioned in Chapter 2 are not easily obtain- able. They are either abandoned, require manual build, or are a product of research and have never been made available. In order for anyone to use Helveg, it needs to be easy to install. The .NET Core Tool API allows for easy installation of command- line applications from the NuGet package platform and is thus an excellent fit for Helveg.

10 3. Overview of Helveg

Permissive license Helveg’s source code is licensed under the 3-Clause BSD License not only to fulfil requirements imposed on this thesis but also to support extension and further development [22]. The code repos- itory is available at https://gitlab.com/helveg/helveg/.

3.2 The Metaphor

As stated in Chapter 2, a software visualization metaphor is a mapping between software and an environment that is familiar to humans. In the case of Helveg, this environment is a group of islands scattered with trees, cabins, meadows, and other structures. Additionally, com- piler errors and warnings manifest as fire and damage to the structure they are related to. This metaphor is close to that of IslandViz, mentioned in Section 2.3. In fact, Helveg borrows the idea of mapping external dependencies to cargo containers directly from IslandViz. It also uses a similar algo- rithm to arrange the islands in the ocean. However, Helveg puts related types closer together and thus gives more meaning to their position than IslandViz, which regards all regions of an island as equal [4]. Additionally, Helveg captures type- related details such as their kind, and whether they can be compiled. What follows is a complete list of the mappings between C# and natural phenomena. This list is accompanied by Figure 3.1 showing individual mappings.

Islands A Visual Studio solution is a group of MSBuild projects, which are themselves groups of C# source files. In Helveg’s landscape, the solution is the ocean, and the projects are islands. Bridges Bridges connect projects if there is a dependency between them. The arrow-like pattern on the bridge shows the direction from the dependent project, whose configuration file contains the ProjectReference, to the project it references.

11 3. Overview of Helveg

(a) Projects → islands (b) Dependencies → bridges

(c) Packages → cargo (d) Classes → trees

() Structs → cabins (f) Enums → meadows

(g) Delegates → signposts (h) Interfaces → foundations

Figure 3.1: The mapping from C# code to a landscape.

12 3. Overview of Helveg

Trees C# classes are represented by spruce trees. This is because classes can form inheritance hierarchies, which are, to put it another way, acyclic graphs — trees. The number of members in a class determines the size of its tree. In fact, the number of branches growing from the trunk is equal to the member count. Addi- tionally, classes with a common ancestor1, share the tint of their needles. Cabins C# value types (structs) cannot inherit from other classes or structs. Still, structs are conceptually close to classes and there- fore are represented as log cabins. The number of the vertically stacked logs is equal to the member count of its struct. Signposts Delegates are references to methods with a specific return type and parameter list. In a way, they are analogous to C function pointers, and so it is fitting to map them to signposts. The number of arrows on a signpost is equal to the number of parameters of its delegate type plus one, unless the return type is void. Meadows Enums are collections of named integral constants. Often they “decorate” classes and structs. Helveg depicts them as meadows with flowers. Construction sites Interfaces are represented by, what looks like, a foundation of a building or a square-shaped construction site. The side of the square is equal to the square root of the number of members the interface declares. Cargo Dependencies on external packages are visualized as cargo con- tainers stacked on a platform next to the project-island that requires them.

1. Other than System.Object since that is an ancestor of all classes [23].

13 3. Overview of Helveg

Fire and damage Figure 3.2 shows what happens to types if they contain compiler errors. Helveg sets them on fire. If the compiler issues a mere warning, the respective structure only appears damaged: trees miss needles, cabins miss roofs, and meadows miss flower petals.

(a) Error → fire

(b) Warning → damage

Figure 3.2: The effects of compiler errors and warnings.

14 3. Overview of Helveg 3.3 Pipeline

Provided that Helveg finds a codebase to analyze, it executes a pipeline with three stages: code analysis, landscape generation, and rendering. As can be seen in Figure 3.3, each stage is divided into further steps. First, Helveg loads and analyzes one or more MSBuild projects. It obtains data from the C# compiler and transforms it to its internal representation, which can be cached.

C# Codebase Structure Mesh Generation Simplification

Terrain Project Loading Buffer Creation Generation

Vulkan Data Trans- Layout formation Pipelines

Landscape Code Analysis Rendering Generation

Explorable Landscape

Figure 3.3: The Helveg pipeline.

After that, Helveg applies force-directed graph to com- pute the layout of islands and structures. Then it generates a heightmap2 and a terrain made of blocks. Moreover, for every analyzed type a structure is placed onto the procedural terrain. In the final stage, the renderer converts each chunk of the proce- dural world into a mesh and copies it into buffers in GPU3 memory.

2. A two-dimensional array of heights at discrete points. 3.

15 3. Overview of Helveg

There, Vulkan pipelines created for this purpose render the meshes onto the screen. A chapter of this thesis is devoted to each of the three stages: code analysis is described in Chapter 4, landscape generation is covered in Chapter 5, and Chapter 6 is devoted to rendering.

3.4 Architecture

The two technologies at the core of Helveg are .NET Core (the C# runtime) and Vulkan (a low-level graphics API). As a result, Helveg’s codebase is split between a code analyzer/landscape generator written in C# and a C++ renderer. Having a codebase that is a blend of C# and C++ code has its ad- vantages and disadvantages. On the one hand, the renderer is cleanly separated from the rest of the program with its interface defined in the interop header. On the other hand, it also leads to issues like C++ functions being visible to the C# application on Linux but not on Windows, and convoluted build configurations. ~/ helveg/ Analysis/ Analyze.cs Landscape/ Terrain.cs Render/ Serialization/ Program.cs vku/ world_render.hpp/

Figure 3.4: Helveg’s architecture viewed through the file system.

Despite the divide, there is a single entry point to Helveg’s pipeline and that is the Main method of the Program class. The rest of the C# code is divided between the Analysis, Landscape, Render, and Serialization namespaces. Unlike the C# side, the C++ renderer has a flat architecture. However, the Analyze, Terrain, and WorldRender classes contain most of the functionality. Figure 3.4 shows how the file organization copies this architecture.

16 3. Overview of Helveg 3.5 The Debug Command

Throughout Helveg’s development, features needed to be tested even though the pipeline was far from complete. This led to the inclusion of the debug command. Each feature test of the command can be invoked through a subcommand, as depicted in Figure 3.5. The SOURCE argument is a path to the analyzed codebase. It is optional since its default value is the current working directory.

helveg[SOURCE] debug

Figure 3.5: Invocation of a debug subcommand.

The triangle and cube subcommands display a single triangle and cube, respectively. They verify that the renderer can draw simple geometry to a newly opened window. Similarly, eades and fdg are related to the problem of arranging islands and structures. These subcommands show the Eades and FDG graph-drawing algorithms in real time, as depicted in Figure 3.6a. The implementation of these algorithms is the focus of Section 5.1.

(a) fdg (b) chunk

Figure 3.6: Sample outputs of debug subcommands.

17 3. Overview of Helveg

The chunk, opensimplex, and world subcommands test aspects of the landscape generator. For instance, chunk renders a cube composed of yellow and blue blocks, as depicted in Figure 3.6b, thus establishing that a chunk can be turned into a mesh and rendered. The rest of the debug commands bear names like tree, cabin, or cargo. They check that the landscape generator can construct struc- tures implementing the metaphor of Section 3.2 correctly. In summary, Helveg packs a set of feature tests, which are useful for debugging purposes. Moreover, commands like fdg can help under- stand the underlying algorithms. The complete list of these commands can be printed out using the ––help command-line option.

18 4 Code Analysis

To visualize C# code, Helveg first analyzes it and extracts information relevant to the visualization. Thus, the tool requires an abstraction over the C# language. Luckily, the .NET Compiler Platform (Roslyn) provides just that. Roslyn relies on MSBuild to handle other aspects of the build process such as locating source files. Therefore, Helveg depends on MSBuild as well.

4.1 A Brief History of .NET

The creation of the .NET Framework and the C# language has many causes. For instance, in 2000, a court forbid Microsoft to ship modified versions of Java [24, 25]. Microsoft also wanted to maintain a single runtime common to many programming languages, and to provide developer tools for the then-emerging web [26, 27]. .NET Framework and C# were first released in February 2002 to- gether with a version of Visual Studio [28]. In the following year, the Common Language Infrastructure (CLI) and the C# language were stan- dardized as ECMA 335 and ECMA 334, respectively [23, 29]. These specifications made it possible for the project, an open-source implementation of the CLI and C#, to emerge. Hereafter, there were two .NET runtimes: the Windows-only .NET Framework and the cross- platform Mono. In 2016, Microsoft announced .NET Core, a subset of .NET Framework for all major platforms [30]. Thus, the number of .NET runtimes increased to three. How is this relevant to Helveg? The three .NET platforms differ in their tooling and so considerable time would need to be spent to ensure that whether a piece of code targets Framework, Mono, or Core, it can be visualized. To visualize Framework code, Helveg would also have to be able to run on .NET Framework, which would prevent it from using new features that are available only on .NET Core. In the end, Helveg is Core-only. One cause of this is the chosen form of distribution, described in Chapter 7, because it ensures that .NET Core is already present on the user’s computer. The other reason is .NET 5, which is scheduled to release in November 2020. .NET 5 is supposed to deprecate .NET Framework, merge Mono with .NET Core

19 4. Code Analysis

as much as possible, and unify their tooling as well [31]. That makes spending time on the support of Framework and Mono projects diffi- cult to justify.

4.2 Project Loading

The Microsoft Build Engine (MSBuild) is a language-agnostic tool han- dling the build of a codebase. To use MSBuild, one writes or generates a project file. A project file is 1an XML document describing where the source code is, how to build it, its dependencies, and what to do with the outputs [32]. C# projects are declared in MSBuild project files with the .csproj file extension. There are, however, two different .csproj flavors collo- quially called the “old csproj” and the “new csproj”. The .NET Frame- work uses the old one, whereas the new, simplified format has been introduced with the release of .NET Core 1.1 [33]. Because C# projects are often grouped in Visual Studio Solutions, those should be consid- ered as well. Unfortunately, parsing the project files as XML is not enough to load a project. The differences between the two formats combined with the ability to reference other project files make it more convenient to use MSBuild’s API [34]. One way to access the MSBuild API is to depend on the family of MSBuild NuGet packages. However, that would cause the application to include its own copy of MSBuild, which is unnecessary because it is a part of the .NET Core SDK that installed Helveg in the first place. The pack-a-copy approach also does not work because the NuGet packages are not the whole SDK and so attempts to load projects fail because of missing dependencies. The recommended solution is to use MSBuildLocator to find an existing MSBuild installation instead [35]. In this scenario, the NuGet packages are still referenced as build dependencies but are not pack- aged together with the application. Ultimately, Helveg follows this recommendation and should thus be able to load any C# project that the SDK can build. Unfortunately, MSBuildLocator does not load all dependencies of the SDK, so Helveg

1. Extensible Markup Language

20 4. Code Analysis

is forced to reference them as NuGet packages [36]. Since there is no guarantee that Helveg references them all, some projects may fail to load. At this time, there is unfortunately no package that would combine all dependencies of the SDK. Nonetheless, some problems with project loading can be solved using the ––properties command- line option, which passes its values to MSBuild.

4.3 Semantic Model

Once a suitable MSBuild installation is acquired, a project or a solution can be loaded and analyzed by Roslyn. Roslyn replaces the original C# compiler2, which was written in C++ [38]. While that compiler was a black box, Roslyn is an open-source collection of APIs that are used to compile C# and build tools like Visual Studio. The APIs form two layers: the Compiler APIs and the Workspaces APIs [37].

Formatting Find References Code Generation ...

Workspaces Workspaces, Solutions, Projects, Documents APIs

Diagnostics Scripting ...

Compiler Binding and Syntax Trees Symbols Emit APIs Flow Analysis

Figure 4.1: The layers of Roslyn APIs.

As shown in Figure 4.1, the Compiler APIs allow access to data structures like the syntax tree, which is produced for each C# file. Syn- tax trees are made of syntax nodes, which are themselves composed of syntax tokens (terminals of the language grammar) and syntax trivia (whitespace, comments, and directives). Figure 4.2 shows the Syntax Visualizer, a tool provided by the Roslyn team to simplify manipulation with syntax trees [39].

2. Roslyn contains a .NET compiler (written in VB.NET) as well [37].

21 4. Code Analysis

Figure 4.2: A visualizer of Roslyn’s syntax trees [39].

For every file, Roslyn also creates a semantic model. A semantic model “knows” what symbols each node references, where a symbol represents a declared code element. Syntax trees, symbols, semantic models, and other structures together form a compilation. Throughout the APIs, diagnostics represent errors, warnings, and hints issued during compilation or afterwards. The compiler can be extended with analyzers, which may issue their own diagnostics. The Workspaces APIs are at a level above the Compiler APIs. A workspace is like an IDE: it manipulates with a solution3 and it has fea- tures like automatic formatting, reference finding, and code generation. Helveg uses the MSBuildWorkspace, which works with the MSBuild API, to load projects and solution files. At this point, the MSBuild assemblies have to be loaded by the MSBuildLocator as described in Section 4.2.

3. A collection of projects and documents.

22 4. Code Analysis

In the code analysis stage of the pipeline from Section 3.3, Helveg inspects a Compilation of each project. For every type, the tool calcu- lates the cumulative weights of relations with other types from the same project according to Table 4.1.

Relation of type A to type B Increment to the A → B weight A inherits directly from B 8 A is nested within B 8 A implements B 4 A contains B 2 A references B 1

Table 4.1: Weights of type relationships.

Helveg detects all type relationships except for “A references B” through inspection of their type symbols. As for references, those are detected by Helveg’s ReferenceCountingAnalyzer, which is invoked during Roslyn’s initial analysis. These weights are later the input for force-directed graph drawing algorithms described in Section 5.1. After the first enumeration, Helveg goes through the type symbols again and assigns them a “family index” so that types with a common ancestor have the same index. This number determines the color of the spruce trees during landscape generation. Analyzers can be used to enforce coding conventions. Analyzer packages like StyleCop and FxCop do just that [40]. If a project refer- ences an analyzer package, Helveg automatically runs the analyzers it contains. Consequently, warnings and errors caused by violations of coding conventions are handled in the same way as regular compiler diagnostics. Finally, for every diagnostic, Helveg attempts to find the related symbol and set its “health” to Error or Warning. During landscape generation this causes the generated structure to be on fire or damaged.

23 5 Landscape Generation

The problem of generating a landscape based on the code analysis from Chapter 4 is twofold. There is the problem of structure generation (“How to generate an island, a tree, or a cabin?”) and the problem of their layout (“How to arrange the structures?”). Helveg solves these problems in reverse order. Since if it calculates the position of each structure first, it can place them directly in their final position.

5.1 Layout

The placement of structures in the landscape is perhaps the most mean- ingful piece of information Helveg conveys. The closer two structures are, the tighter connection there should be between the types they represent. For this reason, Helveg interprets the results of the code analysis, described in Section 4.3, as weighted undirected graphs that it subjects to graph drawing algorithms. A force-directed graph drawing algorithm produces the layout of a graph by simulating physics-like forces that act upon the nodes of the graph. There are attractive and repulsive forces, which accumulate and displace nodes at the end of each iteration [41]. Helveg contains implementations of two such algorithms. A modified version of Eades’ algorithm arranges the project-islands based on their dependencies. If a project depends on another project, their nodes attract with the force of a logarithmic spring:  d  Fa = c1 · log c2 where d is the distance between the nodes, c1 = 2 is the stiffness of the spring and c2 is the radius of the largest project-island incremented by a fixed amount1 [41].

1. Set through experiment to 500.

24 5. Landscape Generation

Nodes of projects without a dependency in either direction repel each other with the force: c F = 3 d2 where c3 is the square of the largest island’s radius. Finally, to prevent nodes without dependencies from drifting apart, a gravitational force: c4 Fg = d0 where c4 = 1 is applied to every node. The d0 variable is the distance of the node from the origin of the system. It has a lower bound set to 1, which prevents nodes from flinging into infinity if they pass too close to the origin. Because Eades depends on the radius of the largest island, Helveg calculates the layouts of structures on each island before the layout of the islands themselves. The Eades’ algorithm is not suitable for the arrangement of type-structures though. If the node set large enough, the nodes begin to oscillate. They change positions but never settle in one place. Helveg’s other force-directed graph algorithm FDG solves this issue. FDG is based on the description of ForceAtlas2, another algo- rithm, which avoids oscillations by computing a different speed for each node [42].

~ ~0 1: procedure FdgStep(n, w, deg, pos, size, f , f , sG) 2: for i ← 0, n − 1 do . Gravity 3: ~v ← −posi 4: d~ ← ~vk 5: Fg ← kg(degi + 1) 6: if gravity is strong then 7: Fg ← Fg · d 8: end if ~ ← ~v 9: fi Fg k~vk 10: end for

Figure 5.1: The simulation of gravity in an FDG step.

25 5. Landscape Generation

In the first part of an FDG iteration, as shown in Figure 5.1, all nodes are subjected to a gravitational force. This force pulls the nodes to the center of the coordinate space, and thus prevents connected components of the graph from drifting apart. The magnitude of the gravitational force depends on the kg constant and the degree (deg) of the node, which forces well-connected nodes closer to the center. Furthermore, gravity can be strong, which forces the nodes into a more compact layout.

11: for f rom ← 0, n − 1 do . Attraction and repulsion 12: for to ← f rom, n − 1 do 13: ~v ← posto − pos f rom 14: d ← k~vk 15: if prevent overlapping then 16: d ← d − size f rom − sizeto 17: end if 18: if d > 0 then 19: Fa ← w f rom,to · d (deg f rom+1)(degto+1) 20: Fr ← kr d 21: else if d < 0 then 22: Fa ← 0 0 23: Fr ← kr(deg f rom + 1)(degto + 1) 24: end if ~ ← ( − ) · ~v 25: f f rom Fa Fr k~vk ~ ← ( − ) · ~v 26: fto Fr Fa k~vk 27: end for 28: end for

Figure 5.2: Attractive and repulsive forces of FDG.

As Figure 5.2 shows, attraction of two nodes is computed from the distance between them (d) and the weight of their edge (w f rom,to). Repulsion depends on the kr constant and can take node size into account to prevent overlapping.

26 5. Landscape Generation

29: swgG = 0 . Swinging and traction 30: traG = 0 31: for i ← 0, n − 1 do ~ ~0 32: swgi ← k fi − fi k ~ ~0 k fi+ fi k 33: trai ← 2 34: swgG ← swgG + (degi + 1)swgi 35: trag ← traG + (degi + 1)trai 36: end for tra 37: s ← clamp(τ G , 0.5 · s , 1.5 · s ) . G swgG G G Global speed 38: sG ← clamp(sG, kgmin, kgmax) 39: for i ← 0, n − 1 do . Move with adaptive speed ks·s 40: s ← √G i 1+sG· swgi 41: if prevent overlapping then 42: si ← 0.1 · si 43: end if ksmax 44: si ← min(si, ~ ) k fik ~ 45: posi ← posi · fi · si 46: end for 47: end procedure

Figure 5.3: Computation of adaptive speed in an iteration of FDG.

The speed of each node depends on its swinging (swg) and trac- tion (tra), as shown in Figure 5.3. Swinging is the measure of the node’s oscillation, whereas traction measures whether the node keeps moving in the same direction. Both measures depend on the cumula- 0 tive forces from the previous iteration ( f ). Besides these measures, the algorithm calculates the final adaptive speed from several constants and the global speed, which FDG implements without deviation from the ForceAtlas2 description [42]. In summary, the layout is computed separately at the level of struc- tures and at the level of islands. To maintain consistency across multi- ple runs, nodes are first sorted alphabetically according to the name of the project or type they represent, and initially positioned in a cir- cle. Then, Helveg’s FDG algorithm arranges the structures in three

27 5. Landscape Generation phases with iterations that are: unmodified, with strong gravity, and with overlap prevention, respectively.2 Finally, to arrange the islands, Helveg uses the spring-inspired Eades’ algorithm with added gravity.

5.2 Terrain

The FDG algorithm calculates the positions of the structures but does not produce a terrain where they can be placed. The island-like terrain is generated by raising an area surrounding each node to a height above the ocean level. To make the terrain seem less regular, Helveg adds OpenSimplex noise, which is a patent-free alternative to Sim- plex noise [43]. The result of this process is a heightmap like the one depicted in Figure 5.4.

Figure 5.4: The heightmap of an island.

2. Through trial and error the number of iterations in each phase has been set to 2000, 500, and 4000, respectively.

28 5. Landscape Generation

Figure 5.5: The terrain of an island.

Then, Helveg transforms the heightmap into a three-dimensional grid where each voxel3 contains an index of a color in a palette and a flag telling whether the block is empty. Given a heightmap h, the value of each voxel is computed as thus:

 stone, y = 0,   , y ≤ h(x, z) ∧ y ≤ + n (x, z), sand grass level 1 t(x, y, z) = grass, y ≤ h(x, z) ∧ y > grass level + n1(x, z),  water, y > h(x, z) ∧ y ≤ water level,  air, otherwise. where n1(x, z) is the OpenSimplex noise. The voxel grid is divided into chunks, cubes of equal size4. When the terrain is ready, Helveg populates these chunks with structures, and renders them. To illustrate, Figure 5.5 displays the island terrain without water.

3. A value on a three-dimensional grid. 4. Specifically, 128 × 128 × 128 voxels.

29 5. Landscape Generation 5.3 Structures

Helveg generates the structures, which implement the metaphor de- scribed in Section 3.2, in two different ways. Some, like the meadows and signposts, are generated in a straightforward manner using meth- ods of the WorldBuilder class. However, the trees are created using a Lindenmayer system (L-system). Regardless of the way the structures come into being, the consis- tency requirement from Section 3.1 is upheld because all seeds for pseudo-random number generators are based on the names of the Roslyn symbols they represent.

5.3.1 L-systems

Similarly to formal grammars, L-systems apply production rules to rewrite a string of symbols — turn it into another string of symbols from the same alphabet. The initial string of an L-system is called an axiom. Instead of applying the rules one at time like formal grammars, L-systems rewrite all symbols of the string at once [44]. Specific kinds of L-systems introduce further requirements on production rules. For instance, a D0L-system is deterministic and context-free. Therefore, for every symbol, there must be at most one explicit production rule in the a → χ form, where a is a symbol and χ is a non-empty string. For every symbol b that does not appear on the left side of any explicit rule, a b → b identity rule is implicitly added to the rule set. Additionally, probabilities can be assigned to rules to introduce variety. Such L-systems that are also context-free are dubbed stochastic 0L-systems. The rule set of such L-system may contain multiple explicit rules for a single symbol provided that the total of their probabilities is 1. Parametric 0L-systems attach parameters to symbols. The rules are allowed to modify the values of these parameters. These L-systems are useful in graphical applications such as to simulate plant growth [45]. To visualize the development of flora, a way to draw graphics is necessary though. A Logo-style turtle seems to be used most often [44, 45, 46]. Thus, L-systems whose sentences are meant to be interpreted

30 5. Landscape Generation

as commands for the turtle include symbols that can be interpreted as movement and rotation. Helveg has its LSystem abstraction, which is a generic C# class where the TKind type parameter is an enum representing the L-system alphabet. Instead of a string, this implementation rewrites an ImmutableArray of type LSymbol. An LSymbol is then a TKind value with parameters attached to it. Although this ap- proach seems closest to a parametric 0L-system, the production rules use lambda functions and therefore can do virtually anything.

Enum member Symbol [44] Effect Positive YawChange + Turn left Negative YawChange − Turn right Positive PitchChange & Pitch down Negative PitchChange ∧ Pitch up Positive RollChange / Roll right Negative RollChange \ Roll left YawChange of π | Turn around Push [ Save turtle’s state Pop ] Return to last-saved state

Table 5.1: Turtle drawing commands.

If the TKind contains the enum members listed in Table 5.1, it can also be used as a type argument for the LTurtle class. For reference, the same table also lists symbols that L-system research pa- pers use to change the orientation of the turtle [44]. Because Helveg’s LSymbol may encompass any number of parameters, only one enum member is dedicated to rotation about each axis. Internally, the orientation of the turtle is stored as a quaternion that changes according to the yaw, pitch, and roll of the turtle. Since these values are usually associated with an aircraft, Figure 5.6 illustrates their implementation on a plane.

31 5. Landscape Generation

Figure 5.6: Orientation of Helveg’s “turtle”.

In essence, L-systems are a formalism similar to grammars. They are able to create sequences of turtle drawing commands. Helveg implements both L-systems and Logo-style turtles as generic classes with lambda functions in place of rewriting and drawing rules.

5.3.2 Spruce Trees

In the metaphor from Section 3.2, C# classes are represented by spruce trees. These trees are generated with an L-system that first creates a sequence of drawing commands for the turtle. Altogether, the spruce trees are the most complex structures Helveg generates.

Enum member Symbol Meaning Forward F(l, r) Branch with a length and a radius

ZerothOrder B0 Tip of the trunk

FirstOrder B1 Tip of a trunk-attached branch

SecondOrder B2 Tip of an auxiliary branch

ThirdOrder B3 Needles (third-order branches)

Table 5.2: Additional symbols of the spruce L-system.

32 5. Landscape Generation

The production rules Helveg uses come from the work of Omel’ko, who bases them on the measurements of real spruces [46]. Conse- quently, the L-system uses symbols besides those listed in Table 5.1. These symbols represent the already-grown branches and the buds of future branches as described in Table 5.2.

up to 5× B0 → F(l0, 0.5)[/(0.4π)&(0.42π)B1] /(random)B1 B1 → F(l1, 0.5)[+(0.4π)B2]B1[−(0.4π)B2] B2 → F(l2, 0.5)[+(0.4π)B3]B2[−(0.4π)B2] B3 → F(l3, 0.5)

Figure 5.7: L-system production rules for the growing of spruce trees.

π All spruces originate from the same “∧(− 2 )B0” axiom, which turns the turtle towards the sky (positive y axis) and places a bud of zeroth order (the trunk). Rules listed in Figure 5.7 then rewrite the strings of symbols until the required number of first order branches has been reached. Because this number has to be equal to the number of members inside the visualized class, the rule for the B0 symbol produces up to 5 first-order branches. Additionally, after each level of the spruce tree, the turtle rolls slightly to the left or right by a random angle to make the tree seem more natural. The branches of real spruce trees grow in diameter as the plant grows as a whole. The change in diameter of a branch is proportion- ate to the total volume change of its offspring branches. This change propagates recursively from the youngest shoots to the bottom of the tree [46]. In Helveg, the L-system does not capture this phenomenon by itself. Instead, the growth of branches is calculated separately after every rewrite of the LSymbol sequence. In contrast to their diameter, the length of each branch is deter- mined only by its order alone. The values of l0, l1, l2, and l3 from Figure 5.7 have been set through experiment to 6, 4, 3, and 2 blocks, re- spectively. Finally, if a warning is detected inside the visualized class, the needles of the spruce have the same color as the trunk, which makes the tree seem bare.

33 6 Rendering

Helveg’s renderer, called Vku, is responsible for the actual “visualiza- tion”. It also lets the user explore the landscape generated in Chapter 5 thereby making it interactive. Since it is by necessity a separate C++ library, it bears a different name and declares a public API that theC# side consumes.

6.1 Layers of Vku

Vku is the source of all Helveg’s rendering capabilities, although its original purpose was to be a collection of Vulkan utilities. Vulkan is a low-level, cross-platform graphics API maintained by the Khronos Group [47]. Because Vulkan is defined as a set of C functions and structures, for which a reliable and well-maintained C# wrapper does not exist, Vku is written in C++. Helveg invokes Vku’s functions using the P/Invoke1 approach. One of the reasons Helveg uses Vulkan is that it is a lightweight API. Therefore, Helveg is less likely to breach NuGet’s size limits2 with Vulkan than it would be with a full-fledged framework like Unity [48]. However, the decision to use Vulkan also implies the absence of a framework or a ready-to-use abstraction. Consequently, Vku builds one of its own from scratch. This framework consists of four layers, which are depicted in Figure 6.1. The Base layer contains Resource Acquisition Is Initialization (RAII) wrappers around some of Vulkan’s types. RAII is a pattern ensuring that a call to a vkCreate* function is always coupled with a correspond- ing vkDestroy* call. Utilities that handle tasks like device3 selection and logging are also in Base. The Cores layer depends on Base and is thus depicted above it. Cores are classes that bear responsibility for a common piece of func- tionality. For instance, the RenderCore contains the main rendering

1. Platform invoke guards the transition between memory managed and unman- aged by the .NET runtime. 2. Breaching the size limit would prevent Helveg from being a .NET Core Tool. 3. Device is the GPU in Vulkan’s terminology [47].

34 6. Rendering

Interop Public C API

WorldRender GraphRender TriangleRender ...

Renders High-level workloads

DisplayCore SwapchainCore RenderCore ...

Cores Core components

RAII Device Selection Logging ...

Base Convenience functions and wrappers

Figure 6.1: The layers of Vku’s framework.

loop, the DisplayCore picks a device and opens a window, and the MeshCore represents the vertex and index buffers of a mesh. Renders is the next layer. A render is essentially a self-contained application. The Helveg pipeline is handled by the WorldRender class, whereas the debug subcommands from Section 3.5 are implemented by TriangleRender, MeshRender, ChunkRender, and GraphRender. Finally, the Interop layer declares public functions with the “C” language linkage [49]. These functions are Vku’s entry points. They are the only functions directly invoked from the C# side of Helveg. Thus, Vku, the renderer of Helveg, has a multilayered architecture, where each layer depends on those beneath it. The entry point to the rendering stage of Helveg’s pipeline is in the Interop layer. It is a function named helloWorld, which creates an instance of the WorldRender class.

35 6. Rendering 6.2 WorldRender

The centerpiece of Vku’s Renders layer is the WorldRender class. After all, it is responsible for rendering the procedural landscape in its entirety. Still, its most important pieces are the VkGraphicsPipeline, VkComputePipeline, and VkCommandBuffer objects it creates. A Vulkan graphics pipeline describes how to draw geometric Draw objects. This pipeline, depicted in Figure 6.2, is similar to the render- Input Assembler ing pipeline of OpenGL4. Like in OpenGL, there are fixed-function Vertex Shader stages, which can be configured in a limited fashion (shown in Tesselation red), and shader stages, which Control Shader are programmable using shaders Tesselation (shown in yellow). Although Primitive Generator there are many kinds of shaders, only the presence of a vertex Tesselation shader and a fragment shader is Evaluation Shader mandatory [47]. Similarly, a compute pipeline Geometry Shader is used for general calculations, which do not affect the resulting Vertex Post-Processing image directly. As a result, com- pute pipelines are not executed Rasterization using draw commands, but using Early Per-Fragment Tests dispatch commands. Like graph- ics pipelines, compute pipelines Fragment Shader are programmable. However, in the case of compute pipelines, Late Per-Fragment Tests there is just one kind of shader, the compute shader [47]. Blending The concept of command buffers is related to graphics and Figure 6.2: The graphics pipeline [47]. compute pipelines. In Vulkan,

4. OpenGL is a predecessor of Vulkan.

36 6. Rendering commands are not submitted to the device individually but in bulk, recorded in command buffers. Although the draw and dispatch com- mands are recorded into a buffer sequentially, unless explicitly syn- chronized, they can execute in any order. An advantage of command buffers is that once recorded, they can be used repeatedly (provided they are created as such) [47]. WorldRender records draw calls of four distinct Vulkan pipelines into its command buffers, which are executed every frame. They are the following:

The world graphics pipeline For each chunk of the world, the command buffer includes a draw command of the world graphics pipeline. The shaders of this pipeline implement the Blinn-Phong reflection model, which simulates a directional light shining over the landscape [50]. The fire compute pipeline If there are errors in the analyzed code, Helveg orders Vku to place fires in certain places. The fire compute pipeline calculates the positions of the particles the fire is made of in a compute shader. Positions of particles of all fires in the landscape are computed in a single dispatch call, albeit a workgroup (set of invocations of the compute shader) is assigned to each fire. The fire graphics pipeline For each position provided by the fire compute pipeline, the fire graphics pipeline draws a quad. A geometry shader generates this quad in such a way that it always faces the camera. The text graphics pipeline Helveg shows labels above each structure identifying the type it represents if instructed to do so. The text graphics pipeline is responsible for the rendering of these labels.

In summary, WorldRender, Vku’s most important class, executes draw commands of up to four distinct Vulkan pipelines in its com- mand buffers every frame. The pipelines together create the scene ofa landscape with burning trees and, if enabled, labels that hover above the structures.

37 6. Rendering 6.3 The Camera

The visualization produced by Helveg is not a static image but rather a scene, through which the user can move using a mouse and a keyboard. Vulkan does not provide an abstraction that would open windows or handle user input though. That is the purpose of the GLFW li- brary. GLFW bridges the gap between OS-specific window systems and Vulkan’s Window System Integration extensions [47]. Additionally, GLFW can invoke application-specific callbacks, for instance, when the user moves their mouse, or presses a key [51]. Hence, Vku wraps the features of GLFW that it needs in its Window and CameraCore classes, which belong to the Base and Cores layer, respectively. To be specific, CameraCore implements a control scheme commonly found in games. It has five degrees of freedom: pitch, yaw, up/down, left/right, and forwards/backwards. All keys with a func- tion are listed in Table 6.1.

Key Function W / ↑ Move forward S / ↓ Move backward A / ← Move left D / → Move right Move up Shift ⇑ Move down Esc Show cursor F1 Display labels

Table 6.1: Keyboard control scheme.

38 7 Distribution

Chapter 2 shows that only a few software visualization tools, besides those based on graphs and diagrams, is readily available to users. While Helveg brings some innovation to this kind of software visu- alization tools by visualizing compiler errors and warnings, it does not aim to be a research project but rather a practical tool. Thus, it is important that Helveg is easy to install for C# programmers and easy to distribute for its maintainer.

7.1 A .NET Core Tool

Helveg is a .NET Core Tool, a NuGet package containing a console application. It can be installed with the dotnet utility, which is a part of the .NET Core SDK. As Figure 7.1 shows, Helveg can be installed with a single command [52].

dotnet tool install -g helveg

Figure 7.1: Typical Helveg installation process.

Microsoft distributes some of its projects as .NET Core Tools. For instance, Powershell Core, the cross-platform version of the command- line shell, dotnet-trace, a profiler, and even some SDK commands are all .NET Core Tools [53, 52]. Since NuGet.org does not support search- ing for .NET Core tools specifically, more tools can be found through ToolGet, a third-party website, and the natemcmaster/dotnet-tools curated list at GitHub [54]. In short, .NET Core Tools are an easy way to install applications meant for .NET developers, which is exactly what Helveg is. Hence, Helveg is a .NET Core Tool. To attract users, Helveg is also present on the dotnet-tools list.

39 7. Distribution 7.2 Continuous Deployment

The Helveg NuGet package needs to contain both Windows-specific and Linux-specific components. Thus, Helveg’s renderer described in Chapter 6, needs to be built separately on Windows and Linux and then packaged together with the C# components, which are platform- independent. Only then is the package complete and can be uploaded to NuGet. Since this process is rather time-consuming and error-prone, it has been automated with continuous deployment. Continuous deployment (CD) is a practice of frequent releases that are often automated [55]. Related to CD is continuous integration (CI), which includes automatic builds and tests, but excludes deployment. In Helveg’s case, GitLab1 handles both CI and CD. The very reason I chose GitLab to host Helveg’s Git2 repository is that it offers 50 000 CI pipeline minutes to open-source projects free of charge [56]. These CI minutes are spent in CI runners, the machines that the repository, build it, run tests, and deploy it. A runner can use Docker to do its job in an isolated environment. Docker enables isolation through containers, which are similar to virtual machines, but depend on components of the hosting operating system (OS) instead of packing their own. Furthermore, a Docker container is an instance of a Docker image, which contains all the pieces the hosting OS does not provide. Finally, a Docker image is based on a Dockerfile, which is a script describing how to build the image [57]. Helveg has requirements the build environment needs to satisfy. Appendix B contains a complete listing of these requirements. The CI runner can download the tools and libraries it needs every time it builds Helveg. However, using a custom Docker image is better performance-wise, since Docker images are cached automatically. Therefore, Helveg has its cafstep/helveg-ci Docker images on Dock- erHub where the runner pulls them from. One Docker container is not enough to deploy Helveg though. Three containers participate in the deployment process. One builds Vku on Windows. Another compiles Vku and Helveg on Linux, and

1. In this work, “GitLab” stands for the https://gitlab.com instance of the GitLab software. 2. A version control system. 40 7. Distribution packs Helveg together with both builds of Vku. The final container uploads the package to NuGet. GitLab builds Helveg and Vku every time a commit is pushed to the “master” branch. However, only if a Git tag that matches the v0.x.y version string is pushed, then the CI runner deploys a new version of Helveg to NuGet. The last obstacle to Helveg’s CD is the absence of Windows Shared Runners on GitLab. Shared runners are readily available to any Git- Lab user. While Linux Shared Runners support Docker images, their Windows counterpart, which is currently in beta, does not [58]. As a result, the runner handling Vku’s Windows builds is self-hosted. To summarize, Helveg’s CD entails three Docker containers, two custom Docker images, and an on-premise CI runner. In spite of how needlessly complicated this process may seem, the end result is that Helveg can be deployed within minutes at any time.

41 8 Case Studies

Case studies within this chapter demonstrate Helveg’s functionality on custom-tailored samples and open-source codebases. Furthermore, the studies assess the quality of the visualization and identify its shortcomings.

8.1 Sample Projects

Helveg’s code repository contains three testing samples. The clean sample, as shown in Figure 8.1, consists of a single project with types related to the manufacturing of cheese. It is also apparent that among its types prevail classes, of which five share an ancestor. There is also a cargo container on a platform next to the island. Thus, the project depends on an external package. Moreover, one of cabins on the left side is about ten logs high, which implies that the corresponding struct contains about ten members.

Figure 8.1: A visualization of a tidy project.

42 8. Case Studies

Actually, only four of the dark green trees represent classes with a common ancestor (the CheeseUnit class). The fifth tree is a detriment to the expressiveness of the visualization caused by Helveg’s limited color palette. Also, upon closer inspection of the source code, the largest struct contains just four properties. However, the getters and setters of each property are members of the struct as well, thus the visualization is right in containing a cabin that high. The dirty sample differs from the clean sample in a single line of its project file. This line adds a reference tothe StyleCop.Analyzers package. As a result, the visualization shown in Figure 8.2 looks very similar to that of the clean sample except that every tree is bare and the cabins miss their roofs.

Figure 8.2: A project that breaks coding conventions.

The cause of this are compiler warnings reported because none of the classes and structs inside the project follow StyleCop’s strict coding conventions [59]. Another difference compared to the clean sample is the presence of a second cargo container, which is, of course, the StyleCop package itself.

43 8. Case Studies

Figure 8.3: A project with compiler errors.

Figure 8.3 shows what happens if a new abstract property is in- troduced into the CheeseUnit base class. Apart from the fire that con- sumes the derived classes, the added member caused a slight change to the landscape as a whole. This seems to break the consistency re- quirement of Section 3.1. However, the opposite is true as the addition of a property (and of its getter and setter) is not a mere syntactic change since it causes new symbols to appear in the compilation. In conclusion, Helveg is able to convey information about the size of a project, the size and kind of its types, and whether the project can be compiled. However, it fails to capture details like the difference between type inheritance and composition.

44 8. Case Studies 8.2 DotVVM Academy

DotVVM is a web framework, and DotVVM Academy is its interac- tive web tutorial [60]. More importantly, DotVVM Academy is a C# codebase significantly larger than Helveg’s samples. As demonstrated in Figure 8.4, Helveg is able to visualize Academy’s solution of 15 projects and generate structures of great size. It can be surmised that the depicted projects contain mostly classes, some of which are likely related because they share the color of their needles.

Figure 8.4: A detail of the visualization of DotVVM Academy.

On the other hand, from Figure 8.5 it is clear that the implementa- tion starts to fall apart at its seams. The modified Eades’ algorithm that arranges the islands, as described in Section 5.1, works well because no islands overlap. However, the bridges connecting the islands end up being distracting instead of informative. The algorithm responsible for their generation requires more work. In the future, this issue could be solved by curving and joining the bridges to reduce visual cluttering. The renderer also needs further refinements, since the edges of the world’s chunks show significant artifacts.

45 8. Case Studies

Figure 8.5: The islands of DotVVM Academy.

8.3 Roslyn

An interesting case study would be Helveg’s visualization of Roslyn since its codebase is enormous. In fact, even just the C# compiler project is so immense, that after 15 hours of CPU time1 Helveg consumed all available memory and still was not done generating a heightmap of the terrain. This demonstrates Helveg’s currently most noticeable flaw: the lack of optimization. Its philosophy of generating everything in advance just is not suitable for large codebases. Nevertheless, this presents an opportunity for future work since the resolution of this problem will likely require significant changes across the Helveg pipeline. For instance, the FDG algorithm might have to be replaced with a different method. Then a system where chunks containing only a part of the visualization are streamed to the renderer could be implemented.

1. On the Intel i7-8700 CPU.

46 9 Conclusion

The focus of this work was Helveg, a software visualization tool pre- senting C# projects as islands, similar to the one in Figure 9.1, covered with trees, cabins, and other structures. The relations between the types inside the project manifest as the proximity and color of these structures. In addition, the tool visualizes type-unrelated information like project dependencies and compiler diagnostics with intuitive ef- fects. If a project enforces coding conventions using Roslyn analyzers, Helveg visualizes violations of these conventions as well.

Figure 9.1: Helveg’s visualization of its own C# codebase.

Although the field of software visualization is vast, there have been no easily-obtainable tools supporting the C# language that implement a 3D software visualization metaphor. To the best of my knowledge, Helveg is the first tool to fit these criteria. Helveg is a console application that opens a window where the generated landscape can be explored. Its execution pipeline consists of three stages: code analysis, landscape generation, and rendering. Apart from .NET Core, it relies on the Roslyn compiler and the Vulkan graphics API. All of these technologies are cross-platform and thus allow Helveg to support multiple operating systems.

47 9. Conclusion

Furthermore, Helveg’s use of Lindenmayer systems, force-directed graph drawing algorithms, and pseudo-random number generators gives results that are consistent. It is distributed as a .NET Core Tool, which makes it readily available to C# programmers. Although Helveg achieves goals set in Section 3.1 and the thesis assignment, it can be improved and extended. The existing implemen- tation can be improved through optimization. More kinds of structures and higher graphical fidelity could convey finer details of thecode analysis. Devising a more meaningful way of arranging the generated structures also presents an opportunity for future work. Support for other .NET-based languages can be implemented with relative ease. A more interesting direction presents the LLVM project though. Through LLVM, Helveg could analyze code in almost any . However, the aspect I consider most worthy of extension is the interactivity of the visualization. For instance, Helveg could boost collaboration by letting users join each other’s visualizations. This would allow not only for faster learning but for entertainment as well. Last but not least, if the mapping was detailed enough, perhaps new code could be written from within the visualization itself.

48 Bibliography

1. TOPTAL. Sorting Algorithm Animations [online] [visited on 2020- 07-18]. Available from: https://www.toptal.com/developers/ sorting-algorithms. 2. KUHN, Adrian; LORETAN, Peter; NIERSTRASZ, Oscar. Con- sistent Layout for Thematic Software Maps. In: 2008 15th Work- ing Conference on Reverse [online]. 2008, pp. 209–218 [visited on 2020-07-18]. ISSN 2375-5369. Available from: http: //scg.unibe.ch/archive/papers/Kuhn08bSoftwareMap.pdf. 3. WALLER, Jan; WULF, Christian; FITTKAU, Florian; DOHRING, Philipp; HASSELBRING, Wilhelm. SynchroVis: 3D visualization of monitoring traces in the city metaphor for analyzing concur- rency. In: 2013 1st IEEE Working Conference on Software Visualiza- tion - Proceedings of VISSOFT 2013. 2013, pp. 1–4. 4. SCHREIBER, Andreas; MISIAK, Martin. Visualizing Software Ar- chitectures in Virtual Reality with an Island Metaphor. In: Virtual, Augmented and Mixed Reality: Interaction, Navigation, Visualization, Embodiment, and Simulation [online]. 2018, pp. 168–182 [visited on 2020-07-18]. Available from DOI: 10.1007/978-3-319-91581- 4_13. 5. TEYSEYRE, Alfredo R.; CAMPO, Marcelo R. An Overview of 3D Software Visualization. IEEE Transactions on Visualization and [online]. 2009, vol. 15, no. 1, pp. 87–105 [visited on 2020-07-18]. Available from DOI: 10.1109/TVCG.2008.86. 6. LOVELACE, Ada. Diagram for the computation by the Engine of the Numbers of Bernoulli. In: MENABREA, Luigi Federico. Sketch of the invented by , Esq. [online]. London: Taylor and Francis, 1843, p. 722 [visited on 2020-07-18]. Available from: https://nrs.harvard.edu/urn-3:FHCL.HOUGH: 33047333?n=63. 7. CHEN, Peter Pin-Shan. The Entity-Relationship Model: Toward a Unified View of Data. ACM Transactions on Database Systems. 1976, vol. 1, no. 1, pp. 9–36. ISSN 0362-5915. Available from DOI: 10.1145/320434.320440.

49 BIBLIOGRAPHY

8. OMG. Unified Modeling Language [online]. 2000 [visited on 2020- 07-18]. Available from: https://www.omg.org/spec/UML/1.3/ PDF. 9. MICROSOFT. Design Database Diagrams [online]. 2017 [visited on 2020-07-18]. Available from: https://docs.microsoft.com/en- us/sql/ssms/visual-db-tools/design-database-diagrams- visual-database-tools. 10. MICROSOFT. Design and view classes and types with Class Designer [online]. 2018 [visited on 2020-07-18]. Available from: https: / / docs . microsoft . com / en - us / visualstudio / ide / class - designer/designing-and-viewing-classes-and-types. 11. JETBRAINS. UML class diagrams [online]. 2020 [visited on 2020- 07-18]. Available from: https://www.jetbrains.com/help/ idea/class-diagram.html. 12. GREGG, Brendan. The Flame Graph. Communications of the ACM [online]. 2016, vol. 59, no. 6, pp. 48–57 [visited on 2020-07-18]. ISSN 0001-0782. Available from: 10.1145/2927299.2927301. 13. SITNIK, Adam. Flame Graph [online]. 2018 [visited on 2020- 07-18]. Available from: https : / / . com / Microsoft / perfview/pull/502. 14. CAUDWELL, Andrew H. Gource: Visualizing Software Version Control History. In: Proceedings of the ACM International Conference Companion on Object Oriented Programming Systems Languages and Applications Companion [online]. 2010, pp. 73–74 [visited on 2020- 07-18]. Available from DOI: 10.1145/1869542.1869554. 15. WONG, Darrick. Linux Kernel Development, 1991-2015 [online] [visited on 2020-07-18]. Available from: https://youtu.be/ 5iFnzr73XXk. 16. KASHCHA, Andrei. Software Galaxies [online]. 2020 [visited on 2020-07-18]. Available from: https://github.com/anvaka/pm/. 17. KNIGHT, Claire; MUNRO, Malcolm. Virtual but visible software. In: 2000 IEEE Conference on Information Visualization. An Interna- tional Conference on Computer Visualization and Graphics [online]. 2000, pp. 198–205 [visited on 2020-07-18]. Available from DOI: 10.1109/IV.2000.859756.

50 BIBLIOGRAPHY

18. WETTEL, Richard; LANZA, Michele. Visualizing Software Sys- tems as Cities. In: [online]. 2007, pp. 92–99 [visited on 2020-07- 18]. Available from DOI: 10.1109/VISSOF.2007.4290706. 19. KHALOO, Pooya; MAGHOUMI, Mehran; TARANTA, Eugene; BETTNER, David; LAVIOLA,Joseph. Code Park: A New 3D Code Visualization Tool. In: 2017 IEEE Working Conference on Software Visualization (VISSOFT) [online]. 2017, pp. 43–53 [visited on 2020-07-18]. Available from DOI: 10.1109/VISSOFT.2017.10. 20. JEFFERY, Clinton L. The City Metaphor in Software Visualization. In: WSCG 2019 Proceedings – Part I [online]. 2019 [visited on 2020- 07-18]. Available from DOI: 10.24132/CSRN.2019.2901.1.18. 21. DAVIDSON, Hilda. The Road to Hel [online]. New York: Green- wood Press, 1968 [visited on 2020-07-18]. ISBN 0837100704. Avail- able from: http://www.germanicmythology.com/scholarship/ road_to_hel.pdf. 22. UNIVERSITY OF CALIFORNIA. The 3-Clause BSD License [online] [visited on 2020-07-18]. Available from: https : / / opensource.org/licenses/BSD-3-Clause. 23. MICROSOFT. ECMA-334: C# Language Specification [Also ISO/IEC 23270:2003.]. Ecma International, 2001 [visited on 2020-07-18]. Available from: https : / / www . ecma - international . org / publications/standards/Ecma-334.htm. 24. CARNEY, David. Sun Microsystems v. Microsoft: (Java Licensing Suit) [online]. 2000 [visited on 2020-07-18]. Available from: http: //techlawjournal.com/courts/sunwvmsft/Default.htm. 25. WHYTE, Ronald M. Order Re Sun’s Motion To Reinstate November 17, 1998 Preliminary Injunction Under 17 U.S.C. § 502; Preliminary Injunction Under Cal.Bus. & Prof. Code §§ 17200 Et Seq. 2000. NO. C 97-20884 RMW (PVT). 26. CAMPBELL, Richard; FRANKLIN, Carl. Show 1500 – the History of .NET [online]. 2017 [visited on 2020-07-18]. Available from: https://www.dotnetrocks.com/?show=1500. 27. HOWARD, Rob. An Exciting Time [online]. 2001 [visited on 2020- 07-18]. Available from: https://docs.microsoft.com/en-us/ previous-versions/dotnet/articles/ms972384(v=msdn.10).

51 BIBLIOGRAPHY

28. MICROSOFT. Microsoft Launches XML Web Services Revolution With Visual Studio .NET and .NET Framework [online]. 2002 [vis- ited on 2020-07-18]. Available from: https://news.microsoft. com/2002/02/13/microsoft- launches- xml- web- services- revolution-with-visual-studio-net-and-net-framework/. 29. MICROSOFT. ECMA-335: Common Language Infrastructure (CLI) [Also ISO/IEC 23271:2003.]. Ecma International, 2001 [visited on 2020-07-18]. Available from: https://www.ecma-international. org/publications/standards/Ecma-335.htm. 30. LANDER, Richard. Announcing .NET Core 1.0 [online]. 2016 [visited on 2020-07-18]. Available from: https : / / devblogs . microsoft.com/dotnet/announcing-net-core-1-0/. 31. LANDER, Richard. Introducing .NET 5 [online]. 2019 [visited on 2020-07-18]. Available from: https://devblogs.microsoft. com/dotnet/introducing-net-5/. 32. MICROSOFT. MSBuild [online]. 2016 [visited on 2020-07-18]. Available from: https : / / docs . microsoft . com / en - us / visualstudio//msbuild. 33. LANDER, Richard [online]. 2017 [visited on 2020-07-18]. Avail- able from: https : / / devblogs . microsoft . com / dotnet / announcing-net-core-tools-1-0/. 34. MICROSOFT. MSBuild .targets files [online]. 2017 [visited on 2020-07-18]. Available from: https://docs.microsoft.com/en- us/visualstudio/msbuild/msbuild-dot-targets-files. 35. MICROSOFT. Update an existing application for MSBuild 15 [on- line]. 2016 [visited on 2020-07-18]. Available from: https://docs. microsoft.com/en-us/visualstudio/msbuild/updating-an- existing-application. 36. NOWAK, Ryan. Should MSBuildLocator handle loading of NuGet as- semblies? [online] [visited on 2020-07-18]. Available from: https: //github.com/microsoft/MSBuildLocator/issues/86.

52 BIBLIOGRAPHY

37. NG, Karen; WARREN,Matt; GOLDE, Peter; HEJLSBERG, Anders. The Roslyn Project: Exposing the C# and VB compiler’s code analysis [online]. 2012 [visited on 2020-07-18]. Available from: https: //www.microsoft.com/en-us/download/details.aspx?id= 27744. white paper. Microsoft Corporation. 38. TORGERSEN, Mads. How Microsoft rewrote its C# compiler in C# and made it open source [online] [visited on 2020-07-18]. Available from: https://medium.com/microsoft-open-source-stories/ how-microsoft-rewrote-its-c-compiler-in-c-and-made- it-open-source-4ebed5646f98. 39. MICROSOFT. Syntax Visualizer Overview [online] [visited on 2020-02-20]. Available from: https : / / github . com / dotnet / roslyn/wiki/Syntax%20Visualizer. 40. MICROSOFT. Overview of source code analyzers [online]. 2019 [vis- ited on 2020-07-18]. Available from: https://docs.microsoft. com/en-us/visualstudio/code-quality/roslyn-analyzers- overview. 41. KOBOUROV, Stephen G. Force-Directed Drawing Algorithms. In: Handbook of Graph Drawing and Visualization [online]. Ed. by TAMASSIA, Roberto. 2013 [visited on 2020-07-18]. Available from: https://cs.brown.edu/people/rtamassi/gdhandbook/. 42. JACOMY, Mathieu; VENTURINI, Tommaso; HEYMANN, Se- bastien; BASTIAN, Mathieu. ForceAtlas2, a Continuous Graph Layout Algorithm for Handy Network Visualization Designed for the Gephi Software. PLOS ONE [online]. 2014, vol. 9, no. 6, pp. 1–12 [visited on 2020-07-18]. Available from DOI: 10.1371/ journal.pone.0098679. 43. SPENCER, Kurt. Noise! [online] [visited on 2020-07-18]. Avail- able from: https://uniblock.tumblr.com/post/97868843242/ noise. 44. PRUSINKIEWICZ, Przemysław; HANAN, James. Lindenmayer Systems, Fractals, and Plants [online]. 1989 [visited on 2020-07-18]. Available from: http://algorithmicbotany.org/papers/lsfp. pdf.

53 BIBLIOGRAPHY

45. HANAN, James. Parametric L-systems and Their Application To the Modelling and Visualization of Plants [online]. 1992 [visited on 2020-07-18]. Available from: http://algorithmicbotany.org/ papers/hanan.dis1992.pdf. PhD thesis. University of Regina. 46. OMEL’KO, A. M. L-System-Based Model of Growth of Dark Coniferous Tree Species. Contemporary Problems of Ecology [on- line]. 2008, vol. 1, pp. 272–277 [visited on 2020-07-18]. Available from DOI: 10.1134/S199542550802015X. 47. KHRONOS, Vulkan Working Group. Vulkan® 1.2.147: A Spec- ification (with all registered Vulkan extensions) [online] [visited on 2020-07-18]. Available from: https://www.khronos.org/ registry/vulkan/specs/1.2-extensions//. 48. MICROSOFT. NuGet.org frequently-asked questions [online]. 2019 [visited on 2020-07-18]. Available from: https://docs.microsoft. com/en-us/nuget/nuget-org/nuget-org-faq. 49. Language linkage [online] [visited on 2020-07-18]. Available from: https://en.cppreference.com/w/cpp/language/language_ linkage. 50. BLINN, James F. Models of Light Reflection for Computer Synthe- sized Pictures. SIGGRAPH Comput. Graph. [online]. 1977, vol. 11, no. 2, pp. 192–198 [visited on 2020-07-18]. ISSN 0097-8930. Avail- able from DOI: 10.1145/280811.280981. 51. LÖWY, Camilla. GLFW Documentation [online]. 2020 [visited on 2020-07-18]. Available from: https://www.glfw.org/docs/ latest/. 52. MICROSOFT. How to manage .NET Core tools [online]. 2020 [vis- ited on 2020-07-18]. Available from: https://docs.microsoft. com/en-us/dotnet/core/tools/global-tools. 53. MICROSOFT. Installing PowerShell on Windows [online]. 2020 [vis- ited on 2020-07-18]. Available from: https://docs.microsoft. com / en - us / / scripting / install / installing - powershell-core-on-windows. 54. MCMASTER, Nate (ed.). dotnet-tools [online] [visited on 2020- 07-18]. Available from: https://github.com/natemcmaster/ dotnet-tools.

54 BIBLIOGRAPHY

55. SHAHIN, M.; ALI BABAR, M.; ZHU, L. Continuous Integration, Delivery and Deployment: A Systematic Review on Approaches, Tools, Challenges and Practices. IEEE Access [online]. 2017, vol. 5, pp. 3909–3943 [visited on 2020-07-18]. Available from DOI: 10. 1109/ACCESS.2017.2685629. 56. GITLAB. GitLab for Open Source [online] [visited on 2020-07-18]. Available from: https://about.gitlab.com/solutions/open- source. 57. DOCKER. Docker Docs: Glossary [online] [visited on 2020-07-18]. Available from: https://docs.docker.com/glossary. 58. AZZOPARDI, Steve. Windows shared Runner GA [online]. 2020 [visited on 2020-07-18]. Available from: https://gitlab.com/ groups/gitlab-org/-/epics/2162. 59. TUNNEL VISION. StyleCop.Analyzers [online]. Micorosfy, 2020 [visited on 2020-07-18]. Available from: https://www.nuget. org/packages/StyleCop.Analyzers/. 60. RIGANTI. DotVVM [online] [visited on 2020-07-18]. Available from: https://www.dotvvm.com/. 61. MICROSOFT. .NET Core RID Catalog [online]. 2019 [visited on 2020-07-18]. Available from: https://docs.microsoft.com/en- us/dotnet/core/rid-catalog.

55 A Electronic Attachments

The following items are attached to this thesis:

• The helveg-v0.6.2.zip archive containing the source code of Helveg and Vku corresponding to the v0.6.2 tag of its Git repos- itory1. Figure A.1 lists notable files and directories within the repository.

• Helveg’s NuGet package that can be installed on a 64-bit Win- dows or Linux system. Appendix B describes how to install the package. The latest version of the package can also be obtained from NuGet.org2.

~/ ...... the repository root cmake/ ...... additional CMake modules docker/ ...... the cafstep/helveg-ci Dockerfiles helveg/ ...... the C# code Analysis/ Landscape/ Render/ Vku.cs ...... C# wrapper of Vku Serialization/ Program.cs ...... the entry point vku/ ...... the C++ code shaders/ CMakeLists.txt interop.hpp ...... the C#/C++ interop interface world_render.hpp ...... the main renderer sample/ ...... sample projects from Section 8.1 CMakeLists.txt build.sh ...... build script for Linux build.ps1 ...... build script for Windows Helveg.sln

Figure A.1: Notable files and directories of the Helveg repository.

1. https://gitlab.com/helveg/helveg 2. https://www.nuget.org/packages/helveg

56 B Build Instructions

Because Helveg is written in two programming languages that inter- operate with one another, its build process is more complicated than that of a typical .NET Core console application. The build environment needs to conform to the following require- ments: Operating system Windows 10 and Linux are supported. Specifically, the Arch Linux and 20.04 distributions have been tested. .NET Core SDK The .NET Core SDK of version 3.1 or newer is required to build the C# side of Helveg. CMake Vku uses CMake to generate a Makefile on Linux. On Windows, CMake creates either an MSBuild project or a configuration file for the Ninja build system. CMake 3.14 or newer is required to build Vku. Internet connection CMake downloads Vku’s dependencies as part of its configura- tion step. Additionally, the build environment must provide the Git executable. glslangValidator The glslangValidator utility compiles shaders in GLSL1 to SPIR-V2. On Windows, it is installed with the Vulkan SDK. On Linux, it can likely be obtained through the distribution’s pack- age manager. GLFW dependencies GLFW handles cross-platform window creation and user input. On Windows, it requires the Windows SDK, which can be in- stalled as a Visual Studio component. On Linux, GLFW depends on the Xorg development libraries.

1. OpenGL Shading Language 2. Standard Portable Intermediate Representation 57 B. Build Instructions A C++ compiler Clang and the GCC3 can build Vku on Linux. MSVC4 does the same on Windows. Additionally, Helveg’s build script expects the Ninja build system to be installed on Windows.

With these requirements met, the most convenient way to build Helveg is using the build.sh build script on Linux or build.ps1 on Windows. Although for manual builds, the following commands are recommended.

1. Change the current working directory to the root of Helveg’s repository and create the build and artifacts directories.

2. Configure and build Vku.

(a) On Windows, make sure you are inside a x64 Native Tools Command Prompt for VS 2019 or have otherwise configured 64-bit MSVC to be detectable by CMake and run:

cmake -B "build" ^ -DCMAKE_INSTALL_PREFIX="artifacts" ^ -DCMAKE_BUILD_TYPE="Debug" ^ -G Ninja cmake --build "build" --target install

(b) On Linux, run:

cmake -B "./build" \ -DCMAKE_INSTALL_PREFIX="./artifacts" \ -DCMAKE_BUILD_TYPE="Debug" cmake --build "./build" --target install

3. GNU Compiler Collection 4. ++

58 B. Build Instructions

3. To produce the executable in build/helveg, run the following with replaced by the Runtime Identifier of the build envi- ronment [61]:

dotnet build --runtime --output "./build/helveg"

4. To produce the NuGet package, run:

dotnet pack "./helveg"

Please note that to build a complete Helveg NuGet package, both Windows and Linux builds of Vku, must be present in the artifacts directory.

5. To install the manually-built NuGet package, first uninstall any previously installed versions of Helveg:

dotnet tool uninstall -g "helveg"

Then run5:

dotnet tool install -g "helveg" \ --version "0.0.0-dev" \ --add-source "./artifacts"

5. In a Windows command line, replace the ‘\’ continuation character with ‘^’.

59