Managing Project Complexity with Static Analysis Tools
Programming can be difficult, especially when working on a large, collaborative project. Project complexity often increases throughout development, and everyone has their own personal style of writing codes. For these reasons, it is often necessary to use tools that can help us manage project complexity and enforce a common programming style. This is what I'm currently learning in my Open Source class.
In this blog post, I want to share my experience with learning about and adding Static Analysis tools to my to manage project complexity in my Open Source class.
Static Analysis Tools
I've learned that static analysis tools operate on source code and not running code. Tools that analyze running code are called dynamic analysis tools, but I won't be discussing dynamic analysis tools in this blog post. Static analysis tools can be thought of as
"spell check for programmers", as they help developers maintain source code quality by:
- fixing formatting issues
- spotting suspicious code constructs
- altering developers to common errors
- operate on source code (static) vs running code
Why Static Analysis
Static analysis tools aren't the first or only method of enforcing code styles formatting. Other ways to enforce code formatting include adding a style guide to project documentation or enforcing code rules during code reviews. However, there are a couple problems with these methods:
- new contributors often forget or ignore style guides
- nit-picking stylistic errors are a waste of time for both contributors and maintainers
Using static tooling in a project avoids these problems and eliminates any arguments that can arise over styling preferences.
My Lab Exercise
For this week's lab exercise, I learned how to work with and setup the following static analysis tools with my ctil project:
- an automatic source code formatter
- a source code linter
In setting up the above tools I also did the following:
- setup a command-line or project build scripts to run static analysis tools
- integrated an IDE with these static tools, and
- added contributor documentation with instructions to setup and use these tools
Adding a CONTRIBUTING.md file
At the start of this project, I added both usage information and environment setup in a README.md file. As my project is becoming more complex and because I am adding static analysis tools to support development, I added a CONTRIBUTING.md file to contain my environment setup instructions and contributing guidelines. Due to time constraints, I ended up using a CONTRIBUTING.md template generated using https://generator.contributing.md/ and adding instructions on top of that.
Adding packages to a C++ project is difficult (for me)
ctil is written in C++, so I added the following Clang Tools by LLVM:
- Code Formatter: Clang-Format, and
- Code Linter: Clang-Tidy
Both clang-format and clang-tidy are command-line tools, but can also instead be integrated to an IDE. I ended up doing both to support my work, as I wanted to use these tools from the command line and with Visual Studio 2019:
- To add the command-line tools I added Clang Tools in my Visual Studio 2019 installation:
- To integrate Clang Tools with the Visual Studio IDE, I added the Clang Power Tools extension:
Clang Tool Configuration
clang-format
and clang-tidy
can be configured in a project with their own config files, .clang-format and .clang-tidy respectively. In my experience, I found the LLVM documentation helpful on creating a .clang-format
file, but for .clang-tidy
the documentation was a little cryptic. I found these blog posts by the Clang Power Tools team a little more helpful:
- Clang-Format: https://www.clangpowertools.com/blog/getting-started-with-clang-format-style-options.html#FirstClangFormatFile
- Clang-Tidy: https://www.clangpowertools.com/blog/automatically-detect-your-clang-tidy-file.html
To create a .clang-format
config file I was able to run this command found in the LLVM documentation and the Clang Power Tools blog:
clang-format -style=llvm -dump-config > .clang-format
To create a .clang-tidy
config file I was used the Clang Power Tools plugin to generate one with default checks:
Formatting and Linting my Program:
To format all the source code in my file, from the project's root directory I used the clang-format command line tool instead of creating my own script:
clang-format -style=file -i *.cpp *.h
After running clang-format I found that my entire source code was reformatted! Specifically, clang-format changed the indentation style of my source code and applied an indent-length of 2 characters. I've heard that code formatters can sometimes break code depending on the severity of the changes. Luckily, I found that my program was unbroken, so I was able to commit these formatting changes with no issue.
Similarly, to lint the source code, from the project's root directory I used the clang-tidy command line tool:
clang-tidy --config-file=".clang-tidy" *.cpp *.h
When using clang-tidy both as a command-line tool and a Visual Studio plugin, I received warnings but was unable to find any specifics:
Because of this, I didn't make any linting changes to my source code. If anyone reading has any suggestions on how to locate warnings from clang-tidy
I would appreciate your input in the comments.
My Experience - Package Management in C++ is Difficult (for me)
The point of adding Static Analysis tools was to enforce a common code format and linting for all contributors and maintainers to ctil. However, I had a tough time adding these tools to my project. To get all of this working, I had do:
- modify my Visual Studio installation
- add new values to my System PATH variable
- add a plug-in/extension to my Visual Studio IDE
Is There a C++ Package Manager that works like NPM?
This would be worth the trouble if it meant future contributors would be able to install these dependencies out-of-box, but for C++ projects, there's no convenient way I know to do this. NodeJS projects have a project.json
file that contains all the dependencies contributors and users need to run a project. After cloning a NodeJS project, contributors just need to run npm install
and other variations to set up their environment. For C++ there doesn't seem to be a default package manager like npm that provides this ease of environment setup, or if there is I haven't learned about it.
If it took me this much trouble to setup these tools, I can't imagine how far prospective contributors will go before giving up on my project and working on something else. If anyone reading knows a good package manager that I can retroactively integrate to my project, I would appreciate suggestions that would make environment setup convenient for contributors.
Top comments (0)