Autotools Linux : Served On The Platter #2

Monday, 10 March 2014
Autotools are a great way of packaging binary applications in Linux.The autotools need to be installed by installing the auto-tools-dev and other dependencies.It uses the old Makefile way for compiling the program and checking dependencies. Here in this we take a sample C program depending on wxWidgets and openGL and build the install scripts using Autotools.Note that the directory structure is as follows :
|___Canvas
           |____src [ the source folder ]
           |         |__paint.cpp
           |____res [ the resources and data ]

Autotools uses a predefined directory for installing files and these directories are named in the autotools site.For eg. $PREFIX stands for /usr/local/ hence when you write your program make sure to use these locations.

Autoscan: We use an automated tool to generate the initial configure.scan script. In the root directory run 'autoscan' command.This will generate a configure.scan and a report there by traversing through all the directories for dependencies. Now rename this to 'configure.ac' and edit it as follows.
 
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT([canvas], [1.0], [saswat.cs11@iitp.ac.in])
AM_INIT_AUTOMAKE([-Wall foreign])
AC_CONFIG_SRCDIR([src/paint.cpp])
AC_CONFIG_HEADERS([config.h])

# Checks for programs.
AC_PROG_CXX

# Checks for libraries.
AM_OPTIONS_WXCONFIG
reqwx=2.4.0
AM_PATH_WXCONFIG($reqwx, wxWin=1)
if test "$wxWin" != 1; then
 AC_MSG_ERROR([
  wxWidgets must be installed on your system.
 
  Please check that wx-config is in path, the directory
  where wxWidgets libraries are installed (returned by
  'wx-config --libs' or 'wx-config --static --libs' command)
  is in LD_LIBRARY_PATH or equivalent variable and
  wxWidgets version is $reqwx or above.
  ])
fi
 
CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY"
CFLAGS="$CFLAGS $WX_CFLAGS_ONLY"
LIBS="$LIBS $WX_LIBS -lGL -lGLU -lglut `wx-config --gl-libs`"

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL

# Checks for library functions.
AC_FUNC_MALLOC


AC_OUTPUT(Makefile src/Makefile res/Makefile)
 
Now notice the Macros in the section.AC_INIT initialize the package name and version and bug to send mail.AC_PROG_CXX checks for C++ in the system.We then check for wxWidgets in the system.This is present in their wiki for code above.Next add the FLAGS for compilation of librariesAC_OUTPUT checks for the Makefiles that should be generated as mentioned in brackets.Each must have a Makefile.am ready in them.

MAKEFILES: Each makefile.am should be as follows.In the source directory the Makefile is as follows:


bin_PROGRAMS = canvas
canvas_SOURCES = paint.cpp


The bin_PROGRAMS specifies the following binaries to be compiled and stored in the $PREFIX/bin directory.The _SOURCES specify the sources of the binaries.For the data directory the makefile should be as follows:

resdir = $(datarootdir)/@PACKAGE@
res_DATA = canvas.png chk.png crop.png curve.png erase.png ...


 We define a data directory according to the one used in the binary and the data files will be written to it.

COMMANDS: Once these files are ready run the following commands in order:
* aclocal
* automake --add-missing
* autoconf
* autoreconf -fvi
You will get your scripts.Run configure and make install to install.This project can be found in my github account :  https://github.com/saswatraj/Canvas

Overheads:Threads and Processes in C

Sunday, 25 August 2013
For creating processes in Linux we need to use the library available in Unix unistd.h . The normal process for creating a child process is as follows:

#include<stdio.h>
#inlcude<unistd.h>
int main()
{
      pid_t pid;   //the process id
      if(pid=fork()<0)
      {
          printf("Failed to create the childd process\n");
          exit(0);
       }
      if(pid==0)
       {
           //work to be done by the parent process
        }
      else
       {
           //the child process here
        }
     return 0;
}

To find out how much over overhead does this cost to the system let us create multiple child processes.This is usually done this way:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<unistd.h>
#include<assert.h>
#define NUM_PROCESSES 100

struct timeval t1,t2;

int main()
{
      pid_t pid[NUM_PROCESSES];
      int i;
      //clock_t start,stop;
      //double t=0.0;
      //assert((start=clock())!=-1);
      gettimeofday(&t1,NULL);
      for(i=0;i<NUM_PROCESSES;i++)
      {
         if((pid[i]=fork())<0)
       {
         perror("fork error\n");
       }
     else if(pid[i]==0)
       {
         //do work with the child
         printf ("[log]Created child process number:%d\n",i);
         exit(0);
       }
      }
      int status;
      pid_t rstatus;
      int n=NUM_PROCESSES;
      while(n>0)
    {
      rstatus=wait(&status);
      --n;
    }
      //stop=clock();
      //t=(double)(stop-start);
      //printf("Time taken ::%f\n",t);
      gettimeofday(&t2,NULL);
      printf("---------------time taken is::%ld----------------\n",t2.tv_usec-t1.tv_usec);
      return 0;
}

So we calculated the system time taken for creating 10 processes was : In micro seconds the total amount of time taken was about 15,441.To compare this to thread creation process we wrote a program with same number of threads as the number of processes i.e. 100 .Again we use the gettimeofday function to get the time taken for spawning the threads.The program for thread is as follows:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<time.h>
#include<assert.h>
#define NUM_THREADS 100

struct timeval t1,t2;

void *PrintCreated(void *threadId)
{
  long tid;
  tid=(long)threadId;
  printf("[log]Created thread with thread id::%ld\n",tid);
  pthread_exit(NULL);
}

int main()
{
  pthread_t threads[NUM_THREADS];
  int rc;
  long t;
  /*clock_t start,stop;
  double tt=0.0;
  assert((start=clock())!=-1);*/
  gettimeofday(&t1,NULL);
  for(t=0;t<NUM_THREADS;t++)
    {
      //printf ("[log]Creating thread %ld\n",t);
      rc=pthread_create(&threads[t],NULL,PrintCreated,(void *)t);
      if(rc){
    perror("Error creating thread\n");
      }
    }
  /*stop=clock();
  tt=(double)(stop-start);
  printf("Cpu time taken:%f\n",tt);*/
  gettimeofday(&t2,NULL);
  printf("--------------time taken :: %ld----------------\n",t2.tv_usec-t1.tv_usec);
  pthread_exit(NULL);
}


The time taken for generating NUM_THREADS was 9453 milliseconds.Hence spawning of threads is 1.63 times faster than spawning of processes because in creating threads we donot need to create the data space and other things because threads share the data.
Copyright @ 2013 code-craft. Designed by Templateism | MyBloggerLab