Systematic Reuse and Ad Hoc Forking to Develop Software Variants

Research output: Book / Anthology / Report / Ph.D. thesisPh.D. thesis

View graph of relations

A common way to implement variability in C/C++ systems is to use reprocessor
annotations to allow software to be configurable. Source code is annotated by developers, who can then use preprocessor tools to exclude or include code fragments at compilation time. Although annotations such as #ifdef and #endif increase efforts in maintenance, clutter the code, and challenge program comprehension, they are easy to use, scalable, and therefore heavily used in practice. An alternative for developing software variants is to reuse existing code by forking an existing project. In its simplest form, forking is the process of copying an existing project and then having complete freedom to modify the fresh copy. This is a quick, effective, and common method used in open source and industrial software projects because of its low costs. However, this method does not scale and increases maintenance efforts due to multiple copies of the
same artifacts that need to be maintained in multiple places.
In this dissertation I explore the advantages and disadvantages of using these two techniques to develop software variants in practice. The main goal is to understand how to leverage their benefits while reducing the associated costs and issues. I analyze a complex and popular 3D printer firmware and its community, to understand how variants are developed using preprocessor annotations and forking. I explore the idea of combining the two techniques to have the advantages of both, while reducing some drawbacks. As a way to achieve this, I propose and show the feasibility of a variation control system that combines and unifies the usage of preprocessor annotations and forking, leveraging their benefits. Developers work on specific projections (variants)
of the code, make changes and push their changes back to the repository. The variation control system also offers support for independent development through forking.
Often, forked variants need to be reintegrated into an integrated platform, though it is not a trivial process. I argue that the integration should be supported by specific tools that are not based on the classical diff tools. To this end, I propose to abstract from code and lift the process to more common integration intentions. To achieve this, I developed a set of generic integration intentions that guide the developer through the integration process. Developers have two views showing the differences between the mainline and the forked variant, can make changes that they can see in those two views (while the views are simultaneously synchronized), and can preview the result of their changes and intentions in the preview view. This allows them to explore different integration goals and quickly apply and undo intentions. Through a series of simulations and a controlled experiment, I show that users using a specialized tool do less mistakes compared to traditional merging tool, while they are using just a few operations to achieve their integration goal.
Original languageEnglish
PublisherIT-Universitetet i København
Number of pages190
ISBN (Print)978-87-7949-008-6
Publication statusPublished - 2017


No data available

ID: 83177808