2010-07-20 8 views
5

Supposons qu'il existe un programme C, qui stocke sa version dans un char* global dans main.c. Est-ce que le buildsystem (gnu make) peut extraire la valeur de cette variable au moment de la construction, de sorte que l'exécutable construit puisse avoir le nom exact de la version tel qu'il apparaît dans le programme?Est-ce que les variables makefile peuvent être affectées avec des valeurs lues à partir des fichiers source?

Ce que je voudrais réaliser est que, étant donné la source:

char g_version[] = "Superprogram 1.32 build 1142"; 

le buildsystem générerait un exécutable nommé Superprogram 1.32 build 1142.exe

Répondre

5

Le shell function vous permet d'appeler des applications externes telles que sed qui peut être utilisé pour analyser la source pour les détails requis.

+0

Bien que sa chaîne de version ressemble étrangement fabriqué à la main, j'aurais également conseillé de vérifier 'outil what'. Ce plus «shell» pourrait être ce qu'il cherche. – Dummy00001

+0

Merci de m'avoir répondu, cela pourrait bien marcher, à condition que je sois à la hauteur de mes capacités sur sed (et les autres utils, mentionnés ci-dessous par mouviciel) ... – Manjabes

1

Vous pouvez utiliser n'importe quelle combinaison d'outils de texte unix (grep, sed, awk, perl, queue, ...) dans votre Makefile afin d'extraire cette information du fichier source.

5

Définissez votre variable version à partir d'une macro:

char g_version[] = VERSION; 

puis faites votre makefile mettre un argument -D sur la ligne de commande lors de la compilation

gcc hack.c -DVERSION=\"Superprogram\ 1.99\" 

Et bien sûr, vous devriez dans votre exemple d'utilisation sed/grep/awk etc pour générer votre chaîne de version.

+0

Je connais l'option -D, mais cela ne peut pas être appliqué dans ce cas. La chaîne de version doit rester là où elle est. – Manjabes

0

Habituellement, la version est définie comme une composition de plusieurs valeurs #define (comme dans le arv library par exemple).

Alors allons-y pour un exemple simple et de travail:

// myversion.h 
#define __MY_MAJOR__ 1 
#define __MY_MINOR__ 8 

Puis dans votre Makefile:

# Makefile 
source_file := myversion.h 
MAJOR_Identifier := __MY_MAJOR__ 
MINOR_Identifier := __MY_MINOR__ 

MAJOR := `cat $(source_file) | tr -s ' ' | grep "\#define $(MAJOR_Identifier)" | cut -d" " -f 3` 
MINOR := `cat $(source_file) | tr -s ' ' | grep '\#define $(MINOR_Identifier)' | cut -d" " -f 3` 

all: 
    @echo "From the Makefile we extract: MAJOR=$(MAJOR) MINOR=$(MINOR)" 

Explication

Ici, je l'ai utilisé plusieurs outils il est donc plus robuste:

  • tr -s ' ': pour supprimer l'espace supplémentaire entre les éléments,
  • grep: pour sélectionner la ligne correspondant unique, notre but,
  • cut -d" " -f 3: pour extraire le troisième élément de la ligne sélectionnée qui est la valeur cible!

Notez que les valeurs de définition peuvent être n'importe quoi (pas seulement numérique).

Prenez garde à utiliser := (non =) voir: https://stackoverflow.com/a/10081105/4716013