Tip:
Highlight text to annotate it
X
In software development, building software requires building its executable programs and libraries from corresponding sources.
This process is specified in build files which direct the build tool on how to derive the target programs from sources
Among several build tools, make is very popurarly used
This is a Makefile that specifies the rules to build the main, sender, and receiver programs on a machine with either Java or C.
make processes the Makefile in two stages:
The first stage is evaluation, where make resolves all variables, statements, and rules into a set of concrete rules.
In this case, make produces two sets of concrete rules: one if Java is installed, and one if C is installed.
A Makefile consists of rules
Each rule has a target file to produce
and a set of prerequisites
To build the target from the prerequisites a set of OS shell commands called recipe needs to be executed. This stage is called execution.
Now, Let's take a look at the evaluation phase.
The first line assigns the path of Java compiler to variable "JavaComp".
For Java-installed machine, lines 4-6 are used to set the extension of source code and program files, and compiler's command.
Lines 13 to 15 define the program names that make will produce.
Lines 17 and 18 will be evaluated to the prerequisites of "sender.jar" and "receiver.jar"
This function call will fetch all the data files from the current user directory, for example sample.dat
At line 20, make defines "install" rule with "sender.jar" and "receiver.jar" as prerequisites.
Lines 22 to 24 defines a macro and $1 represents the first parameter.
The foreach at line 26 iterates over the values of variable "executables" to define two rules via the execution of the macro at lines 22-24
Lines 28 and 29 add a recipe to rules "sender.jar" and "receiver.jar"
Lines 31 and 32 represent an implicit rule which is a template rule for any prerequisite whose name ends with .dat
For example, the rules "sample.dat", and "javaConf.dat" are produced from the implicit rule.
Due to the dynamic nature in make, it is challenging to build the analysis tools for refactoring or code smell detection in Makefiles.
First, name analysis of variables or targets is not straightforward.
Since Make is dynamic, the variable's name or ID can be the result of the evaluation of other variables.
Its also difficult to distinguish between a variable ID and a string value
Another challenge is that one entity's name is produced from different code locations
For example, to rename the suffix "src" at line 17, the renaming locations include lines 17, 18, and 23.
That is, line 26 calls line 23 which is evaluated to lines 17 and 18.
Using a text search leads to many wrong locations.
Second, automatic dependency analysis among prerequisites/targets is also challenging
Let's assume that a user downloaded our motivating Makefile and has a file named "sender.dat" in his current directory
make will produce the following set of rules:
Notice that "sender.dat" is a prerequisite of "sender.jar"
and the rule "sender.dat" is produced via the implicit rule.
and that creates a cyclic dependency between the rules. This causes an execution error.
This error is difficult to reveal as it only appears if the user has installed Java, and has data file named "sender.dat".
To address those challenges, we propose SyMake.
SyMake symbolically evaluates the Makefile to build its symbolic dependency graph.
Each of these nodes represents a target or a prerequisite.
For example, "install" node corresponds to target "install"
Due to if Condition, rule "install" will have two possible sets of prerequisites either: "sender.jar and receiver.jar" or "sender.o and receiver.o".
Those two possiblities are represented by the Select node.
This symbolic node represents the returned value from the function call "wildcard".
Each SDG node refers to a V-model which represents the symbolic string value for the corresponding rule component.
For example, this block represents the V-model of the recipe of "sender.jar" rule.
It consists of a Concat node which represents the string value being concatenated from its children nodes.
It consists of a Concat node which represents the string value being concatenated from its children nodes.
Let's assume that we want to rename the suffix "src" to "lib".
Let's assume that we want to rename the suffix "src" to "lib".
Enter the new name "lib"
Then, SyMake renames it successfully, and highlights all updated locations.
SyMake also allows you to rename targets.
SyMake detects code smells and errors in the Makefile.
SyMake lists all smells and errors and the corresponding line numbers and description.
Double-clicking on a smell shows a detailed description about the smell and highlights the corresponding locations in code.
In this case a cyclic dependency is detected!
For larger and complex Makefiles, SyMake can detect many potential code smells and errors.