Rudziankoŭ
Rudziankoŭ

Reputation: 11251

What is the principal difference between make command and running build .sh script?

In this Linux manual is written that make is:

a utility for building and maintaining groups of programs (and other types of files) from source code.

Description The purpose of the make utility is to determine automatically which pieces of a large program need to be re-compiled, and issue the commands necessary to recompile them.

What does automatic determination mean here? What is the principal/significant difference between running make or just running ./build.sh where I have my build scripts?

Upvotes: 1

Views: 4215

Answers (1)

jfMR
jfMR

Reputation: 24738

What is the principal/significant difference between running make or just running ./build.sh where I have my build scripts?

make can be easily used in such a way that it only rebuilds what needs to be rebuilt (and nothing more than that).


Comparative example

Consider a project to be built, program, consisting of the following files:

main.c
foo.c
bar.c
foo.h
bar.h

For this discussion, let's assume that foo.c and bar.c only include (i.e.: depend on) foo.h and bar.c, respectively.

  • With a build.sh script which simply consists of commands for building a software like the following:

    gcc -c foo.c
    gcc -c bar.c
    gcc -c main.c
    gcc foo.o bar.o main.o -o program
    

    If just foo.h gets modified, this project needs to be rebuild. With this approach, this will be done by re-running build.sh, which compiles all the source files. Note, that neither bar.o nor main.o would actually need to be generated again, since the files bar.c, bar.h, main.c didn't changed and they don't depend on foo.h at all (i.e.: they are not affected by a change in foo.h).

  • With make however, if used properly, a dependence graph is generated, so that only the files that need to be updated would be generated again: in this case foo.c and program.

    That relies on the dependency relationship between the source files and object files (among other things) being properly specified to make. This is achieved by means of a makefile:

    program: main.o foo.o bar.o
        gcc -o $@ $^
    
    foo.c: foo.h
    bar.c: bar.h
    

    Basically, it is explicitly specifying that:

    • program depends on main.o, foo.o and bar.o.
    • foo.c depends on foo.h.
    • bar.c depends on bar.c.

    and implicitly:

    • main.o depends on main.c
    • foo.o depends on foo.c
    • bar.o depends on bar.c

    That way, make knows what has to be rebuilt or updated whenever something changes and it updates only that instead of building everything from scratch.

Upvotes: 3

Related Questions