Building Projects for Linux

March 13, 2016

It is common belief that hacking (making your own program) for Linux is accessible to anybody with a computer. While there is no financial barrier to developing for Linux, I found that poor documentation makes developing for Linux an arduous task.

Here, I’ll share what I learned about building helloworld.c.

The basics

When making a single file c program, one is often taught to create a new directory and to create a new c file, typically called helloworld.c.

This can be achieved with the following commands:

~$ mkdir hello
~$ cd hello
~/hello$ touch helloworld.c

Now you can edit your helloworld.c file with your favorite text editor and add the following lines inside:

#include <stdio.h> // Include basic library that allows you to use functions such as printf

// All programs are required to return an error code, success = 0
int main(){
    printf("Hello world!\n"); // \n is a new line
    return 0; // return sucess (0). Anything else is considered an error code
}

helloworld.c is technically the only file you need to create your program. You can now compile it with

~/hello$ gcc helloworld.c -o helloworld

and run it with

~/hello$ ./helloworld

Makefiles

Saying that you only need a single file for a C program is almost akin to saying that you can write a website purely in HTML. While it is technically possible, it doesn’t make things easy to change nor does it make your tools portable to new projects.

One might tell you to create a Makefile in the directory containing something like:

all:
    gcc helloworld.c -o helloworld

clean:
    rm helloworld

To compile, you invoke the command make or make all. While to delete all generated files, you invoke the command make clean.

This all is nice, but what if you want to install it in a system directory? What are the system directories for your flavour of Linux? Should you install it in /bin, /usr/bin, /usr/local/bin, /usr/share/bin? What about uninstalling the program? These are all questions that have been asked, and answered, by previous Linux developer that had to take care to compile programs on all kinds of machines. This is where the Autotools come to play.

Getting fancy

I am largely following this tutorial that simplified autotools for me.

Typically projects will include a configure file and a Makefile. Unfortunately, these files need to abide by a large set of standards and check for libraries that could be located in many different directories and create outputs in the appropriate directories.

All these files have the same name

The idea behind the autotools is that you will create a 5 line file, to generate a file that is compatible with the large set of standards mentioned above. To base file, will typically have an additional extension .ac or .am for autoconf and automake respectively.

Getting started

To start using the autotools, you will have to create a file called configure.ac with the following:

AC_INIT([package], [version])
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_HEADERS([config.h])     # not even really needed
AC_PROG_CC                        # or AC_PROG_CXX
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

and a file Makefile.am

bin_PROGRAMS = helloworld
helloworld_SOURCES = helloworld.c

Now you are ready to start the compilation procedure:

~/hello$ autoreconf -fvi
~/hello$ ./configure
~/hello$ make

The first command generate the configure file. The second command generates the Makefile, and the third command generates your executable helloworld.