Welcome to the most active Linux Forum on the web.
Go Back > Blogs > TheIndependentAquarius
User Name


Rate this Entry

Writing a basic makefile

Posted 12-29-2011 at 03:54 AM by TheIndependentAquarius
Updated 06-14-2012 at 03:44 AM by TheIndependentAquarius

  • Q: Why should we split our program instead of
    placing all the code in one file?

    A: If/When our program becomes very large, or it contains
    the code for some entirely different sets of functionalities,
    it may become cumbersome for us to edit/read the lengthy
    Also, if we make a small change and then try to recompile,
    the whole giant file will get compiled again and may
    consume quite some amount of time.

    Dividing our source code into separate files makes it
    manageable since we'll be knowing which file do we have
    to edit to get the `x` effect. Other files will stay as
    they are.

    Less time will be spent in compilation since only those
    files will be compiled which have the recent uncompiled

  • Q: How to compile the source files separately?
    A: Suppose our main directory is `makeFileDemo`.
    It contains sub directories namely `header` and `source`.

    The source files we have are `sourceA.cpp`, `sourceB.cpp`,
    and `main.cpp` stored in the sub directory namely `source`.

    The header file we have is `headerAB.h` stored in the sub
    directory namely `header`.

    anisha@linux-y3pi:~/makefilesDemo> ls -R
    header  source
    main.cpp  sourceA.cpp  sourceB.cpp
    Now, the step to compile the source files of the sub
    directory `source` (assuming we are currently
    in the main directory makeFileDemo)
    to get a
    final executable file is:

    anisha@linux-dopx:~/makeFileDemo> g++ source/x.cpp source/y.cpp source/main.cpp
    anisha@linux-dopx:~/makeFileDemo> ls
    a.out  header  source
    The default executable file namely a.out gets created if we don't specify our own executable name with -o option.

    It is a possibility that we've just modified one source file out of for example existing ten files, so logically we shouldn't be bothered to re-compile the other nine source files every time we modify just one of them.

    To avoid recompiling the other n-1 source files every time we modify just one of the n files, we can create object files of all the n files and then simply link them together.
    anisha@linux-dopx:~/makeFileDemo> g++ -c source/x.cpp
    anisha@linux-dopx:~/makeFileDemo> g++ -c source/y.cpp
    anisha@linux-dopx:~/makeFileDemo> g++ -c source/main.cpp
    anisha@linux-dopx:~/makeFileDemo> ls
    header  main.o  source  x.o  y.o
    anisha@linux-dopx:~/makeFileDemo> g++ main.o x.o y.o -o executable
    anisha@linux-dopx:~/makeFileDemo> ls
    executable  header  main.o  source  x.o  y.o
    Now, if we edit y.cpp and re-run above command with the previously created object files the change won't get reflected because we haven't recompiled the files, we have just relinked their previously created object files.

    To see the effect of the edit we made to the y.cpp, we have to recreate the y.cpp's object file.
    anisha@linux-dopx:~/makeFileDemo> g++ -c source/y.cpp
    Then rerun:
    anisha@linux-dopx:~/makeFileDemo> g++ main.o x.o y.o -o executable
  • Why do we need a Makefile?
    We need a Makefile if we don't want to bother ourselves by rerunning and retyping all the above shown commands each and every time we modify a tiny piece of code. Also since simply recompiling each and every file may consume a heavy amount of time depending on the code.

    Makefile contains the dependency graph of the desired files of a particular project. The program make checks the modification times of the files, and whenever a file gets edited more recently
    than something that depends "on" it, it runs the compiler accordingly.

    For example, if you edit y.c, it becomes "newer" than its previously created object file y.o.
    In this case, make runs:
    g++ -c y.cpp
    to create a new object file y.o, then runs
    g++ main.o x.o y.o -o executable
  • How to write a Makefile?
    Target is considered to be a file which will be created or updated when any of its source files are modified.

    Example: when a source file y.cpp is modified we need to recompile it so that the changes get reflected in its corresponding object file. So, here the target is the object file of the source
    file y.cpp.

    Target syntax:
    y.o : y.cpp xy.h
    If you do not explicitly include the header files in your Makefile, your program will not be updated if you make a change to your header (.h) files.

Makefile syntax:
  1. We need to combine the all the individual object files of all the individual source files and produce one target object file.
    Specification of the final target and the corresponding command need to be the first statements in the Makefile.

    In the below code finalObjectFile is the name of our object file which is the merger of all other individual object files.
    finalObjectFile: x.o main.o y.o
  2. We need to specify the usual compiler command which will take all the individual object files of all the individual source files and produce one target object file. The commands need to be started
    with a TAB.
          g++ x.o main.o y.o -o finalObjectFile
  3. We need to specify the target object file for the individual source files.
    We first specify the target and then its dependencies.
    x.o: source/x.cpp header/xy.h
          g++ -c source/x.cpp
    y.o: header/xy.h source/y.cpp
          g++ -c source/y.cpp
    main.o: header/x.h source/main.cpp
          g++ -c source/main.cpp
Posted in GNU Make
Views 836 Comments 0
« Prev     Main     Next »
Total Comments 0




All times are GMT -5. The time now is 08:36 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration