Installer Xapian 1.2.5 et le binding Ruby chez Dreamhost

Il est temps de faire le ménage sur les libs installées depuis quelques années chez mon hébergeur : DreamHost.
L’un des composants majeur que j’utilise et qui n’est pas disponible par l’hébergeur est Xapian. Actuellement la version 1.2.5 est stable, mettons à jour notre ancienne version 1.0.23.

Pour rappel Xapian est une librairie de recherche plein texte open source écrite en C++.

Logo Xapian

Premièrement sur les environnement de Dreamhost, les packages de développement de la librairie UUID ne sont pas disponible, faisons une installation locale.

Récupérer la lib UUID du projet e2fsprogs avec l’une des urls suivantes :

  • git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
  • http://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
  • https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
cd $HOME
mkdir -p $HOME/opt/src
cd $HOME/opt/src
git clone git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
cd e2fsprogs
./configure CFLAGS=-fPIC --prefix=$HOME/opt
cd lib/uuid
make && make install

Récupérons les sources de xapian-core puis installons :

cd $HOME/opt/src
wget http://oligarchy.co.uk/xapian/1.2.5/xapian-core-1.2.5.tar.gz
tar -zxvf xapian-core-1.2.5.tar.gz
cd xapian-core-1.2.5
./configure LDFLAGS=-L$HOME/opt/lib CFLAGS=-fPIC CXXFLAGS=-I$HOME/opt/include --prefix=$HOME/opt
make && make install

Récupérons les sources de xapian-bindings puis installons la version pour Ruby :

cd $HOME/opt/src
wget http://oligarchy.co.uk/xapian/1.2.5/xapian-bindings-1.2.5.tar.gz
tar -zxvf xapian-bindings-1.2.5.tar.gz
cd xapian-bindings-1.2.5
./configure --with-ruby LDFLAGS=-L$HOME/opt/lib CFLAGS=-fPIC CXXFLAGS=-I$HOME/opt/include --prefix=$HOME/opt RUBY_LIB=$HOME/opt/ruby_modules RUBY_LIB_ARCH=$HOME/opt/ruby_modules XAPIAN_CONFIG=$HOME/opt/bin/xapian-config
make && make install

Dans l’application RubyOnRails indiquons le chemin de nos modules installés localement (config/environnement.rb) :

if ENV['RAILS_ENV'] == "production"
    config.load_paths += [ ENV['HOME'] + '/opt/ruby_modules' ]
end

Intel GMA 500 sous linux, kernel 2.6.37

J’ai dernièrement écris un billet sur le netbook Asus EeePC 1201HA dans lequel je critiquais le travail d’Intel (certes un rachat) sur l’architecture GMA 500 soit les drivers linux poulsbo, tout pas beau…

Architecture SCH

Actuellement on peut voir que dans les nouveautés du noyau linux 2.6.37 le driver poulsbo (Intel GMA 500) est présent grâce au travail de Lee Chun-Yi de Novell. Mais ça reste un début seulement car ce pilote ne semble gérer nativement que le rétro-éclairage de l’écran.

Intel, quant à lui, semble au courant du problème mais ne priorise pas sa résolution. C’est dommage pour ceux qui ont hérité de ce GMA 500.

Singleton threadsafe en cplusplus

Le motif de conception Singleton est l’un des plus simple a maîtriser. Mais lorsqu’il s’agit d’accès concurrentiel dans un programme, les implémentations classiques ne suffisent plus. Il faut garder à l’esprit que les architectures multiprocesseurs ont plusieurs caches souvent asynchrones « write-back » par opposition à « write-through » pour synchrone (rare car moins performant).

Un singleton moderne devrait implémenter les notions suivantes :

Qu’est ce qu’un Singleton ? En programmation un Singleton est un objet dont on veut garantir qu’une seule instance vit pendant l’exécution du programme. Imaginez un système d’exploitation qui aurait deux instances de son système de fichier !!! C’est le boxon assuré.

Voici mon implémentation en cplusplus (code source d’exemple) :

//singleton.h
#ifndef __SINGLETON_H_
#define __SINGLETON_H_

#include <cstdlib> //std::atexit()

#define MFENCE			"memory_fence"
#define MUTEX_LOCK		"lock"
#define MUTEX_UNLOCK	"unlock"
#define MEMORY_READWRITE_BARRIER	"memory_barrier"

template <typename T>
class Singleton
{
public:
	static T& instance()
	{
		return *get_instance();
	}

	static const T& const_instance()
	{
		return *get_instance();
	}

	static void destroy()
	{
		MFENCE; //On s'assure que tous les caches processeurs sont à niveau
		if (pInstance_ != 0)
			delete pInstance_;
	}

protected:
	Singleton(){}
	~Singleton()
	{
		pInstance_ = 0;
		created_ = false;
	}

private:
	static T* pInstance_;
	static volatile bool created_;
	Singleton(const Singleton &);
	Singleton& operator= (const Singleton &);

	static T* get_instance()
	{
		if (created_ == false)
		{
			MUTEX_LOCK; //On s'assure qu'un seul thread a la main
			if (pInstance_ == 0)
			{
				pInstance_ = new T();
				std::atexit(Singleton::destroy);
			}
			MUTEX_UNLOCK;
			MEMORY_READWRITE_BARRIER; //On s'assure que le compilateur ne change pas l'ordre de ces 2 instructions
			created_ = true;
			MFENCE; //On s'assure que tous les caches processeurs sont à niveau
		}
		return pInstance_;
	}
};

template<typename T> T* Singleton<T>::pInstance_ = 0;
template<typename T> volatile bool Singleton<T>::created_ = false;

#endif//!__SINGLETON_H_

Notons que pour les mutexes, les meilleures implémentations permettent aussi, en plus d’être dans une zone synchrone, de réaliser l’équilant de [SLM]FENCE (PIII : SFENCE – P4 : LFENCE, MFENCE). Pour ce qui est de l’annulation de l’ordre des instructions par le compilateur, je ne vois rien d’autres que d’utiliser une librairie qui fournit des MACROS adaptés aux différents compilateurs et plateformes.

Bonne et heureuse année 2011 à tous

Cette année 2010 est passée à une vitesse telle que je n’ai pas testé grand chose…

Néanmoins dans mes nouvelles résolutions pour 2011 :

  • C++0X
  • Go (Google)
  • Ruby (Rails 3)
  • Python 3
  • Java (GWT 2)

Meilleurs vœux 2011 !!!

Drivers Canon MP540 sous Ubuntu >= Karmic Koala

Sous Jaunty Jackalope (9.04) il était facile d’installer les drivers de l’imprimante Canon MP540 récupéré directement du site de Canon. Depuis Karmic Koala (9.10), la libcupsys2 devient libcups2 ; il est devenu impossible d’installer ces drivers puisque Canon n’a pas mis à jours ses packages (04/2008). Ce tutoriel est basé sur la version allemande de Vitali Henrichs.

Image de l'imprimante Canon MP540

Imprimante Canon MP540

Toutefois il reste encore une solution, récupérer les modifications que j’ai faîtes ou réaliser les modifications vous-même en suivant les étapes suivantes.

Fichiers à jour : cnijfilter-common_3.00-1_i386.deb, cnijfilter-mp540series_3.00-1_i386.deb.

Télécharger et décompresser les drivers depuis le site de Canon :

mkdir MP540_debian_driver
tar xvf MP540_debian_drivers.tar -C MP540_debian_driver
cd MP540_debian_driver
tar xvf MP540_debian_printer.tar
tar xvf MP540_debian_scangear.tar

Nous devons modifier les fichiers de contrôle des packages Canon pour déclarer libcups2 à la place libcupsys2.

Commençons par le packge cnijfilter-common_3.00-1_i386.deb :

dpkg-deb -x cnijfilter-common_3.00-1_i386.deb common
dpkg-deb --control cnijfilter-common_3.00-1_i386.deb
vim DEBIAN/control

Remplacer la ligne :

Depends: libc6 (>= 2.3.4-1), libcupsys2 (>= 1.2.1), libpopt0 (>= 1.7)

Par :

Depends: libc6 (>= 2.3.4-1), libcups2 (>= 1.2.1), libpopt0 (>= 1.7)

Copions nos modifications dans le répertoire « common » et reconstruisons le package :

cp -a DEBIAN/ common/
dpkg -b common cnijfilter-common_3.00-1_i386.deb

Installons l’archive modifiée :

sudo dpkg -i --force-architecture cnijfilter-common_3.00-1_i386.deb
rm -rf common DEBIAN

Modifions le package cnijfilter-mp540series_3.00-1_i386.deb :

dpkg-deb -x cnijfilter-mp540series_3.00-1_i386.deb mp540series
dpkg-deb --control cnijfilter-mp540series_3.00-1_i386.deb
vim DEBIAN/control

Remplacer la ligne :

Depends: libatk1.0-0 (>= 1.9.0), libc6 (>= 2.3.4-1), libcairo2 (>= 1.0.2-2), libcupsys2 (>= 1.2.1), ...

Par :

Depends: libatk1.0-0 (>= 1.9.0), libc6 (>= 2.3.4-1), libcairo2 (>= 1.0.2-2), libcups2 (>= 1.2.1), ...

Copions nos modifications dans le répertoire « mp540series » et reconstruisons le package :

cp -a DEBIAN/ mp540series/
dpkg -b mp540series cnijfilter-mp540series_3.00-1_i386.deb

Installons l’archive modifiée :

sudo dpkg -i --force-architecture cnijfilter-mp540series_3.00-1_i386.deb
rm -rf mp540series DEBIAN

Installons les drivers pour la fonction scanner :

sudo dpkg -i --force-architecture scangearmp-common_1.20-1_i386.deb
sudo dpkg -i --force-architecture scangearmp-mp540series_1.20-1_i386.deb

Modifions les droits du fichier « /usr/lib/cups/filter/pstocanonij » qui n’appartiennent pas à « root » après l’installation et redémarrons cups :

sudo chown root:root /usr/lib/cups/filter/pstocanonij
sudo service cups restart

Pour accéder aux options avancées de l’imprimante vous pouvez récupérer le fichier ppd depuis le site de Vitali :

wget http://www.viilinux.de/viilinux_wp-content_EF65lgN/uploads/2010/08/MP540-series.ppd_.tar.gz
tar -zxvf MP540-series.ppd_.tar.gz
sudo cp MP540-series.ppd /etc/cups/ppd/

Merci à Vitali et à ceux qui l’on aidé à réaliser ce tuto.