The make command in Linux automates the process of creating and compiling applications from their source code.
When compiling an application, the utility reads a makefile that contains instructions on how to build the application and then executes the necessary commands to carry out the build process. It helps developers manage the build process efficiently by automating repetitive tasks and saving time.
The scope of the utility extends beyond building applications. You can use it to describe any task where specific files require automatic updates whenever there are changes in the components.
Table of Contents
- How Does the make Utility Work?
- Syntax of the make Command
- How to use the make Command
- How to Create an Application With make
- Modify/Update the Program
How Does the make Utility Work?
The make utility reads instructions from a makefile (containing rules and dependencies) and then executes the specified commands to build a software app. The rules in the file define how to compile source code files, link them together, and create the final executable library.
Simply put, it ensures the ease of program compilation, making the process more efficient and less time-consuming. It’s versatile and you can use any programming language, as long as its compiler can be executed through a shell command line or Linux terminal.
make will not limit your capacity to enhance and automate the build process, providing flexibility across various programming languages and project structures.
Simple Compilation with Make
Compiling an application is straightforward when dealing with just a few files. For instance, you can follow a process to compile a C program with three separate files (testfile_1.c, testfile_2.c, testfile_3.h).
First, you would invoke the compiler with the gcc command as illustrated below:
# gcc testfile_1.c testfile_2.c testfile_3.h
This command generates an a.out file, a standard executable program.
Now, imagine compiling an application by combining multiple files from different sources. If someone makes a change in a single file, you have to go through the time-consuming exercise to update the final application file. This is where make comes in handy. It simplifies the process and makes it more efficient.
The utility automates the compilation process, updating only the changed files without recompiling everything. For this, the make utility uses a makefile to determine which program parts need recompilation.
What are Makefiles
A simple makefile is a single file containing rules that tell the make utility how to build or compile a program. Each rule in this file has three parts: the target, dependencies, and command(s).
When you make changes to your code, the ‘make’ utility reads the makefile and figures out what parts of your program need to be updated. This automates the building process, making it easier to manage the entire process and save hours that would be otherwise wasted on repetitive tasks.
A well-constructed makefile describes the relationships between different components with clear instructions for building and managing project dependencies. As a result, the make utility streamlines the development and deployment process.
Here’s how a typical entry in the makefile looks like:
This syntax highlights the following components:
Target: This is the file’s name to be created or updated.
Dependencies: These files are needed to create the target file names, separated by spaces.
Commands: This set of commands defines how to update the target based on changes in the dependencies.
Usually, the first rule is the default/primary instruction, telling the utility how to create the final executable file (the target) from pieces that haven’t been made yet (dependencies).
Here’s the syntax for target and dependencies:
EXECUTABLE: Object file 1, Object file 2
Note: In makefiles, when you want the system to do something, you must press the TAB key before giving the command. If you forget to do this, the command won’t work.
Once the first rule is established, the user includes directions (in the form of source files) to create object files, as shown below:
The make utility does its job by first turning the initial (source) files into intermediate files called object files. Then, it transforms these object files into the main file we want—the final application.
The makefile instructions, including those three rules we mentioned earlier, are set up like this:
EXECUTABLE: Object file 1, Object file 2
Object file 1: Source file 1, Source file 2
Object file 2: Source file 2
Syntax of the make Command
The syntax of the make command in Linux is as follows:
# make [OPTIONS] [TARGET]
The options can modify make behavior, while the target specifies what part of the makefile to execute. If you run make without any arguments, it will follow the default commands for the target defined in the makefile.
Options for the make Command
The make command is very versatile and can carry out designated tasks efficiently.
When you run make without any flags or options, it starts performing tasks in the makefiles. However, you can modify this default behavior with different arguments that affect the utility’s operation and behavior.
The following are the most commonly used options for the make command.
The basic syntax of the make command with options is:
# make [options] [target]
How to use the make command in Linux
Understanding how the make command and makefiles work is best achieved through hands-on experience. Here are the prerequisites for working with this utility:
Before diving into the demonstration of make command’s simple compilation, it’s essential to:
- Understand basic Linux commands.
- Have familiarity with programming in C/C++.
- Have access to a Linux system with make installed.
An Example Run of the make Utility
Let’s explore this with a simple program that displays “Hosted at RedSwitches” as the output.
- Create a directory and name it Test_dir.
# mkdir Test_dir
2. The next step is to prepare the source files. For this demonstration, we’ll create three C files named int_main.c, text_file.c, and text_head.h
Create a new file without any content using the touch utility:
# touch file_name
Here’s a short description of these files:
- int_main.c: This file contains the main (primary) function calling another function.
- text_file.c: This file has the message that’ll be used as the output.
- text_head.h: This file acts as the table of contents for functions (someText() in this case). Both C files use the #include directive to bring the functions into the other files.
Note: In most cases, developers use the C language to work with the make utility. However, you can use the following languages with the utility:
How to Create an Application With make
There are two ways to compile an application with the make command.
The first involves directly using the GCC compiler. Alternatively, you can opt for a more organized approach by creating a makefile.
Let’s explore both of them below:
Option #1: Create a Program in C Using GCC Compiler
This approach is suitable for smaller projects.
Follow these steps to create a program using GCC (GNU compiler collection) compiler:
- Go to the terminal and find the folder with the target files.
- Start the compile process using the gcc int_main.c text_file.c. Note that the header isn’t separately compiled because it’s already part of the C files.
# gcc int_main.c text_file.c
3. Once the process finishes, use the ls command to verify that the directory contains the new a.out executable file.
Optional: You can also see the executable a.out file via the File Explorer.
4. Test the executable a.out file.
When the application has been successfully compiled, you’ll see the output in the terminal.
Option #2: Create a Program in C Using the make utility and a makefile
The make command simplifies and automates the process of compiling software, improving efficiency and maintaining consistency, especially in large-scale development projects.
- Start by making a new text document in the directory containing the source files and name it makefile. This file contains instructions for the make utility:
2.Add the following statements to the makefile:
3. Replace target with the name of the executable:
4. Include the object files int_main.o and text_file.o as dependencies. Whenever these object files are modified, the make command automatically recompiles the target.
5. Compile the files with the GCC compiler:
<TAB> gcc int_main.o text_file.o
6. Include the -o flag and designate the target as redswitches.
At this point, the makefile should look like:
Create the main.o in the makefile
Declare int_main.o as the target.
Specify int_main.c as its dependency. This file is used for generating and updating int_main.o.
To update int_main.o whenever int_main.c changes, use the command:
gcc -c int_main.c
The -c flag tells the makefile to compile the source code into an object file without creating an executable.
<TAB> gcc -c int_main.c
The makefile for int_main.o will look like this:
Create the text.o
Set text.o as the target with text.c and text.h as dependencies. Note that only text.c is compiled, as header files are not compiled:
text.o: text.c text.h
<TAB> gcc -c text.c
Use the make Utility
After saving the Makefile, enter make in the terminal.
The make command will generate two object files (int_main.o and text_file.o) and the executable (redswitches).
Use the ls command to verify that the files have been created in the directory.
Run the redswitches file
To run the redswitches file, simply type:
Modify/Update the Program
The make command plays a crucial role in managing programs effectively. It determines which file needs updating by comparing the modification times of the target file and dependencies. It simplifies program maintenance by only making changes when necessary.
If a dependency has been modified more recently than the target file or if the target file doesn’t exist, make understands that the target needs updating. It then follows the instructions in the makefile, executing commands. This process ensures that only the required files are updated during the build, making the build system more efficient.
For example, do you want to alter the output message in the redswitches program from “Hosted at Redswitches” to “Linux server”? Here’s how to do that:
1. To edit the source file, open text_file.c in your text editor.
2. Modify the existing message in the text_file.c file.
3. After saving the changes, open the terminal and execute the make command. During the execution, the utility examines the modifications in text_file.c and proceeds to recompile only this modified file.
4. When the compilation is complete, you can confirm the changes by running the executable with ./redswitches.
Clean Object Files
The first time you use make, it creates object files and the executable program.
In a large project, there can be a lot of these intermediate files. We recommend including a clean option to keep things neat in the source folder and remove these object files after the compilation.
rm *.o redswitches
The clean command consists of a target with no dependencies, ensuring it’s always executed. The rm command deletes the specified files. Using the *.o pattern, it matches and deletes all files with the .o extension and redswitches, keeping the directory tidy.
You also use the following command to perform the cleanup:
You can verify that the cleanup process has been executed with the ls command that shows that the object files and redswitches have been removed.
Compile All Files
Use the command make -B to compile every file in your project, not just the ones that have changed. This is equivalent to doing a full recompile of the project.
For instance, if you revert the message in the text_file.c to “Hosted at Redswitches” and want to recompile all files, you would use:
# make -B
The make -B command updates every file, compiling all of them in the directory, irrespective of whether they were changed or not.
Use a Custom Makefile
The make command typically looks for a file named makefile. The make -f command is used to create specific makefiles, allowing for flexibility in the build process.
Execute make with the -f flag and a filename:
# make -f [file_name]
For example, if your makefile is named my_file, you would use:
# make -f new_file
Variables in makefiles
Variables in makefiles are useful for representing file names, arguments, and related elements. To define a variable, assign a value with =.
For instance, replace gcc with a variable R:
R = gcc
redswitches: int_main.o text_file.o
$(R) int_main.o text_file.o -o redswitches
$(R) -c int_main.c
text_file.o: text_file.c text_head.h
$(R) -c text_file.c
Now, when you run make, it treats the R variable as gcc. As you can see, variables in the makefiles make it easier to introduce flexibility into the build process.
Run make in the Debug Mode
You can print errors in commands by running the make command with the -d flag that initiates the debug mode:
The make command is a powerful tool for automating software compilation. Learning how to use it improves your development skills and significantly optimizes your project’s build process.
It becomes even more effective when paired with advanced hosting solutions like RedSwitches’ bare metal hosting, offering the reliability and performance required for demanding development tasks.
RedSwitches offers the best dedicated server pricing and delivers instant dedicated servers, usually on the same day the order gets approved. Whether you need a dedicated server, a traffic-friendly 10Gbps dedicated server, or a powerful bare metal server, we are your trusted hosting partner.
Q. What is a makefile?
A makefile is a file containing the instructions and a list of commands used by the make command to compile and link a program.
Q. Can make be used for languages other than C/C++?
Yes, make can also be used for other programming languages, though it’s most commonly associated with C and C++.
Q. Why is make important for Linux developers?
make automates the compilation process, reduces errors, and saves time, especially in large projects with many components.
Q. How does make handle dependencies?
Make handles dependencies by checking the modification times of files to determine whether they need to be updated before executing the corresponding commands.
Q. Can I define custom commands in a Makefile?
You can define custom commands and rules in a Makefile to suit your program requirements.
Q. What is the default file name for a makefile?
The default file names are Makefile and makefile.
Q. How do I run a makefile?
To run a makefile, type make in the terminal directory where the Makefile is located. Once you do so, it’ll create the required (make) file.
Q. What is the use of the -t or –touch flag?
The -t or –touch flag is used to simulate the process of updating files without actually modifying them. It is useful to understand the impact of potential changes/updates to the build process.
Q. Can make compile code in parallel?
Yes, make can compile code in parallel using the -j option, which specifies the number of jobs to run simultaneously.
Q. How do I clean the build using make?
You can clean the build by defining a clean target in the makefile, which typically removes all the redundant object files and the executable.
Q. What does the $@ symbol mean in a makefile?
$@ is an automatic variable in make that represents the file name of the rule’s target.
Q. What does the $< symbol represent in a makefile?
$< is an automatic variable representing a rule’s first dependency when using the make command. It helps streamline build instructions in a makefile.
Q. How do I use variables in a makefile?
Variables in a makefile are defined with a name, an assignment operator (=), and a value. They can be referenced using $(VARIABLE_NAME).
Q. Can I include one makefile in another?
Yes, you can include a makefile in another using the include directive.
Q. What is the difference between = and := in makefile variable assignment?
= is used to expand the value when used, whereas := expands the value when declared.
Q. What is a phony target in makefile?
A phony target in a makefile is like a nickname for a set of instructions. It’s not an actual file but a name used to execute specific tasks when you ask for them.
Q. How does the make command determine if a target needs to be updated?
The make utility uses the makefile database and the files’ last-modification times to decide which files need to be updated. It issues the commands recorded in the database for each of those files.