Automate the compilation process for a multiple file C project

Suppose a C program consists of 2 C program files:

f1.c f2.c
#include <stdio.h>
#include "f2.h"

int main( int argc, char *argv[] )  
{
   double a, b;

   a = 4.0;

   b = square( a );  

   print( a );      
   print( b );                       
}  
#include <stdio.h>
#include "f2.h"

void print ( double x )
{
   printf("Number = %lf\n", x );
}

double square( double x )        
{
   double r;          
   r = x * x;      
   return ( r );   
} 

In addition, we have the header file f2.h for f2.c:

// header file f2.h

void print ( double x ) ;
double square( double x ) ;

Automate the compilation process for a multiple file C project

  • Suppose the executable program is:

       main
    

  • The chain of file dependencies, starting from the target main:

      main  depends on:            f1.o f2.o
            constructed using:     gcc -o main  f1.o f2.o
                
      f1.o  depends on:            f1.c
            constructed using:     gcc -c f1.c
    
      f2.o  depends on:            f2.c 
            constructed using:     gcc -c f2.c 

  • However, there are more dependencies...  

    Hint:   look for #include files !

Automate the compilation process for a multiple file C project

Notice that the files f1.c and f2.c #includes the header file f2.h:

f1.c f2.c
#include <stdio.h>
#include "f2.h"

int main( int argc, char *argv[] )  
{
   double a, b;

   a = 4.0;

   b = square( a );  

   print( a );      
   print( b );                       
}  
#include <stdio.h>
#include "f2.h"

void print ( double x )
{
   printf("Number = %lf\n", x );
}

double square( double x )        
{
   double r;          
   r = x * x;      
   return ( r );   
} 

When the header file f2.h is updated, the change is included inside f1.c and f2.c

Automate the compilation process for a multiple file C project

  • The complete chain of file dependencies includes the header files:

      main  depends on:            f1.o f2.o
            constructed using:     gcc -o main  f1.o f2.o
                
      f1.o  depends on:            f1.c 
            constructed using:     gcc -c f1.c
    
      f2.o  depends on:            f2.c 
            constructed using:     gcc -c f2.c 
    
      f1.c  depends on:            f2.h
            constructed using:     ???
    
      f2.c  depends on:            f2.h
            constructed using:     ???
     

  • However:

    • There are no commands needed to created the result file...

Automate the compilation process for a multiple file C project

  • We can simplify the chain of file dependencies as follows:

      main  depends on:            f1.o f2.o
            constructed using:     gcc -o main  f1.o f2.o
                
      f1.o  depends on:            f1.c f2.h
            constructed using:     gcc -c f1.c
    
      f2.o  depends on:            f2.c f2.h
            constructed using:     gcc -c f2.c 

  • Effect:

    • When the header file f2.h is updated, we will execute:

         gcc -c f1.c
         gcc -c f2.c
      

      (That's what we really want to do !)

Automate the compilation process for a multiple file C project

  • Writing a Makefile for this chain of file dependencies:

      main  depends on:            f1.o f2.o
            constructed using:     gcc -o main  f1.o f2.o
                
      f1.o  depends on:            f1.c f2.h
            constructed using:     gcc -c f1.c
    
      f2.o  depends on:            f2.c f2.h
            constructed using:     gcc -c f2.c 

  • Makefile:

    
    main: f1.o f2.o
            gcc -o main f1.o f2.o
    
    f1.o:  f1.c  f2.h
            gcc -c f1.c
    
    f2.o:  f2.c  f2.h 

Automate the compilation process for a multiple file C project

  • Writing a Makefile for this chain of file dependencies:

      main  depends on:            f1.o f2.o              
            constructed using:     gcc -o main  f1.o f2.o 
                
      f1.o  depends on:            f1.c f2.h
            constructed using:     gcc -c f1.c
    
      f2.o  depends on:            f2.c f2.h
            constructed using:     gcc -c f2.c 

  • Makefile:

    main: f1.o f2.o
            gcc -o main f1.o f2.o
    
    f1.o:  f1.c  f2.h
            gcc -c f1.c
    
    f2.o:  f2.c  f2.h
            gcc -c f2.c 
    

Automate the compilation process for a multiple file C project

  • Writing a Makefile for this chain of file dependencies:

      main  depends on:            f1.o f2.o
            constructed using:     gcc -o main  f1.o f2.o
                
      f1.o  depends on:            f1.c f2.h   
            constructed using:     gcc -c f1.c 
    
      f2.o  depends on:            f2.c f2.h
            constructed using:     gcc -c f2.c 

  • Makefile:

    main: f1.o f2.o
            gcc -o main f1.o f2.o
    
    f1.o:  f1.c  f2.h
            gcc -c f1.c
    
    f2.o:  f2.c  f2.h
            gcc -c f2.c 
    

Automate the compilation process for a multiple file C project

  • Writing a Makefile for this chain of file dependencies:

      main  depends on:            f1.o f2.o
            constructed using:     gcc -o main  f1.o f2.o
                
      f1.o  depends on:            f1.c f2.h
            constructed using:     gcc -c f1.c
    
      f2.o  depends on:            f2.c f2.h   
            constructed using:     gcc -c f2.c 

  • Makefile:

    main: f1.o f2.o
            gcc -o main f1.o f2.o
    
    f1.o:  f1.c  f2.h
            gcc -c f1.c
    
    f2.o:  f2.c  f2.h
            gcc -c f2.c
    

DEMO: demo/C/Make/2