Introducing jSlider: A Content Slider plugin for JQuery

jSlider is a light weight JQuery plugin for content sliding. By content we mean everything: HTML code, Images, Advertisements etc etc. jSlider allows to put our content in simple <div>‘s, and then it automatically generates a content slider for you, which one can customize using various options provided.

Screenshot
Below is a screen shot of a content slider using jSlider:

jSlider

Download and Demo
jSlider is hosted at google code. Use the following links for demo and downloads:

Using jslider.jquery.js
Below is a sample html code which will be processed by jslider:

Sample input to jslider

    <div id="jslider">
      <div>
        <input type="hidden" value="Title for Content 1"/>
        <div>
          HTML Content # 1
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 2"/>
        <div>
          HTML Content # 2
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 3"/>
        <div>
          HTML Content # 3
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 4"/>
        <div>
          HTML Content # 4
        </div>
      </div>
      <div>
        <input type="hidden" value="Title for Content 5"/>
        <div>
          HTML Content # 5
        </div>
      </div>
    </div>

One must preserve the div structure as given in the example above. The hidden input values will be taken as heading for that block of content. If you want to have no heading or a common heading, fill this hidden input field appropriately.

Sample output from jslider

  <div id="jslider">
    <div class="slider">
      <h2>Title for Content 1</h2>
      <ul>
        <li class="selected">1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
      </ul>
    </div>
    <div class="content">
      <div class="block">
        <input type="hidden" value="Title for Content 1"/>
        HTML Content # 1
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 2"/>
        HTML Content # 2
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 3"/>
        HTML Content # 3
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 4"/>
        HTML Content # 4
      </div>
      <div class="block">
        <input type="hidden" value="Title for Content 5"/>
        HTML Content # 5
      </div>
    </div>
  </div>

Customizing jslider.jquery.js
jSlider provides following options for customization:

  1. width: Width of jslider div above, defaults to ‘610px’
  2. height: Height of jslider div above, defaults to ‘225px’
  3. slider_height: Height of slider div above (navigation bar), defaults to ’24px’
  4. content_height: Height of content div above, defaults to ‘180px’
  5. block_width: Width of block div inside content div’s above, defaults to ‘590px’
  6. block_padding: Padding of block div inside content div’s above, defaults to ’10px’
  7. animation_time: Time taken by 1 slide of content, defaults to 300 msec
  8. animation_type: Animation type, defaults to ‘linear’. Other option is ‘swing’

Rest of the options like various padding etc can be controlled using the css properties. View demo for more implementation details. This is my first jquery plugin and I am only 2 weeks old in jquery. If you find any bug or need any enhancement, you are most welcome.

Building a Custom PHP Framework with a custom template caching engine using Output Control functions

In past 1 year or so, I had opportunities of using a lot of php frameworks including zend, symfony, cakephp, codeigniter. All frameworks have their pros and cons, however that is out of scope of this blog post. You may want to checkout this comparison list of php frameworks here.

In this blog post I will build a custom PHP framework (MVC Architecture). Then go on to discuss in brief about the output control functions and finally show how to build a custom template caching engine using these functions for our framework.

Source Code
You may want to download the complete source code for this blog post from here.

Building a custom PHP Framework
We will choose a MVC architecture for our framework. Here is a basic directory structure for our custom framework:

/index.php
/.htaccess
/config.ini.php
/404.php
/view
    /view/test1.php
    /view/test2.php
/model
    /model/model.class.php
/controller
    /controller/controller.class.php
/log
    /log/logger.class.php
    /log/log.log
/cache
    /cache/cache.class.php
    /cache/template.cache.class.php
    /cache/template
        /cache/template/test1.php.tmp
        /cache/template/test2.php.tmp

The view, model, controller, log and cache directories contains the following framework modules respectively:

  1. view directory contains our view level files. i.e. files containing our HTML, js, css code.
  2. model directory contains the model class responsible for interacting with database and other storages
  3. controller directory contains our controller class. Each incoming request is first received by the controller class constructor, which thereafter controls the flow of request in the framework
  4. log directory contains our logger class. This class is auto loaded for every request providing a basic logger::log($log_message) logger method throughout the framework. This class logs all data in a file called log.log.
  5. cache directory contains our cache class. For this blog tutorial, we will only write the template caching engine class. In production systems, we might have individual classes for other types of cache systems e.g. memcached (Read Memcached and “N” things you can do with it – Part 1 to know more about memcached and MySQL Query Cache, WP-Cache, APC, Memcache – What to choose for a complete comparison lists of various other caching techniques.

Lets see in details, what all file each and every directory contain contains.

Root directory files
We have 4 files in our root directory, namely .htaccess, index.php, config.ini.php and 404.php in order of relevance. Lets look through the content of these files:

.htaccess

RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php
  1. 1st two lines essentially means that Switch on the apache rewrite module and set RewriteBase as / i.e. the root directory
  2. Last 3 lines mean that, if incoming request is for a file or directory which physically exists under the root directory serve them otherwise route all other requests to index.php in the root directory

Hence now for an incoming request like http://localhost/test1.php, apache will route the request to index.php in the root directory because there is no test1.php under the root directory. Cool, lets see what index.php has to offer.

index.php

<?php

  // include configuration file
  include_once("config.ini.php");

  // include controller files
  include_once("controller/controller.class.php");

?>

index.php doesn’t do much except for including our core configuration file and controller class file. Controller class constructor is initiated as soon as the class file is included.

config.ini.php is our core configuration file. It provides the framework with an array called $config containing various information like: mysql database credentials, requested url details and various other global parameters. Lets see what all parameter does it provide us with.

config.ini.php

<?php

  $config = array(
                  'host'=>array(
                                'name' => "http://".$_SERVER['HTTP_HOST'].'/',
                                'uri' => $_SERVER['REQUEST_URI'],
                                'url' => parse_url($_SERVER['REQUEST_URI']), // note it contains the parsed url contents
                               ),
                  'mysql'=>array(
                                 'host' => 'localhost',
                                 'name'=> 'testdb',
                                 'user' => 'root',
                                 'pass' => 'password',
                                ),
                  'cache'=>array(
                                 'template' => 'On', // template caching switched on by default
                                 'memcached' => 'Off', // switch off memcached caching
                                ),
                 );

?>

$config[‘host’] array saves various parameter about the host itself, e.g. hostname, hosturi (the requested uri, hosturl (it contains the parse_url(hosturi)).

$config[‘mysql’] array contains mysql database parameters. However in this blog post we will not interact with databases.

$config[‘cache’] tells the framework what all caching modules are switched on.

404.php

<html>
  <head>

  </head>
  <body>
    <h1>404 Page</h1>
  </body>
</html>

Controller directory files
For this blog post, controller directory consists of a single class file. i.e. controller.class.php. We saw this being included by index.php in the root folder above. As soon as controller class is included, it’s constructor is invoked. Before we dig in more, lets see the controller class file:

controller.class.php

<?php

  // include logger class
  include_once("log/logger.class.php");

  // include cache class (contains template caching)
  include_once("cache/cache.class.php");

  // include model class
  include_once("model/model.class.php");

  class controller {

    function __construct($config) {
        global $config;

        // generate requested template name and path
        $config['template']['name'] = $config['host']['uri'] == '/' ? 'index.php' : substr($config['host']['uri'], 1, strlen($config['host']['uri']));
        $config['template']['path'] = "view/".$config['template']['name'];

        // check 404
        if(!file_exists($config['template']['path'])) {
            $config['template']['name'] = "404.php";
            $config['template']['path'] = "404.php";
        }
        logger::log("Requested template name ".$config['template']['name'].", path ".$config['template']['path']);

        // invoke template caching engine
        $template_cache = new template_cache();

        // include the template
        include_once($config['template']['path']);

        // cache template
        $template_cache->setTemplate();
    }

  }

  $controller = new controller($config);

?>

At the top, controller class includes the logger.class.php, cache.class.php and model.class.php files. At the bottom, the controller object is instantiated.

The constructor performs the following 5 tasks:

  1. At first it generates a template name and a template path for the incoming request i.e. for http://localhost/, $config['template']['name']='index.php' and for http://localhost/test1.php, $config['template']['name']='test1.php'.
  2. Second it checks for 404. For the above generated template path, e.g. $config['template']['path']='view/test1.php', it checks whether this file exists inside root directory. If it doesn’t template path and names are set to 404.php
  3. Thirdly, It invokes the template caching engine. i.e. $template_cache = new template_cache();
  4. Forth, it includes the generated template path above i.e. include_once($config['template']['path']);
  5. Fifth and finally, it caches the generated HTML, js, css code by the template file includes above. This is achieved by the following code, $template_cache->setTemplate();

Before we move our attention to, lets see in short the content of log and view directories.

Log directory files
Log directory contains our logger class. This class is auto loaded for each incoming request that is being routed to index.php in the root directory (as we saw above). The logger.class.php provides a static logger::log($log_message) method, which can be used throughout the framework for logging messages. We will be using it everywhere.

logger.class.php

<?php

  class logger {

    static $log_file = "log/log.log";

    static function log($log) {
      if($log != '') {
        $fh = fopen(self::$log_file, "a");
        fwrite($fh,date('Y-m-d H:i:s')."n".$log."nn");
        fclose($fh);
      }
    }

  }

?>

The logger class by default logs all data to a file called log.log.

View directory files
For this blog post, we have two simple test pages in view directory namely test1.php and test2.php, which can be access by typing http://localhost/test1.php and http://localhost/test2.php respectively in the browser.

test1.php

<html>
  <head>

  </head>
  <body>
    <p>
      <?php echo model::test1data(); ?>
    </p>
  </body>
</html>

test1.php simply calls the model class method called model::test1data() (static method). This method extracts some dummy text from the database and returns it back.

Model directory files
Model directory contains the model class file. In production systems, model class file will provide various methods to select and insert data in the databases. However for this blog post we will simply return some static dummy test.

model.class.php

<?php

  class model {

    // This method will return data generally from a database table
    // To keep it simple for the post we return some dummy lipsum text
    static function test1data() {
      logger::log("Returning test1data() from database");
      return "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut nulla ac risus viverra ornare. Nulla consectetur, metus eleifend pharetra posuere, lacus nibh elementum leo, in fermentum lectus lorem in ipsum. Nullam pulvinar purus at erat pharetra volutpat. Pellentesque egestas rutrum lectus, ut rutrum tellus tristique sed. Integer diam est, ornare ac ultricies vel, aliquam non mi. Etiam tempor leo eu lacus tempus sagittis sagittis turpis dictum. Sed leo sapien, pharetra sit amet faucibus et, mollis id nulla. Praesent feugiat mi nec dui scelerisque mollis vehicula magna feugiat. Aliquam erat volutpat. Curabitur quis velit ut nibh rhoncus convallis. Proin mauris nunc, rhoncus vel laoreet vel, aliquet quis nunc. Aenean interdum risus non neque blandit sed adipiscing ipsum mollis. Vivamus enim orci, ultrices at scelerisque vel, laoreet a turpis. Nullam posuere ante sed nisl porta porta aliquam metus suscipit. Fusce enim odio, iaculis at suscipit eget, vestibulum volutpat enim. Nam dictum turpis quis velit posuere in malesuada mi convallis. Donec faucibus, felis id dictum imperdiet, orci tortor tristique neque, vitae lobortis libero tellus sed lorem. Duis tellus magna, commodo eget blandit ut, auctor nec nibh. Maecenas ornare ornare risus nec ultrices. Pellentesque lectus eros, imperdiet ut rhoncus vel, tempus ut nisi.";
    }

    static function test2data() {
      logger::log("Returning test2data() from database");
      return "Vestibulum laoreet nibh sed nulla mollis cursus. Maecenas sodales mauris sit amet ligula euismod a lacinia turpis adipiscing. Nulla gravida porta augue, id adipiscing libero tincidunt ac. Morbi non velit id odio porta tempus id eget massa. Cras nibh purus, gravida sed suscipit ut, tincidunt eu neque. In id est eros, ac sodales orci. Ut lectus augue, feugiat sit amet consectetur id, pharetra quis tellus. Maecenas eget lobortis urna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce tincidunt eleifend neque. Aenean accumsan orci vitae erat blandit porttitor. Aliquam tristique dolor ac nibh elementum id lacinia diam cursus.";
    }

  }

?>

Cache directory files
For this blog post, cache directory contains the main cache.class.php file which in turn includes various other cache classes e.g. template.cache.class.php

cache.class.php

<?php

  // check for switched on cache modules
  foreach($config['cache'] as $key => $value) {
    // include all cache classes, which are swicted on
    if($value == 'On') {
      // naming convention is <modulename.cache.class.php>
      include_once('cache/'.$key.'.cache.class.php');
    }
  }

?>

Output Control Functions
PHP is a very simple language. You can write a Hello World! code or calculate similarity between two strings (see similar_text()), both with a single line of code. And hence there are a lot of fundamental concepts of PHP, which not only beginners but even some advanced coders can ignore. One such concept is Output Control in PHP.

The Output Control functions allow you to control when the output of your PHP script will be thrown to the browsers (console). i.e. You can pre-process the final html output (append, prepend, chip-chop, inserting ad-codes, url linking, keyword highlighting, template caching), which will otherwise be thrown on the browser. Interesting, isn’t it? Can you feel the power of Output Control functions?

  1. ob_start: This turns on output buffering. i.e. no output is sent from the script, instead the output is saved in an internal buffer. However output buffering doesn’t buffers your headers. ob_start() also takes an optional callback function name. The function is called when output buffer is flushed (see ob_flush()) or cleaned (see ob_clean()). We can access the this internal buffer using functions like ob_get_contents()
  2. ob_end_flush: This function send the content of the buffer (if any) and turns off output buffering. We should always call functions like ob_get_contents() before ob_end_flush(), since any changes after this functions will not reflect on the browser

Building a custom Template Caching Engine
We saw above some of the output control functions PHP has to offer. ob_start(), ob_get_contents() and ob_end_flush(); are the 3 functions we will use to create our custom template caching engine.

template.cache.class.php

<?php

  class template_cache {

    var $template_cache_file = FALSE;
    var $template_cache_file_ext = ".tmp";
    var $template_cache_dir = "cache/template/";
    var $template_cache_ttl = 300; // secs

    function __construct() {

      // initiate template caching
      $this->init();

    }

    function init() {
      // get template path
      $this->template_cache_file = $this->generateTemplatePath();

      // get template from cache if exists
      $this->getTemplate();

      // start output buffering
      ob_start();
    }

    function generateTemplatePath() {
      global $config;

      // generate template file name
      return $this->template_cache_dir.$config['template']['name'].$this->template_cache_file_ext;
    }

    function getTemplate() {
      global $config;

      // check if a cached template exists
      if(file_exists($this->template_cache_file)) {
        if(time() - filemtime($this->template_cache_file) < $this->template_cache_ttl) {
          logger::log("Cache hit for template ".$config['template']['name']);
          $content = file_get_contents($this->template_cache_file);
          echo $content;
          exit;
        }
        else {
          logger::log("Cache stale for template ".$config['template']['name']);
          return FALSE;
        }
      }
      else {
        logger::log("Cache miss for template ".$config['template']['name']);
        return FALSE;
      }
    }

    function setTemplate() {
      global $config;

      // get buffer
      $content = ob_get_contents();

      // save template
      logger::log("Caching template ".$config['template']['name']);
      $fh = fopen($this->template_cache_file, 'w');
      fwrite($fh, $content);
      fclose($fh);

      // Flush the output buffer and turn off output buffering
      ob_end_flush();
    }

  }

?>

As we saw above in controller class, the template engine class was instantiated before including the actual template file. Template engine constructor do the following 3 tasks:

  1. Generate a cached file name for the requested uri by calling the $this->generateTemplatePath(); method. e.g. if http://localhost/test1.php is the requested uri, test1.php.tmp is it’s static cached template
  2. Secondly, it tries to fetch the cached template file by calling the method $this->getTemplate(); (read on for details of this method)
  3. Finally it turns on output buffering by calling ob_start();

List of methods provided by template.cache.class.php are:

  1. generateTemplatePath() method generates a cache file name for incoming request. By default extension of all cached files in “.tmp” and are stored under the /cache/template directory.
  2. getTemplate() method do a number of tasks. First, it checks if a cached template exists for the requested uri. If it does not exists or if it is not a fresh cache (see $template_cache_ttl), this method simply returns control back to controller which go ahead and include the actual template file. However if the file exists and is fresh it reads the content of the file and throw back to browser. At this point control is no longer transferred back to the controller, hence saving various un-necessary processing and database calls.
  3. setTemplate() method is called by controller after including the actual template file from under the view directory. Point to note is that, before getTemplate() returns control back to controller (in case of missed or stale cache), the template cache class constructor does switch on output buffering. And when setTemplate() method is called, we can access this buffer using output functions like ob_get_contents() and then save the template for next incoming request. Bingo!. Finally this method throw away the buffer to the browser using ob_end_flush();

Is it working?
To verify the flow of framework, I hit the url http://localhost/test1.php 3 times, with $template_cache_ttl = 10; (seconds).

  1. Once after clearing the template cache folder
  2. Once within next 10 seconds
  3. And finally after 10 seconds

Here is how the log file looks like:

2009-08-16 19:50:49
Requested template name test1.php, path view/test1.php (1st REQUEST)

2009-08-16 19:50:49
Cache miss for template test1.php

2009-08-16 19:50:49
Returning test1data() from database

2009-08-16 19:50:49
Caching template test1.php

2009-08-16 19:50:54
Requested template name test1.php, path view/test1.php (2nd REQUEST)

2009-08-16 19:50:54
Cache hit for template test1.php

2009-08-16 19:51:03
Requested template name test1.php, path view/test1.php (3rd REQUEST)

2009-08-16 19:51:03
Cache stale for template test1.php

2009-08-16 19:51:03
Returning test1data() from database

2009-08-16 19:51:03
Caching template test1.php

Moving forward, What’s Next? Extending template.cache.class.php
Template cache class can be extended to do a lot more, other than caching the template files. For instance we might want to perform (chip-chop, append, prepend etc) a few tasks, before we cache the final template and throw back to the browser. Few tasks which look quite obvious to me are:

  1. Short Codes: We can insert short codes in our HTML templates, which later on can be expanded into full fledged codes. e.g. For embedding a YouTube video, we can simply put something like [[YouTube yjPBkvYh-ss]] into test1.php. And in setTemplate() method we can call helper/plugin methods to process such short codes. More professionally, we can add hooks for various tasks we might want to perform before caching the template. Read How to add wordpress like add_filter hooks in your PHP framework for a more professional approach.
  2. Inserting page header and footer: Instead of including page header and footer inside test1.php, we can simply put our main <body> code inside test1.php. Then before caching the template file, we can append and prepend header and footer modules to the buffer of each page. Thus avoiding including the same header and footer files across various pages.
  3. HTML module caching: There are several instances where we can have a common module across all pages. For instance, I can have a events module across all my pages, which basically displays a calendar with various events for the week or month marked on it. The event details are extracted from the database. Since this module of mine is a static HTML chunk for atleast a week, I would like to have a difference cache for this module. Intelligently hooking up these modules with template caching engine, can allow us to do module level caching

I can probably write down 10-15 more such applications and probably there might be many more such applications of the above coded template caching engine. (Note: The power actually lies in Output Control Functions provided by PHP).

Let me know if you liked the post or any bug in it.

fixed.js – Solution to IE6 “position:fixed” Bug

IE6 has been a bane for all frontend developers for years. An element can be positioned relative to the browser window using the style position:fixed, it does not move when the page is scrolled. You can do nice layout things (e.g. facebook chat bar) with this in most modern browsers but not for IE6 in windows until you use fixed.js

Sample Code for Facebook Type Chat Bar

<html>
  <head>
    <style type="text/css">
      body {
        margin:0px;
        padding:0px;
        height:1600px;
        position:relative;
      }
      #shoutbox {
        position:fixed;
        background-color:#F2F2F2;
        border-top:1px solid #CCCCCC;
        bottom:0px;
        left:0px;
        width:100%;
        height:25px;
      }
    </style>
    <script type="text/javascript" src="fixed.js"></script>
  </head>
  <body>
    <div id="shoutbox">
      <!-- Our Shoutbox -->
    </div>
  </body>
</html>

The above code will show you a bar at the bottom of the page, which remains fixed at the bottom even if you scroll the page.

How does fixed.js help me?

  1. fixed.js is smart enough to invoke only if the browser is IE6 on Windows machine. This is achieved by these two lines of code in fixed.js.
    [email protected]_on
    @if (@_win32 && @_jscript_version>4)
  2. It specifically tells IE6 how to render elements with position:fixed attributes. Which are otherwise ignored by IE6.
  3. For remaining browsers, fixed.js go to sleep silently. Doesn’t do any processing.

Download fixed.js
fixed.js is developed and maintained at doxdesk.com. Click here to download fixed.js

Happy Coding!

How to generate random password like WordPress using PHP?

WordPress Blogging Engine is a champion in a lot of way. One of the unique thing which you might have noticed is the random password generated by the wordpress, in case you try to generate a new password. Here are a few examples:

  • j0LH(WM9b_-q
  • wr^sqct1cmff
  • )P4-e531#-aL

Lets have a look at the code which can generate such random passwords for us. Later on we will dig deep into the code to understand each and every bit of it:

<?php

  class utility {

    static $random = '';

    // generates a random password
    // By default of length 12 having special characters
    static function generate_password($length = 12, $special_chars=true) {
      $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
      if($special_chars) $chars .= '!@#$%^&*_-()';

      $password = '';
      for($i=0; $i<$length; $i++)
        $password .= substr($chars, self::generate_random_number(0, strlen($chars)-1), 1);
      return $password;
    }

    // generates a random number between $min and $max
    static function generate_random_number($min=0, $max=0) {
      // generate seed. TO-DO: Look for a better seed value everytime
      $seed = mt_rand();

      // generate $random
      // special thing about random is that it is 32(md5) + 40(sha1) + 40(sha1) = 112 long
      // hence if we cut the 1st 8 characters everytime, we can get upto 14 random numbers
      // each time the length of $random decreases and when it is less than 8, new 112 long $random is generated
      if(strlen(self::$random) < 8 ) {
        self::$random = md5(uniqid(microtime().mt_rand(), true).$seed);
        self::$random .= sha1(self::$random);
        self::$random .= sha1(self::$random.$seed);
      }

      // take first 8 characters
      $value = substr(self::$random, 0, 8);

      // strip first 8 character, leaving remainder for next call
      self::$random = substr(self::$random, 8);

      $value = abs(hexdec($value));
      // Reduce the value to be within the min - max range. 4294967295 = 0xffffffff = max random number
      if($max != 0) $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1)));
      return abs(intval($value));
    }

  }

  // print new random password
  echo utility::generate_password();

?>

Lets dig into the code
static function generate_password($length=12, $special_chars=true) is a static method of our utility class. It accepts two parameters. $length who’s default value is 12 and $special_chars who’s default value is true. By turning on $special_chars, our random generated password will include characters like !@#$%^&*_-()

static function generate_random_number($min=0, $max=0) is yet another static function of the utility class. It generates random number between $min and $max, the two parameters which can be passed. Default value for both is 0. However internally, generate_random_number() do a lot of trick to get us some really random numbers.

Algorithm
generate_random_number() works with following variables:

  1. $seed: which is equal to mt_rand()
  2. self::$random is a static variable. To start with this variable equals to ” (nothing). generate_random_number() checks for the length of self::$random. If its length is < 8, it generates a new 112 character long random value (see the code above) and assign it to self::$random. From here on, every time a random number is requested, it uses a chunks of 8 characters from the starting of self::$random, which is then used to generate a random number (see the code above). After each iteration length of self::$random decreases by 8. Because self::$random is 112 characters long, we can use it 14 times to get a random number (14×8 = 112).
  3. $value is the actual 8 digit character extracted from the starting of self::$random, which is later on processed to generate a random number between $min and $max values.

Further these methods can also be used to generate short url’s like tinyurl.com or bit.ly.

Getting started with Autotools – GNU Build System on Debian

The_GNU_logo
If you eat and drink open source, chances are high that you might have downloaded an open source project code, only to see files like: aclocal.m4, configure.ac, Makefile.am, Makefile.in and what not. You might have also used commands like ./configure, make etc but what are these files? Does they really belong to the project you download? Do I need to understand them? In this blog post I look forward to answer all your question, as well as introduce you to not so popular Autotools – A GNU Build System.

Setting up Autotools on Debian?
Before we go ahead and understand what Autotools is, we will try building a HelloWorld package. Lets get started by setting up Autotools on debian machine.

  • apt-get install build-essential
  • gcc –version (verifying install)
  • g++ –version (verifying install)
  • apt-get install automake autoconf

You have your environment ready. Lets start packaging the HelloWorld package.

Hello World Source Code
Download full source code from here

We will need to create 5 files for our basic HelloWorld package. Start by creating a directory structure like this:
HelloWorld
    — configure.ac
    — Makefile.am
    — README
    — src
        — Makefile.am
        — helloworld.c

src/helloworld.c

#include <config.h>
#include <stdio.h>

int main (void) {
    puts ("Hello World!");
    puts ("This is " PACKAGE_STRING ".");
    return 0;
}

Note we don’t have a config.h file but still we include it here. In actual config.h will be autogenerated by the autotools, when we build the package. Similarly, PACKAGE_STRING will be a pre-defined variable inside config.h.

src/Makefile.am

bin_PROGRAMS = helloworld
hello_SOURCES = helloworld.c

Here we tell the build system to generate a binary named helloworld using the sources defined below i.e. helloworld.c

Makefile.am

SUBDIRS=src
dist_doc_DATA=README

Here we give information about the various sub-directory. For a bigger project you might have a man directory, data directory etc. Also we tell the build to package README file with the build.

README

This is a demonstration HelloWorld package for GNU Automake.
Type `info Automake' to read the Automake manual.

configure.ac

AC_INIT([helloworld], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
 Makefile
 src/Makefile
])
AC_OUTPUT

Don’t leave the post on seeing the above file. We will go through each and every one of them. configure.ac contains a series of M4 macros that will expand to some shell code to finally generate the configure script. Autotools have utilities like automake and autoconf (details below) which read this file to generate intermediate and final build files. The variables starting with AC_ are Autoconf macros and those starting with AM_ are Automake macros.

  1. AC_INIT: Initializes autoconf. It takes 3 input parameters: Name of the package, Version of the package and Contact address for bug reports
  2. AM_INIT_AUTOMAKE: Initializes automake. It can take a number of available input parameters. -Wall -Werror specifically tells automake to turn on all warnings and report them as error. While development we will keep error reporting turned on. foreign tells automake that this package doesn’t follow GNU standard. As per GNU standards we should also distribute files like ChangeLog, AUTHORS and at this stage we don’t want automake to complaint about them.
  3. AC_PROG_CC: This line tells configure script to search available C compilers and define variable CC with its name. Later on many intermediate files will use this variable CC for building binary files.
  4. AC_CONFIG_HEADERS: It tells the configure script to generate a config.h file which is pre-included by helloworld.c. Generated config.h will have content like this:
    /* config.h.  Generated from config.h.in by configure.  */
    /* config.h.in.  Generated from configure.ac by autoheader.  */
    
    /* Name of package */
    #define PACKAGE "helloworld"
    
    /* Define to the address where bug reports for this package should be sent. */
    #define PACKAGE_BUGREPORT "[email protected]"
    
    /* Define to the full name of this package. */
    #define PACKAGE_NAME "helloworld"
  5. AC_CONFIG_FILES: This tells configure script list of files from which it should generate it’s *.in templates. This variable is also used by automake utility to know list of Makefile.am it should process. (Note: Each directory should have a Makefile.am file and as you keep adding new directories keep adding them to AC_CONFIG_FILES, else build will not consider your new directories while building packages.
  6. AC_OUTPUT: It is a closing command that actually produces the part of the script in charge of creating the files registered with AC_CONFIG_HEADERS and AC_CONFIG_FILES.

Building a Hello World package for distribution
Lets create our first package for distribution.

  1. cd path/to/helloworld/directory: Migrate to the project directory
  2. autoreconf –install: This command initiates the build system. You should see something like this as output:
    configure.ac:2: installing `./missing'
    configure.ac:2: installing `./install-sh'
    src/Makefile.am: installing `./depcomp'
    

    Also if you scan through the HelloWorld directory, you will find a lot of new files being generated by the build system. Particularly you will see a Makefile.in being generated for each Makefile.am. Apart from these files of interest are configure and config.h.in.

  3. ./configure: It utilizes *.in files generated by the previous step to build the Makefile, src/Makefile and config.h. You should see something like this on your console:
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... no
    checking for mawk... mawk
    checking whether make sets $(MAKE)... yes
    checking for gcc... gcc
    
  4. make
  5. src/helloworld: This will output this on the console.
    Hello World!
    This is helloworld 1.0.
  6. make distcheck: This utility finally creates the helloworld-1.0.tar.gz package for distribution. You should see this on your console on running this utility:
    ================================================
    helloworld-1.0 archives ready for distribution:
    helloworld-1.0.tar.gz
    ================================================

Installing distributed HelloWorld package

  1. Copy the generated package into your temp directory and then issue the following commands
  2. tar -xzvf helloworld-1.0.tar.gz
  3. cd helloworld-1.0
  4. ./configure
  5. make
  6. make install

make install will copy the helloworld binary into the /usr/local/bin directory. Try running helloworld from command line and you should see a similar output, as we saw above while building the package. Further it also copies the README file under /usr/local/share/doc/helloworld directory. If your built package includes the man directory, it gets copied to /usr/local/share/man automatically.

What is Autotools?
Autotools is a build system developed by GNU which helps you distribute your source code across various Unix systems. The files you are wondering about are auto generated by the Autotools.

Autotools is a combination of several utilities made available by GNU, including:

  1. Autoconf
  2. Automake

There are many others which can be listed above, but for this blog post we will restrict ourselves to Automake and Autoconf only.

Autoconf
autoconf process files like configure.in to generate a configure script. When we run the configure script, it reads other template files like Makefile.in to generate a final output file, in this case Makefile

Automake
It reads all Makefile.am and generate corresponding Makefile.in, used by the configure script as described above.

Happy Packaging!