Devot Logo
Devot Logo
Arrow leftBack to blogs

Make Dev's Life Easier - Master the Makefile

Ante C.6 min readJun 14, 2024Technology
Ante C.6 min read
Contents:
Make(file) as a response to boredom
Makefile in an average project
Make in practice
Some ideas for the future

What would you say is the sworn secret enemy of every developer?

Boredom! We're talking about a slightly different type of boredom than your usual, everyday boredom. Even though you have tons of work and shouldn’t be bored—you’re doing boring tasks, stagnating at work, and generally losing energy on repetitive tasks or “reinventing the wheel.”

It's the same story every day. First, we set up the project and create a CRUD. Then, we onboard a new developer and spend hours helping them set up the project. We run all the code quality and testing tools before committing and writing our documentation. Finally, we set up the project again, but this time on a Mac, and so on and so forth.

The amount of time lost on these tasks is excessive, especially if you, like me, get stubborn and record how much time you’ve spent on it for a single week. Multiply that by the number of weeks and the number of colleagues in the team, and you get an annual amount of hours (read: measured in weeks) that is permanently lost and often difficult to bill to clients.

Make(file) as a response to boredom

What is Make?

Let's not go into too much detail. Our AI friend says this:

"The Linux make command is a commonly used utility by sysadmins and developers. The command assists in the compilation process and is a must-have tool for building large applications. This utility cuts out repetition and speeds up compilation, saving time."

This sounds exactly like what we need, right? Let's start by setting up this mystical tool.

How to install Makefile?

Make comes with any Mac or Linux operating system. Enter make in the console to check that everything works. With Windows, the process is a bit more complicated. First, install Chocolatey (the Windows equivalent of Brew or APT). Then, you can install Make quickly with the command choco install make.

Makefile in an average project

1. Setup of the Makefile

After installing Make on the OS, let's set it up on the project. In the project folder, type touch Makefile, and that's pretty much it. After that, the goal is to fill the Makefile with useful commands.

2. But, first - documentation!

Note: It is MANDATORY to use tabs instead of spaces for indenting commands. Makefile does not like spaces (except within quotes!). The @ symbol is used so that the command preceded by "-" is not printed in the console as output.

No one wants to search through code to find out what commands do - documentation is most important. By default, “make” will display documentation if run without arguments. Initially, it is empty, displaying the error "No Targets".

Let's add a command and document what it does. We add a "default" block, as in the snippet, with a bunch of “echo” commands to display on the screen exactly what commands we have in this Makefile.

Let’s create a Makefile with the following content:

If now we type in the console:

We will be greeted by a nice little screen in this style:

3. Defining commands

Now that we have written the documentation and noted that we have three commands—tests, cs, and md—it's time to define what each of them does. So, we add the following snippet to the bottom of the Makefile:

This piece of code specifies in the Makefile what happens when any of these “named blocks” are used as the first argument. Make, in this case, simply executes the commands in that order.

4. Sequential execution of multiple commands (so-called chaining)

Given that this is a DevOps/Developer tool, from the above example, we see how we now have a simple way to run three tools - Code Style Checker, Mess Detector, and PHPUnit, which runs functional tests.

However, before we put everything into production, we need to run 3 (in letters: THREE) commands. Nobody has time for that—we can do better.

Let's get to know Make command chaining - a very simple way to string your build processes in order and thereby automate many things. For example, we will define a master command quality that will be responsible for running all code quality and testing tools, where, in our case, all three are already defined.

So let's start with the documentation - we add an additional line in the default block:

So, let’s define the “quality” command in the following way:

When we run make quality - it will execute all the actions defined in the "quality" command itself and line up everything listed to the right of the colon.

5. What about shell commands?

Combining shell commands and a Makefile works great - simply add them as commands within Makefile commands. For example, you can do it like this:

make launch will build Docker containers, start them, and run the shell command /scripts/launch.sh, in which we can have one, five, or even fifty other shell commands that may need to be executed within the Docker containers.

6. Let's turn makefile output into art (by coloring the output)

First, a little cheat sheet:

Then, in our regular tone, a new command colors: in the documentation (add it yourself) and a new command definition in the following way, using tput setaf for text color and tput setab for background color:

True, it's not as elegant as using html tags, but that's unnecessary. Experience shows that it's enough just to highlight the descriptive titles of individual commands with color. When we create a command that executes them sequentially, it will look super professional, I promise.

Make in practice

A simpler README.md

We've all worked on one or more projects where we spent the first three days of onboarding setting up the project, reading setup instructions from README.md that Pero and Mirko haven't updated since last Christmas, and half of it doesn't work. Moreover, there are issues because the instructions assume locally installed nginx and MySQL and similar.

All this prompted me a few years ago to organize every project I work on so that the content of the documentation in README.md for setting up the project looks approximately like this:

This simplifies the process by guiding the developer through the steps of entering all access keys, GitHub tokens, and passwords. It also provides brief instructions on which URL to open and where to find everything.

This approach typically requires 2-3 hours of work per project, with an additional 1-2 hours needed to update the Makefile during the project's SDLC. In total, this amounts to a maximum of 6 hours of effort. However, the result is significant time savings—potentially dozens of hours—on setup, running various commands, and less reliance on senior colleagues.

How do we use Makefile at Devōt?

Finally, an example of how Devōt uses Makefile in one of their projects, let's call it a “Top Secret” project. We only display the make install command:

To sum it up, the command with nicely formatted and colored output in the console:

  • Initiates commands that create your local configuration

  • Launches the dockerized application

  • It asks you to enter all passwords, URLs, and secret keys

  • Downloads vendor libraries

  • Executes the build process

  • Runs database migrations and populates it with data

  • Explains what you need to add to the /etc/hosts file

  • Displays URLs of different versions of API documentation

All this is done in a way where less experienced colleagues can look at the command and understand most of the setup process steps from the provided comments.

shell variable makefile

Some ideas for the future

The Makefile is an extremely useful tool that offers numerous options, possibilities, and tricks to simplify your life. However, we will list only a few useful commands that we often use while leaving the rest to you (after all, you are the engineers, right?)

  • wipe: - Resets the project to factory settings

  • db-backup: - Creates a database dump (the correct way!)

  • nginx-logs: - Follows the logs on the nginx container

  • quality: - Runs all available tools for code quality checking, standards, and analysis

  • fixtures: - Fills the database with all necessary initial data

  • urls: - Displays the URLs of the project (Frontend, Backend, external services, etc.)

  • docs: - Regenerates all documentation

  • cache-reset: - Clears all application cache

Make is a great tool that optimizes and automates many 'boring' tasks, ensuring you don’t irreversibly lose time. If you have any further questions about how we at Devōt save time, or if you would like to learn more about our methods, please feel free to contact us.

Spread the word:
Keep readingSimilar blogs for further insights
Building Our New Website with Next.js: The Benefits and Challenges
Technology
Mario F.Luka C.5 min readOct 18, 2024
Building Our New Website with Next.js: The Benefits and ChallengesWe decided to rewrite our website, focusing on design and maintainability. Read why we chose Next.js.
Optimize Web Applications With NextJS Server and Client Components
Technology
Luka C.5 min readOct 11, 2024
Optimize Web Applications With NextJS Server and Client ComponentsIn this blog post, explore how the dynamic duo of Next.js server and client components can improve your web applications.
Exploring TypeScript Metaprogramming
Technology
Juraj S.5 min readSep 3, 2024
Exploring TypeScript MetaprogrammingThe idea for this blog came from the workshop hosted by Daniel Ostrovsky. So, let's dive deep in exploring TypeScript metaprogramming.