¿Cómo dejar que el progtwig muestre el número de versión correcto en el control de fuente?

Deseo que mi progtwig C muestre la versión correcta mantenida en control de fuente mercurial. Mi método existe algunos problemas.

  1. Si modifico other.c, la versión no puede mostrarse correcta.
  2. Si modifico main.c sin check in, deseo que me avise.
  3. Hay muchos files en directorys separados. Desearía poder cambiar la versión solo cuando cambien los files de dependencia.

Por cierto, no me importa qué sistema de control de versiones se use, solo me pregunto si estos problemas podrían ser resueltos.

C Principal

int main() { printf("version=%s\n", VERSION); return 0; } 

makefile

 VERSION=$(shell hg id -i) # PHONY force main.c always compile .PHONY: main.c all: main main: main.o other.o gcc main.o other.o -o main main.o : main.c gcc -c -DVERSION=\"${VERSION}\" main.c -o main.o other.o : other.c gcc -c other.c -o other.o 

Para mi primera pregunta, Carl Norum proporciona una solución para usar PHONY, este método tiene un efecto queueteral, siempre buildá main.c y main ejecutable aunque no haya modificaciones.

La solución estándar para su primer problema es crear un file (digamos config.h) con la configuration del sistema y variables globales cambiantes como VERSIÓN. main puede include config.h. Puede editar config.h a mano o tener config.h reconstruido desde marcadores Makefile una regla como:

 config.h : force-rebuild sed -e 's/[@]VERSION[@]/$(VERSION)/' $<.in > $@ .PHONY : force-rebuild 

donde su file de plantilla config.h.in contiene "@ VERSIÓN @" donde quiera que vaya el número de versión.

Su sistema de control de versiones debe manejar el segundo problema. svn status y commands similares manejan esto muy bien.

Para el tercer problema, no existe una solución estándar, ya que la mayoría de las reglas de respuesta de versión requieren interacción humana. Cuando etiquetó correctamente su versión anterior, puede comparar dos versiones en el control de su versión; por ejemplo, para SVN:

 svn diff $MYREPO/tags/$CURRENT_VERSION . 

y mira la diferencia. $ MYREPO se puede raspar desde la salida de svn info y CURRENT_VERSION desde config.h.

  1. Si desea que su cadena de versión se mantenga actualizada, necesitará build el file que la contiene cada vez. En su caso, eso significa build main.c , incluso si no hay nada desactualizado. Usted podría hacer main.o un objective falso, y eso lo haría por usted. Si main.c vuelve complicado y buildlo cada vez lo hace demasiado lento, puede pensar en poner la información de la versión en un file por separado y solo comstackr esa.

  2. make no tiene manera de manejar su request por sí mismo, pero es de suponer que su sistema de control de versiones puede decirle si no ha registrado los files. Puede agregar un cheque para eso a cualquiera de sus recetas y salir en caso de falla. Aquí hay un ejemplo (para git, no sé mercurial):

     allcheckedin: @if [[ -n $$(git status -s) ]] ;\ then \ echo "All files not checked in." ;\ exit 1 ;\ fi 

No estoy seguro de entender por completo su tercera pregunta. Si puede aclararla, trataré de ayudarlo.

Use algo como SVN o CVS para control de versiones. Luego use el formatting what (vea man what) para colocar una cadena estática en cada file .c o .cpp que incorpore una versión que cualquier sistema de versión puede colocar en ella automáticamente.

es decir

 static const char[] = "@(#) $Id$"); /* For example SVN */ 

Pueden usar la utilidad para saber exactamente las versiones para todos los files en la compilation.