Search

Makefiles: Using variables

Prev: make is smart We can use variables in makefile to prevent typing the same strings over and over and also make the file more easy to understand.

Defining variables: Let us say we have a makefile to compile three independent executables hello_1, hello_2 and hello_3



In the above makefile we use the string "cc -o" repeatedly. Instead of typing the whole string every time we can create a variable for it.
We can create a variable of any name by using the "=" sign. The left hand would be the name of the variable and the right hand side would be the value of the variable.
Any where in the file if we want to use the value of the variable we just have to use the name of the variable in the format $() and make will automatically replace the variable with its value while executing.



In the above file have created a variable CC and used it whenever we needed cc -o.
Note that variables are case sensitive thus "cc" "CC" and "Cc" are all different.
We can also use variables for prefixes of various strings. Like in the example above "hello" is like a prefix to a number of strings, thus we can use a variable for it.



Recursive expanded variables : We can create recursive variables by using one variable while declaring another.



In the above example "targets" is a variable, which is a list of all the targets. The targets variable uses the variable "pf" , thus to find out what $(targets) refers to make will have to expand pf creating a recursion among variables any depth of such recursion is allowed.
The limitation of defining variables using "=" is that a variable can not refer to itself in recursion.



In the above example, the second definition of variable "targets" uses the "targets" itself in recursion. Such usage will result in an infinite loop, which make successfully detects and throws the error.



Simply expanded variables This can be prevented by making use of simply expanded variables which are defined using ":=". The use of ":=" makes the expansion of all the variables in the assignment only once and stop, thus preventing the infinite loop.

Thus in the above example the second definition should be



Now make will not throw any error and will successfully compile the targets.

Using shell in declaration : We can also execute shell commands while defining variables.



In the above example we executed the command "pwd" and assigned the result to the variable "opd" which we used while compiling to indicate the path where the compiled executable needs to be stored.


Makefiles:make is smart

Prev: Multiple independent targets

Till now to compile a c program we have passed the command to the makefile to compile a given c code. But make has built in intelligence and can work even without the command.

Let us say we have ta file

hello.c



To compile this file using make we just need to create the makefile with the contents

makefile



make looks at the targets and if no dependencies and commands are mentioned in the makefile,it automatically looks for a file with the name .c i.e. in the above example hello.c and compiles it to create the executable.



If we want to make sure that the correct files are being compiled before actually generating the executable we can just print the commands that make is going to run by passing the option "--just-print".



In the above case the executable will not get generated, but it only prints the commands that will be executed.

We can also print the folders in which make is running the commands from using the option -w



Next: Makefiles: Using variables

Makefiles: Multiple independent targets

Prev: Multiple dependent targets

The make command when executed with out any arguments always tries to create the first target. But in one makefile we can specify as many independent targets as we want and then choose to create the specific targets .

Let us say we have two programs

hello_1.c



hello_2.c



The above two are independent programs which can be compiled on the command line using



The same can be done by creating a makefile with two targets "hello_1" and "hello_2".

makefile:



Now if we run the command make



We can see that if use the command make with no arguments the first target i.e. hello_1 gets crated. Now if we want to create the second target we will have to pass the second target to the make command as an argument.



Thus we can specify any specific target we want to create as the argument to the command make.

If we want to option of creating all the independent targets with out specifying every target separately we add a target to the makefile and mention all the targets as the dependencies.

makefile:



Now we can create hello_1 and hello_2 by running make with all as the target.



Thus we can use makefile with multiple targets and selectively create the required targets or create all of them together.

Next: Makefiles: make is smart

Makefiles: Dependent targets

Prev: Makefiles : Introduction The makefiles can have as many targets as we want, and they could be dependent on another or independent.

Let us say we have the following codes
hello_main.c



print_hello.c



The first program is calling a function declared in the second program. To compile these codes we can run the command



This can be broken down into the following steps
Creating the object code



This will generate the object files "hello_main.o" and "print_hello.o"

Now we can club the object codes into one executable



This will generate the final executable hello.

For creating the executable hello, hello_main.o and print_hello.o are the prerequisites.
Thus the makefile entry for target hello is



For creating the object codes, hello_main.o and print_hello.o are the targets and hello_main.c and print_hello.c are the prerequisites

Thus the make file entries for the two object codes is



Combining the above two we can create the full makefile

makefile:



Note the order in which the entries have been added. The final target is the first entry, the prerequisites for the final target are created by making them as targets in the subsequent entries.

Now run the command make



We can see that make starts compiling from the first independent target hello_main.o then it compiles print_hello.o then it create the final executable using the two object files.

Now open the program print_hello.c and modify the print statement



Save the program and run the command make again.



We can see that make compiled only the modified program and did not compile hello_main.c which was not modified after the executable "hello" was created.

The above split was shown just show the concept of dependent targets. We can compile the same code using the shorter makefile

makefie:



If you misspell any of the prerequisite names then make will throw an error and fail. For eg. if we create the above makefile with the file name hell_print.c



On running make we will get the error



The above error indicates that the problem is with the file name "hell_print.c" as the makefile is unable to find a file with that name. Next: Makefiles :Multiple Independent targets

Makefiles: Introduction

Makefiles: Introduction Makefiles are the files used by the utility make. make helps in compiling a source code into an executable or automate execution of commands listed in the makefile.

Let us say we have a file "hello.c"

hello.c



The usual compilation of this in linux using gcc is



We can use a makefile to do the same compilation
The syntax of writing a makefile is



A makefile is comprised of

Target : The executable which has to be generated. In the above case the target is the executable hello.

Prerequisite: The source files required to generated the target. In the above example the source is hello.c

Command: If the prerequisite is available which command will convert it into the target ? The command in the above example is "cc -o hello.c -o hello". The command always has to be preceded by a single tab space

Create a file by the name "Makefile" and enter the contents

Makefile



Now open a terminal and cd to the folder where the makefile is stored.
Run the command



We can see that make has run the command and generated the executable just as we did from the command line.
You might get the following error if you have omitted the tab space before the command.



If you name the makefile wrongly You might get the error



The makefile can also be named with any other name we want but in that case we need to use the option "-f" with the command make. If we want to name the above makefile as my_makefile then we need to use the command make as

After the makefile has generated the executable if we run the command make again we will get the message



This is a special property of the make utility. It will generated a new executable of the mentioned target only if the target does not exist or the source file has been modified after the target has been generated. Next : Makefiles: Dependent targets

Extracting pages from a pdf file using linux command line

pdftk is a tool which we can use to split or extract pages from a pdf document.

To install pdfktk on debian based systems



Let us say we have a pdf file,temp.pdf, with 100 pages in it. We want to extranct the pages 20 to 30 and create a new pdf . We can do it using pdftk



If the command returns to the prompt with no errors, we will have a new pdf file in the same directory with the name new.pdf.

We can pick specific pages instead of a range by just passing the page numbers.

To create a new pdf by extracting pages 21,25, and 28 we can use.



We can also select only even/odd pages by passing the option even/odd respectively

To extract all the odd numbered pages we can use the range as 1-end and use the keyword odd.




Truncate:Reduce file size from command line in linux

We can change the size of a file from the command line using the command truncate.

For e.g.



We can change the size of temp1.txt to any size we need.



But be careful as the truncation simply removes the content of the file to reduce its size.