jueves, 13 de septiembre de 2007

#ident - Identificando revision de fuentes en binarios (C/C++)

La directiva #ident o #pragma ident dentro de un fuente C o C++ nos permite asignar una identificación en forma de texto a dicho fuente. Esta identificación se incorporara dentro del binario al momento de compilar, lo que nos permite, combinado con un sistema de control de versión, identificar exactamente que archivos fuente forman parte de un binario. Esto es particularmente util en entornos de trabajo donde existen varios grupos que modifican fuentes dentro del mismo repositorio (desarrollo, soporte, etc.) y el producto tiene varios clientes en producción.

Ejemplo 1 (manual):
#ident "ejemplo.cpp v1.23 (2007-09-12)"

En este caso el texto es generado manualmente por el programador, y este es el encargado de actualizar la versión cuando se modifica el fuente. El problema de esta forma de usar el #ident es que es muy fácil modificar el fuente y olvidar actualizar la versión y fecha.


Ejemplo 2 (svn):
#ident "$Id$"

Suponiendo que nuestros fuentes esten versionados con Subversion (svn), se puede solucionar fácilmente el problema del ejemplo anterior utilizando tags de svn:keywords. De esta manera el svn se encarga automáticamente de mantener actualizados los datos con cada commit.
Lo único que tenemos que haces es agregar el tag $Id$ como muestra el ejemplo y ejecutar el comando:
svn propset svn:keywords Id ejemplo.cpp

De esta manera el tag sera convertido automáticamente por svn a algo similar a lo siguiente:
#ident "$Id: ejemplo.cpp 429 2007-09-12 21:40:25Z pepito $"

Como se puede ver, tenemos (en orden): el nombre del fuente, el numero de revisión, la fecha y hora del commit y el usuario que lo realizo.
En base a esto, es muy fácil hacer un programita que recorra los binarios en busca del string '$Id: ' y nos muestre el resultado.

Ejemplo 3 (svn/SCCS):
#ident "@(#)$Id$"

Una buena opción para no tener que hacer el programa que busque los tags es utilizar el comando what de SCCS (Source Code Control System) o su contraparte GNU, el CSSC (Compatibly Stupid Source Control).
Para esto debemos modificar ligeramente el #ident agregando adelante el string '@(#)', que es lo que el comando what usa para buscar los comentarios que va a mostrar.
Esto es especialmente recomendable si los equipos donde va a correr nuestro sistema de producción son SunOS/Solaris o algún otro Unix, ya que en general se suele encontrar el comando what en estos sistemas operativos.

Si tenemos la directiva #ident de esta manera en todos nuestros fuentes y headers, la salida del comando what sera algo similar a:

> what bin/ejemplo
bin/ejemplo:
SunOS 5.9 Generic May 2002

$Id: ejemplo.cpp 429 2007-09-12 21:40:25Z pedro $
$Id: ejemplo.h 410 2007-09-10 20:12:02Z jose $
$Id: func_adic.cpp 139 2007-01-01 11:20:45Z juanito $
$Id: defines.h 13 2006-05-10 18:34:55Z pepito $

Buscando informacion sobre este tema, lei en algún lado que hay que agregar la opción -fident a la linea de compilación para que el #ident sea tenido en cuenta. Con gcc esto no parece ser necesario, no se con otros compiladores.

Referencias:
Libro Control de versiones con Subversion - Traduccion al español del libro oficial de svn (version 1.1/1.2)