On this topic, It just put a couple things to finding out how we can use Makefile
. It just a brief tutorials from Learn Makefiles With the tastiest examples, Just learn and figure out why want to play with this one and C, C++
Reference Documentation
Makefile and anything about that type scripting
Define, Why do we need Makefile ?
Makefiles are used to help decide which parts of a large program need to be recompiled. In the vast majority of cases, C or C++ files are compiled. Other languages typically have their own tools that serve a similar purpose as Make. Make can also be used beyond compilation too, when you need a series of instructions to run depending on what files have changed.
On my opinion, with C
or C++
, multiple file need to compile in one time, although if you think you will run with command, so just go ahead, but I need to said that not easily. You can see how you need Makefile
instead of type command like example (IDK but gRPC make nightmare when compile with typing)
I just a fresher with Makefile
but i need to figure out when you give a time for defining Makefile
, I will cut a lot of time when you need moving C
or C++
module into another environment, module or container and compile itself for example, so that reason why i need to learn this πππ
What alternatives are there to Make?
- C/C++: SCons,Β CMake,Β Bazel, andΒ Ninja or maybe Visual Studio or Visual Studio Code will help you compile
- Java: Ant,Β Maven, andΒ Gradle.
- Other languages like Go, Rust, and TypeScript have their own build tools
Interpreted languages like Python, Ruby, and raw Javascript don't require an analogue to Makefiles. The goal of Makefiles is to compile whatever files need to be compiled, based on what files have changed. But when files in interpreted languages change, nothing needs to get recompiled. When the program runs, the most recent version of the file is used.
Version of Make and Install Make
Currently version Make on Ubuntu 22.04 is 4.3. You can check it with below command
In situation, your shell doesnβt have make
, you can install it via some package managing like apt(Linux) / choco(Windows) / yum(CentOS/RedHat)
or directly from website like Window. Some instruction can helping Intro to βmakeβ Linux Command: Installation and Usage
With Ubuntu 22.04, Just easily run this command
Makefile syntax, properties with example
Syntax
A Makefile consists of a set ofΒ rules. A rule generally looks like this:
- TheΒ targetsΒ are file names, separated by spaces. Typically, there is only one per rule.
- TheΒ commandsΒ are a series of steps typically used to make the target(s). TheseΒ need to start with a tab character, not spaces.
- TheΒ prerequisitesΒ are also file names, separated by spaces. These files need to exist before the commands for the target are run. These are also calledΒ dependencies
Basic Example
So let take a editor or just terminal for create the first Makefile, this command will help you
After you have your Makefile, let play with it and analysis about this one
Like I refer above about the Makefile use for do compile a bunch of files, if your terminal doesnβt exist hello
and hello1
file, Makefile will actually work and print your string. Letβs run command and view the result
When we run make
, it will run the first target of Makefile is hello
β currently It will find hello
file is exist or not, if not it will execute command. So if hello
file really exist, it will not execute command. You can specify the target with make
command with append it into.
Deep into advantage Makefile
This tutorial documentation is contributing this example
Level 1
Create a file blah.c
and put some line of C
into this, after that create make file for compile blah.c
file
So just run with basic make
command, you will see output file is blah
in your directory. make
help you build this file from command, but in secondly, your make
command will return make: 'blah' is up to date.
. Like I refer above, if you file is already existed, your command will not run
But It has problems, when you change blah.c
β make
is not actually work, so you need to but the thing called βprerequisitesβ into Makefile
With this condition blah.c
will become factor which effect into blah
. This mean, when you change blah.c
β Target blah
can recompiled. Letβs run make
and watch a result
Conclusion you will have take in those example
- The first target is selected, because the first target is the default target
- This has a prerequisite ofΒ
blah.c
- Make decides if it should run theΒ
blah
Β target. It will only run ifΒblah
Β doesnβt exist, orΒblah.c
Β isΒ newer thanΒblah
Tip
π₯Factπ₯ To make this happen, it uses the filesystem timestamps as a proxy to determine if something has changed. This is a reasonable heuristic, because file timestamps typically will only change if the files are modified. But itβs important to realize that this isnβt always the case. You could, for example, modify a file, and then change the modified timestamp of that file to something old. If you did, Make would incorrectly guess that the file hadnβt changed and thus could be ignored.
Level 2
If you work with more target, makefile
will have some fun. Change your make file to new one
This file above from official documentation, It mean when you run make
, It will execute and run those target because
- Have condition between those targets, before depend on like
blah
βblah.o
βblah.c
- Actually condition when you want to run
make
successfully is removingblah.c
and run make.
Copy this makefile
and run it with your shell to get result
After I deleted blah.c
, rerun with make
and all step will run. Go far way, If you edit it (and thus change the timestamp to newer thanΒ blah.o
), the first two targets will run. If you runΒ touch blah.o
Β (and thus change the timestamp to newer thanΒ blah
), then only the first target will run. If you change nothing, none of the targets will run. Try it out!
With those concept, you can handle infinity loop when create and update a file with this example. Have Conditions but itself make dependency on others, but will cause effect for each others
Make Clean
clean
is target for using remove the outputs of other target, not special wold inmake
clean
is not first target (default) and not a prerequisite. It just run when you domake clean
Warning
clean
is not intended to be a filename. If you happen to have a file namedΒclean
, this target wonβt run, which is not what we want. UseΒ.PHONY
Β to fix this
Example
Run make with command and see what result you will have
First of all, when you run make
in default, it just run hello
target and not execution clean
and when you run with make hello
, clean
will not execute. Providing it, clean
is not first or default target, If you want to execution it, Do command make clean
Make Target
In the Make will some situations when you play with target βΆοΈ βΆοΈ Documentation Example
- When you want to make run all target, Make offer you
all
. Ifall
target is listed, it will primary target and run default when not specify target when runmake
command βall: one two three
- Multiple target can call easily via
$@
, it automatic variable and will run for each to contain target name
Make variables
I rate about Make
variables
Like any program or scripting language, Variables is important part when code or write script for any kind of them. Make script become parameterize, secure and flexible. Make is not exception
Variables can only be strings. Youβll typically want to useΒ :=
, butΒ =
Β also works
Example
Tip
- Single or double quotes have no meaning to Make. If you put a single quote, your script will parse to
'file'
- Reference variables using eitherΒ
${}
Β orΒ$()
. When you try with$x
, it works but not recommend
Some special case when doing with Makefile
variables
There are two type of variables
- recursive (useΒ
=
) - only looks for the variables when the command isΒ used, not when itβsΒ defined. - simply expanded (useΒ
:=
) - like normal imperative programming β only those defined so far get expanded
Different between recursive
or simply expanded
- Overwrite or changing in last result
With this example above, Tell us something
recursive
can append or relate by othersβs define variables on whatever effect for it . In the end of Make, when print, this one can show the last result which effect the variable.- But some how,
simply expanded
canβt do like thattwo
is justtwo
and not append anymore likerecursive
. Becauselater_variable
is not put on the head of two variable when it defined, therefore justtwo
variable canβt readlater_variable
- Allow append to a variable or not
With
recursive
, It will not append anything, just infinite loop when call itself βMakefile:3: *** Recursive variable 'one' references itself (eventually). Stop.
but on the besidesimply expanded
do great things when can be able append to itself
Special things when assign with variable
?=
only sets variables if they not set- An undefined variable is actually an empty string!
- To make a variable with a single space, useΒ
$(nullstring)
- UseΒ
+=
Β to append
Environment variable with Makefile
When Make starts, it automatically creates Make variables out of all the environment variables that are set when itβs executed.
TheΒ export
Β directive takes a variable and sets it the environment for all shell commands in all the recipes
With some complicated, just take a look in how can perform make
effect with sub make
. And with .EXPORT_ALL_VARIABLES
willΒ exports all variables for you. You can copy and play with on βΆοΈ βΆοΈ Documentation Example
Automatic Variables and Wildcards
Take a look in tutorials, it will talk about some wildcards and special automatic variables, some tips and usage when you know what you are doing βΆοΈ βΆοΈ Example Documentation
Advance Makefile Part
Make
is made for doing easily when compile C
and C++
, If you reach this part, maybe will need to redirect to Tutorial documentation - Chase Lambert to figuring out it. I will listed some hotkey and you can reach it from the tutorials.
- Fancy Rules : Specify and implicit rules, kind of thing like precompile or compile with brief or short way, I think so. Moreover, you will have meet some specify pattern and functional with rule like Static Pattern Rules, Static Pattern Rules and Filter Function, Pattern Rules and Double-Colon Rules
- Commands and execution: This part will talk about how you can do slient with
Makefile
, use command execution rule, set default shell , Double dollar sign, Error handling, Interrupting or killing make, Recursive use of makeand Arguments to make - Additional variables: This part will talk about how we can do Override variable,List of commands and define,Target-specific variables and Pattern-specific variables
- Conditional part of Makefiles: Like the name it will talk about condition with If/else statements, Check if a variable is empty, Check if a variable is definedand MAKEFLAG
- Functions: Talk about how to create a functions with First Functions, String Substitution, The foreach function, The if function, The call function and The shell function
- Others: Some others function has offered by Make like Include Makefiles, The vpath Directive, Multiline, .phony and .delete_on_error