Self Teacher – my first iPhone app available in App Store

Published on: Sunday, August 5th, 2012 by tomasz

Recently my first iPhone app was released in App Store. The application allows you to learn vocabulary or almost anything with various types of exercises (multiple choice, type in, cards). It monitors your progress schedules, repetitions and allows to download lists of your words from Google Spreadsheet. Application is available in English and Polish.

Link to application in App Store: Self Teacher

   

More info


Ubuntu 11.4 installation from USB on MacBook Air

Published on: Tuesday, July 5th, 2011 by tomasz

Installing Ubuntu on a MacBook Air which has no CD drive is a tricky task. First of all it is impossible to boot from the USB stick created in Ubuntu, secondly even if you manage to boot from it, the installer will fail as it tries to read from /cdrom anyway.

Some time ago I found the following thread which described step by step procedure of generating bootable USB stick, recognized as CD drive. In order to make it working, you have to download and extract the mkhybridiso.tar.gz (from the above page) and remaster your Ubuntu ISO with the following command:

tar xvf mkhybridiso.tar.gz
cd mkhybridiso
sudo ./mkhybridiso.sh /PATH/your-ubuntu.iso

After some time a hybrid ISO is generated (with ‘hybrid’ suffix), when this is done, copy the ISO onto USB stick:

sudo dd if=your-ubuntu_hybrid.iso of=/dev/sdb bs=1M

Note that /dev/sdb corresponds to your USB drive identifier (you can get the proper name by executing dmesg | less just after inserting the USB stick).
When USB stick is ready, you can reboot the MBA and start the installer (for example via rEFIt). It is very probable that the installation hangs on a black screen. In order to avoid that make sure that you add “nomodeset” parameter to the initializer list, just before invoking the installer from the purple menu. If all steps are accomplished the installation should end with success.

Unfortunately, the above procedure doesn’t work well when we have already installed Ubuntu (hence GRUB as well) and we want to boot again from the same Ubuntu USB installer. It doesn’t matter how many times the Mac is restarted you will always end up with rEFIt executing GRUB and Ubuntu from the HD.
In this specific situation, in order to start up from the USB stick installer you may try invoking GRUB command line (by pressing ‘c’ i the GRUB menu).
When GRUB prompt starts, try executing the following:

root (hd1)
set gfxpayload=keep
linux /casper/vmlinuz file=/cdrom/preseed/ubuntu.seed boot=casper only-ubiquity nomodeset --
initrd /casper/initrd.lz
boot

If the sequence is executed correctly, the Ubuntu installer should start booting.


GList iterate and remove pattern

Published on: Thursday, March 31st, 2011 by tomasz

When I checked my blog’s Google Analytics stats, I noticed that someone looked for a way to iterate over a GList and remove its elements at the same time.
This is quite a common problem assuming that you deal with some objects appended to the list. The object can have some expiration timeout or can be marked for lazy removal. An independent process can loop through the list from time to time and remove those marked for releasing. This simple code should do the thing:

/* Set the iterator to the beginning of our list */
GList *node_itr = priv->_list;
while (node_itr != NULL)
{
   GObject *obj = (GObject *)node_itr->data;
   /* Store next element's pointer before removing it */
   GList *next = g_list_next(node_itr);
   /* Some dummy removal condition */
   if (my_gobject_marked_for_removal(obj))
   {
      g_object_unref(obj);
      priv->_list = g_list_delete_link(priv->_list, node_itr);
   }
   node_itr = next;
}

Migration to Xcode 4 – one problem…

Published on: Monday, March 28th, 2011 by tomasz

I’ve bought Xcode 4 from App Store recently and I’ve given it a try. I had some existing CocoaTouch projects created in Xcode 3 and wanted to run them with a new version of environment. The migration was supposed to be seamless, but I experienced the following crash when starting the app.

2011-03-28 11:21:43.411 RacerApp[1209:201]
*** Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason:
'Could not load NIB in bundle: 'NSBundle
</Users/tomasz/Library/Application Support/
iPhone Simulator/4.3/Applications/
17A6CD23-4CDE-17A6-B111-ED0A03EA177A/RacerApp.app>
(loaded)' with name 'MainWindow''

The following post suggested some of the reasons of that failure. I managed to get it working by following only one step, which is simply removing all XIB files from the project and adding them back from Xcode 4. To do that, select a single XIB file in the left pane of Xcode, right click on it and select Delete from pop up menu, in the dialog choose Remove Reference Only. Repeat the step for all XIB files and then add them back with Add files to YourProjectName…

Note: You can arrange the XIB files into groups with New Group from Selection.

It seems that Xcode 4 had some problems with determining location of XIB files in projects created from older versions of Xcode. Luckily it could be fixed quite easily.


Emacs Elisp macro for generating GObject from template

Published on: Saturday, February 5th, 2011 by tomasz

Everyone who has worked with GObjects knows how time consuming is to create a new GObject. In order to make it working you have to generate lot of boilerplate code which is more or less the same for all the objects.
In most of the cases people tend to use templates and make several find-replace substitutions to generate the output GObject.

To simplify everything and to learn more about Elisp I decided to build simple Elisp macros for generating GObjects directly from the Emacs command line. The script prompts for some basic info, like name of the final object (ex. MyExtremelyUselessObject), the output directory where the object is to be generated and some brief description of the object (for Doxygen purpose). While preparing templates I tried to follow GObjects name conventions and used Doxygen for documenting the source code (I know that probably GTK-Doc would be better but in all my current projects I use Doxygen so I know it better). The the set of macros can be downloaded from here: emacs-gobject-macros.tar.gz , a detailed installation instruction is inside the Elisp script. Note, that this script can also generate some kind of C-Objects based on normal C-struct’s.
If you happen to make some useful modification to the script, please let me know!


My first useful Elisp script

Published on: Thursday, February 3rd, 2011 by tomasz

It’s already been one year since I switched from Vim to Emacs (thanks Aleksander;) I heard a lot about how powerful the Elisp is, but I didn’t have much motivation in learning it. I started playing with Elisp last weekend and I must say that is much different from everything I used before. Anyway because I work a lot with GObjects and Glib I decided to create some useful script which will speed up my coding. My first script is trivial but it helps to create GList iterator, it acts as a simple code snippet with this difference, that the initial position of the iterator is assigned with the identifier under the cursor.

Elisp script:

(defun azt-glist-iterate-all()
    "Creates a GList iterator for
      the list under the cursor"
    (interactive)
    (setq itr_template "GList *node_itr = vvv;
while (node_itr != NULL)
{
    /* GType *data = (GType *)node_itr->data; */
    node_itr = g_list_next(node_itr);
}")
    ; Replace patter with a word at point
    (setq initializer
             (replace-regexp-in-string "\*" "" 
                   (thing-at-point 'symbol)))
    (setq itr_template 
             (replace-regexp-in-string "vvv" 
                     initializer itr_template))
    (forward-line 1)
    (insert itr_template)
)

When the script is loaded into Emacs and you start typing something like “GList *my_list = priv->_list” , put your cursor on my_list identifier and M-x azt-glist-iterate-all you will generate the snipper below:

GList *node_itr = my_list;
while (node_itr != NULL)
{
    /* GType *data = (GType *)node_itr->data; */
    node_itr = g_list_next(node_itr);
}

Mounting ext3 partition on OS X 10.6 (Snow Leopard)

Published on: Sunday, January 30th, 2011 by tomasz

Recently I’ve faced some problems with mounting a large (~ 850 GB) ext3 partition on OS X 10.6. I didn’t except any difficulties as I have already mounted ext2 or 3 partitions on my MBP running Leopard. Normally it could be easily done with Macfuse and fuse-ext2 extension. Unfortunately in this specific case it simply didn’t work. I have realized that I’m running a 64-bit version of Snow Leopard and Macfuse is only officially delivered for 32-bit architecture. This explained a lot! I managed to find an unofficial 64-bit compilation of Macfuse which could be downloaded from Tomas Carnecky blog. I installed the 64-bit version and used the old fuse-ext2 plugin, unfortunately when trying to mount the ext3 partition I got the following error:

$fuse-ext2 /dev/disk2s2 /Volumes/Private/

fuse-ext2 /dev/disk2s2 /Volumes/Private/fuse-ext2: version:’0.0.7′, fuse_version:’27′ [main (../../fuse-ext2/fuse-ext2.c:324)]
fuse-ext2: enter [do_probe (../../fuse-ext2/do_probe.c:30)]
fuse-ext2: Error while trying to open /dev/disk2s2 (rc=16) [do_probe (../../fuse-ext2/do_probe.c:34)]
fuse-ext2: Probe failed [main (../../fuse-ext2/fuse-ext2.c:340)]

After googling a little bit, I discovered that this error could be caused by some conflict with previously installed ext2fsx. During my small fight with Snow Leopard and ext3 I tried several possibilities and I totally forgot about them. It seemed that ex2fsx might have caused some conflicts with Macfuse. After uninstalling the ext2fsx the drive could be successfully mounted with the command mentioned above.
FYI, the ext2fsx can be easily removed by using uninstallation script delivered in the dmg package. Also when you mount the device make sure that you specify it correctly by referencing to corresponding /dev/diskXXX. The exact name of the device can be read from the Disk Utility application (right clicking on the partition and selecting “Information”)

Note, that the name of fuse-ext2 may suggest that only ext2 partitions are supported, fortunately both ext3 and ext4 partitions should work correctly as well.


My new project GRepoApplet

Published on: Wednesday, October 20th, 2010 by tomasz

I’ve been not writing here for more than a year. I was quite busy with other things and in the mean time I moved my blog to another provider. Just to make some update – recently in my free time I’ve been working on a GNOME Panel Applet for monitoring status of version control systems. The project has been just released in Launchpad. If you are interested you can checkout the latest source code and post me a comment:
https://launchpad.net/grepo-applet

The applet is really simple and still lacks certain functionality. I’ve defined some blueprints of what is to be implemented soon. If you have any ideas or comments feel free to contact me directly here or simply issue some bug on Launchpad.

Screenshots:

More info


Boost ptr_map iterator incompatibility

Published on: Tuesday, August 11th, 2009 by tomasz

Boost library provides a very powerful set of data structures and algorithms which are intended to be cross platform and rather concise. Unfortunately it happens, that the API of the library changes from version to version. The problem which I faced recently was related to ptr_map container iterator and different methods allowing for accessing keys and values of the container. In boost <=1.33 the mentioned fields could be accessed via iterator->key() and (*iterator) methods respectively. Starting from version 1.34 the authors of the library introduced approach which is compatible with map container from STL and uses iterator->first and iterator->second fields.

Unfortunately I was forced to use different platforms for development (Ubuntu 9.04 – Boost 1.39) and deploying (CentOS 5.3 with Boost 1.33), that’s why some problems appeared.
In order to solve them I used some conditional compilation tricks and some basic AutoConf routines.

First of all in configure.ac file I added the following condition, which tries to compile a given instruction using ptr_map iterator from Boost > 1.33.
If it succeeds the HAVE_PTR_MAP_ITR_SECOND value is defined in config.h file and we are sure that the platform supports STL compatible method of accessing map entries.

AC_TRY_COMPILE(
[#include ],
[boost::ptr_map::iterator itt;int *i=itt-&gt;second;],
AC_DEFINE(HAVE_PTR_MAP_ITR_SECOND,1,
[ptr_map::iterator defines second field]))

Later I created a short macro which will be replaced with appropriate code depending on the HAVE_PTR_MAP_ITR_SECOND condition:

#ifdef HAVE_PTR_MAP_ITR_SECOND
#define ptr_map_itr_second(s) ((s)-&gt;second)
#else
#define ptr_map_itr_second(s) (&amp;(*s))
#endif

The exemplary code showing application of the created macro can be found below:

...
ptr_map::iterator it;
it = ports_map_.find("key");
 
if (it != ports_map_.end())
{
  OffPortRange *port_range =  ptr_map_itr_second(it);
  ....
}

Sindbad PV – Photovoltaic System Designer

Published on: Friday, July 17th, 2009 by tomasz

I’ve added a new project on which I worked last year with my friends Krzysztof Olczyk and Alexi Akl.
The software can be used by amateur photovoltaic system designers in order to simulate the efficiency and benefits of photovoltaic systems in various geographical locations and surroundings (such as buildings, mountains, trees etc). If you are interested in the software please contact one of the authors.

More details


Random number generator based on normal distribution with Boost

Published on: Sunday, April 26th, 2009 by tomasz

Yesterday I was looking for some random number generator, based on gaussian distribution. As I don’t like to reinvent the wheel, I started to look for some already existing solutions. I found out that Boost library provided a very powerful engine for generating random numbers using various algorithms. The whole description of Boost Random Number library is available here.

For those who are looking for already existing solutions I attach a small snippet, which generates random numbers basing on the normal distribution. As typical for gaussian distribution, the algorithm takes two parameters: mean value and sigma(variance).

#include <boost/random.hpp> 
....
 
double 
GetRandomDoubleUsingNormalDistribution(double mean,
                    double sigma)
{
 typedef boost::normal_distribution<double> NormalDistribution;
 typedef boost::mt19937 RandomGenerator;
 typedef boost::variate_generator<RandomGenerator&, \
                         NormalDistribution> GaussianGenerator;
 
  /** Initiate Random Number generator with current time */
  static RandomGenerator rng(static_cast<unsigned> (time(0)));
 
  /* Choose Normal Distribution */
  NormalDistribution gaussian_dist(mean, sigma);
 
  /* Create a Gaussian Random Number generator
   *  by binding with previously defined
   *  normal distribution object
   */
  GaussianGenerator generator(rng, gaussian_dist);
 
  // sample from the distribution
  return generator();
}

New Fuzzy Logic project added

Published on: Wednesday, April 15th, 2009 by tomasz

I managed to add one of my old projects, which I wrote for an Artificial Intelligence course, while studying in Windesheim University of Applied Sciences.
It is a fuzzy logic controller with parser and different controlled processes. As I remember the code is written in such a manner that it should be rather easy to plugin new processes and manage their behavior with my controller.
Of course one has to define certain rules and store them in a knowledge base. The parser of knowledge base file is rather advanced, therefore even complex rules can be defined.

Application can be found in Projects section.


New OpenMPI projects added

Published on: Sunday, March 1st, 2009 by tomasz

After a longer break, I added two projects I had done in the last three months. You can find them in Projects section.
The assignments were related to distributed programming using OpenMPI library. The first one is an implementation of a well known Game of Life, the other one performs a distributed calculation of Laplace equation with a predefined boundary conditions.
Feel free to modify my code, if you achieve some nice or unexpected results don’t hesitate to contact me.


GObject and protected fields – simple hack

Published on: Sunday, December 21st, 2008 by tomasz

Not so long ago I wondered how to add some protected fields into one of my GObject. Those of you who have more experience with Glib and GObject should know a very popular construct allowing to define and then add a private structure to a GObject class definition (with g_type_class_add_private).
As opposed to that, there is no such an easy mechanism which simplifies adding protected fields. Unfortunately when we use inheritance and virtual methods sometimes this can lead to some inconvenience and a lot of boilerplate code (which btw. in case of GObject library can reach a significant number of lines)

I tried to search over the net, but I couldn’t find any solution to this problem. Having no better solution I invented a simple “hack” that mixes the behavior of both private and public fields. Together with some naming conventions it allows to simulate some kind of protected mechanism. Of course the word protected has more intuitive meaning because it violates a lot of constraints that must be satisfied in a real OOP language.
The main problem in implementing protected mechanism in a GObject is the scope and visibility of the protected fields. It is impossible to define them in the source file, because then the implementation will be hidden in all the derived GObjects. That’s why I decided to move it into a header file and wrap all the fields into a struct similar to the one used to define private fields.

/** Struct representing protected fields of a class */
typedef struct
{
    /* Some protected fields */
    guchar *_raw_header;
    guint     _raw_header_size;
    ....
} MicGenericObjectProtected;

Moreover the header file should contain the macro definition allowing to access protected fields from other derived objects. This can be done with the following line:

/** Getter for protected data of an object **/
#define MIC_GENERIC_OBJECT_GET_PROTECTED(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
  MIC_GENERIC_OBJECT_TYPE, MicGenericObjectProtected))

Now it’s time to move into source code of GObject class.
In the class_init function we add the protected structure into class definition with previously mentioned g_type_class_add_private function.


The code can be similar to the one below:

static void
mic_generic_object_class_init (MicGenericObjectClass *klass)
{
 GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
 /** Add private structure to the class **/
g_type_class_add_private (klass,                             \
                          sizeof (MicGenericObjectProtected));
 
object_class->dispose = mic_generic_object_dispose;
object_class->finalize  = mic_generic_object_finalize;
 
/** Virtual public methods with their implementations **/
....
/** Abstract Method */
....
}

That’s everything. This hack is not perfect because it doesn’t allow to easily add both private and protected fields in a single GObject. Remember that g_type_class_add_private can be called only once! The other problem is that protected fields are public to all other code and in fact they can be used from arbitrary object or function. That’s why I decided to implement some kind of naming convention (“protected” suffix) which highlights that a given collection of fields can be used only by derived objects. Of course it is not a protection, it’s more like an information to the programmer. It’s his decision whether he takes it into consideration or not.


Ubuntu 8.10 Fixed problem with sound

Published on: Monday, November 10th, 2008 by tomasz

In my previous post I wrote about a strange bahavior of my freshly installed Ubuntu. One of the problems was related to sound. I managed to get it working. It came out that something had muted the PCM channel of my sound card. ( while updating from Ubuntu 8.04)

You can fix it by right clicking on the “Sound” icon next to menu bar, choosing “Open Volume Control” and moving up the slider next to PCM label.

I read on some boads that it’s quite a common issue on Ubuntu 8.10, and quite a lot of people had problems with that. I hopy that this “silly” solution might help someone.


Ubuntu 8.10 first (bad)impression

Published on: Saturday, November 1st, 2008 by tomasz

Yesterday I found out that a new version of Ubuntu was released. Unfortunatelly I’m always excited in all the latest products and want to test them as fast as possible. That’s why I started to google for the safest and quickest possible way to upgrade.
My previous version of Ubuntu was 8.04 TLS, so I had to change some option in Software Sources dialog in order to make visible the latest version of Ubuntu.
I don’t know if you knew that but by default in Ubuntu only upgrades to “Long term” releases are performed. If you want to upgrade from 8.04 TLS into 8.10 you have to switch to “Normal releases” in Software Sources dialog.

If you need more details about this topic you can find it on the following web page: http://www.ubuntu.com/getubuntu/upgrading

Ok, but what I’ve written so far is not related to my impressions, so here I start:

Installation

My Update Manager had to work really hard and upgrade more then 1300 packages. All in all it took me about 1:20 h for downloading all of the files (on 2Mb/s connection) and then additional 30-40 minutes for unpackaging and setting them up. Unfortunately I started very late in the evening because I didn’t expect that it would take such a long time. Finally I ended up at 2:30 A.M.

First reboot

Although the installation took me some time, I didn’t have much problems with that. But when I restarted the computer the series of strange things started to happen.

Long startup
First of all the system initialized for more than 5 minutes. In the beginning I thought that it just hanged. But then it came out that the problem was related to ALSA demon which did not respond for the certain amount of time. After a given timeout it was killed by the system. That caused another problem which resulted in no support for sound.

No Sound – problematic ALSA
I managed to solve the startup problem temporarily by blocking ALSA daemon. But what’s obvious it didn’t help with the sound:( I guess that the new kernel that was installed in the system might cause some conflict with the sound card or sth.

NVIdia and Compuz Fusion
Another problem, that I faced, was related to Compuz Fusion and NVidia drivers. Fortunately all these eye-catching effects work, but sometimes I observe a strange behavior of my window title which blinks and disappear without any reason. This can be seen on pictures below (look at the right top of windows):

 

I can easily reproduce that strange behavior when the window is deactivated (should be transparent) and then activated by moving mouse cursor over the maximize button.

Firefox

Another problem was related to Firefox. My Adobe Flash plugin stopped working. Firefox claimed that it was not installed, but when I wanted to do that it complained that it’s already installed:) Strange. I had to fix it by removing the plugin manually using apt-get and then reinstalling it back using Firefox.

Summary

To sum up my first impressions with new Ubuntu 8.10.
I must admit that at a first glance it’s hard to see any outstanding and innovative modifications in GUI. In my opinion that should at least influence system stability and reliability. Unfortunately even in this matter I’m not fully satisfied. Maybe my requirements are too high?? Thanks to previous releases of Ubuntu I got used to Linux which works perfectly just out of the box. For me in 8.10 this most crucial rule was violated:(((


AutoTools, tar and paths longer than 99 characters

Published on: Thursday, October 16th, 2008 by tomasz

I tried to build a Debian package for the project I am currently working on. Unfortunately all the paths I used in the structure of my application were very long. While executing make dist command I got lots of errors similar to the one below:

wzt-poc2/media-server/src/[....]wzt-children-manager/tests/: file name is too long (max > 99); not dumped

I found out that the error is due to the tar archiver. It does not support file names (in fact “paths”) longer than 99 characters. This problem can be easily solved by forcing AutoTools to use POSIX version of tar which does not have this limitation.

It is enough to modify a configure.ac file in the following way:

AC_INIT([your-application-name], [0.1.0])
....
AM_INIT_AUTOMAKE([1.9 tar-ustar])

The crucial part is inside the AM_INIT_AUTOMAKE declaration which changes the default tar archiver.


Making Debian library package with dh_make

Published on: Sunday, October 12th, 2008 by tomasz

This post is a short introduction to building *.deb packages using dh_make & dpkg_buildpackage tools.

Let us assume that we want to make a Debian package for a simple library. We are going to create two *.deb files, due to the fact that in Debian-based operating systems, libraries are usually distributed in one of the two forms:

  • dev package – containing both library binaries and header files for programmers. Used mainly by the developers.
  • standard package – storing only the library binaries

Having that in mind, we should start our work from downloading necessary utilities:

apt-get install dpkg-dev dh-make debhelper devscripts pbuilder fakeroot

Next step is to set a proper name for the directory containing the source code of the library.
It should have the following pattern: <package>-<version> ( ex. mylib-0.1.0 )
Inside that directory we execute a command generating files describing the content of the package:


dh_make -l

where “l” stands for library

We can notice that a new directory “debian” was created. It contains several files, the most important are described below:

  • changelog – Changelog for the package from which a number of the latest version is taken
  • control – File containing package description and its dependencies
  • rules – Script responsible for generating package (similar to make)
  • mylib1.install – List of directories containing files which should be copied to the package (normal package)
  • mylib-dev.install - Similar as mylib1.install but related to development package

Just to make it look better, let’s rename all “mylib1*” files into “mylib*” and then delete unnecessary *.EX and *.ex files. (these files are used in more complex packages, for example involving rc.init script modifications)

Exemplary content of the mentioned files is presented below:

debian/changelog

mylib (0.1.0-1) unstable; urgency=low
 
* Initial release
 
-- TG &lt;myemail@x.com&gt;  Fri, 05 Sep 2008 17:40:45

debian/control

Source: mylib
Priority: extra
Maintainer: TG &lt;myemail@x.com&gt;
Build-Depends: debhelper (&gt;= 5)
Standards-Version: 3.7.2
Section: libs
 
Package: mylib-dev
Section: libdevel
Architecture: any
Depends: mylib (= ${Source-Version})
Description:  myITcorner.com Sample Library  (dev)
Development files.
 
Package: mylib
Section: libs
Architecture: any
Depends: libglib2.0-0 (&gt;= 2.6), openssl (&gt;= 0.9)
Description:  myITcorner.com Sample Library.
Binary package

mylib.install
Copy all the libraries from usr/local/lib

usr/local/lib/lib*.so.*

mylib.install
Copy all the libraries (also dev files) and C headers

usr/local/include/*
usr/local/lib/lib*.a
usr/local/lib/lib*.so
usr/local/lib/pkgconfig/*
usr/local/lib/*.la
usr/local/lib/pkgconfig/*

debian/rules
Content of debian/rules script is more complex and in most of the situations we can base our package on the file generated by dh_make utility. However, some minor modifications presented below should be introduced:

...
#Configure and compile library from the
#source code and install it into temporary location
install: build
	dh_testdir
	dh_testroot
	dh_clean -k 
	dh_installdirs
 
	# Add here commands to install
        # the package into debian/tmp
	$(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
 
# Build architecture-dependent files here.
binary-arch: build install
	dh_testdir
	dh_testroot
	dh_installchangelogs ChangeLog
	dh_installdocs
	dh_installexamples
	dh_install --sourcedir debian/tmp

It’s worth mentioning that a structure of the above file is similar to Makefile script. There are some tasks and their dependencies. For example in install task a library is compiled and then installed into debian/tmp directory. Later in binary-arch, a Debian package is generated from the compiled data taken from debian/tmp directory.

Building the package

Package description and configuration files are ready. So how to make a *.deb files? For that purpose we can use the following command:

dpkg-buildpackage -us -uc -rfakeroot

But let’s make it simpler. Why not to add an entry in a Makefile, just to have everything in one place?
Assuming that we are using Autotools, here is the most interesting part of Makefile.am.

Makefile.am

pkg-deb: dist
	- rm -rf  $(TMP_DIR)
	mkdir -p $(TMP_DIR)
	mv $(PACKAGE)-$(VERSION).tar.gz $(TMP_DIR)/
 
	tar --directory $(TMP_DIR)/ \
         -xf $(TMP_DIR)/$(PACKAGE)-$(VERSION).tar.gz
 
	cd $(TMP_DIR)/$(PACKAGE)-$(VERSION)/; \
                ./configure; \
                dpkg-buildpackage -us -uc -rfakeroot; \
                mv ../*.deb $(PWD)/pkg/
 
	rm -rf $(TMP_DIR);

In such a way a new task pkg-deb was defined. It executes another task called dist, which makes a tarball of the library source code. Later dpkg-buildpackage is called and just to clean everything up, some files are either removed or renamed.

It is important not to forget about including debian directory in the tarball generated with dist task. It can be done by adding the following line somewhere at the top of the Makefile.am:

EXTRA_DIST = debian

By the way TMP_DIR stores a location of the directory for the library installation files. In my case I assumed that

TMP_DIR = tmp

Now it’s enough to invoke:


make pkg-deb

Debian packages should be created inside pkg directory.

References:
Debian New Maintainers’ Guide
Andy Balaam’s Blog


Comments are enabled!

Published on: Sunday, September 7th, 2008 by tomasz

I forgot to enable a feature allowing for commenting my blog entries. I fixed it, so if you have any feedback regarding my posts just let me know.


Problem with PKG_CHECK_MODULES under Mac OS X

Published on: Sunday, August 31st, 2008 by tomasz

Yesterday I had some problem with compiling my Glib application under Mac OS X. I knew that everything worked before on Debian and the problem had to be one of this darwin-specific.
Just to make myself clear. Here is the error I got after executing: ./configure

checking for pkg-config... pkg-config
./configure: line 3489: syntax error near unexpected token `GLIB,'
./configure: line 3489: `PKG_CHECK_MODULES(GLIB, glib-2.0)'

It seemed that there was some problem with PKG_CHECK_MODULES – autoconf’s macro responsible for detecting if a given library or module was installed in the system (basing on pkg-config).
In fact it came out that the macro was not defined at all. Normally after running aclocal command it should be generated in the file aclocal.m4. But in my situation there was no such entry.

Why did that occur? At that time I could not answer that question but at least I had some starting point.
You may probably know that aclocal is one of the tools of Autotools package. It creates a file named aclocal.m4 which includes a number of Autoconf macros that can be used later by configure. (one of these macros is of course PKG_CHECK_MODULES)
After reading the aclocal info page I found out that the aclocal.m4 file content was based on some external .m4 files and my configure.ac. I read that the PKG_CHECK_MODULES macro should be defined inside pkg.m4 file, and I really could find it there in my directory /opt/local/share/aclocal .

And here the answer came. I installed pkg-config and Glib using darwin ports, where the default prefix for packages was /opt/local. But on the other hand all the Autotools programs were located in /usr/bin. It was obvious that the prefix was different, so that aclocal could not detect pkg.m4 file and define PKG_CHECK_MODULES macro.

The only missing thing was to inform aclocal about the path of pkg.m4 and all other external .m4 files.
It was simple and could be done by adding extra parameter -I:

aclocal -I /opt/local/share/aclocal

Now after running my autogen.sh file which more or less looked liked that:

aclocal -I /opt/local/share/aclocal
autoheader
automake
autoconf

and later

./configure
make

my application was compiled.
Of course this can be also achieved in many different ways. To find more solutions I recommend studying aclocalinfo page (especially secion Macro Search Path)



Tomasz Gebarowski
Polska Poland

Software Engineer