J'ai une application AVR8 GCC qui peut être construite avec un makefile
standard. Parce que certaines personnes qui souhaitent créer l'application ne veulent pas configurer make et autres (ou ont du mal à le faire), j'ai également trouvé comment configurer le projet afin qu'il puisse également être compilé à partir de l'IDE Arduino.
Tout fonctionne.
Mais, je règle normalement certains éléments dans le makefile
, comme le numéro de version et autres, mais en créant la chaîne VERSION dans le makefile
et en la passant comme définition dans chaque compilation de fichier source. Mais, lorsqu'elle est exécutée à partir de l'IDE Arduino, cette étape ne se produit évidemment pas. Donc, je dois créer un deuxième #define
dans le talon d'esquisse Arduino pour recréer la définition.
Cela signifie que lorsque je mets à jour la version, je dois le faire à 2 endroits, dans le makefile
et dans le fichier source.
L'option la plus simple consiste à déplacer simplement la création de VERSION
vers le fichier source, où les deux peuvent l'utiliser. Et je vais bien faire ça, mais
Le makefile
réellement besoin des informations de version, à la fois pour créer le bon nom de fichier (pensez app_v1.2.3.4.bin ) et pour incorporer le numéro de version dans le fichier bin puisqu'il est utilisé par le chargeur de démarrage (si demandé) pour garantir la version le boot-loader clignote est plus récent que celui déjà en FLASH. Donc, si je déplace les définitions de VERSION
, RELEASE
, MODIFICATION
, etc. dans le code C, je dois trouver un moyen de les ramener dans le makefile
.
J'ai essayé d'utiliser les opérations de lecture de fichier dans le makefile
, mais elles semblent ignorer:
#define VERSION 0 #define RELEASE 1 #define MODIFICATION 2 #define FIX 4
avec le caractère '#' préfacé.
Je vois qu'il y a quelques options pour exécuter sed / awk / etc, dans bash, mais je ne veux pas faire trop d'hypothèses sur l'environnement, et le makefile
fonctionne actuellement sous Windows ainsi que Unix / Linux sans aucune différence.
J'ai essayé quelques exemples de débordement de pile, mais rien ne semble donner ces 4 nombres à partir d'un fichier, .h ou autre.
Je suis d'accord avec la création de version.h avec juste:
#define VERSION 0
Si je peux le lire dans le makefile
et créer les variables dont j'ai besoin.
Jim
3 Réponses :
Je pense que dans ce cas, vous pouvez utiliser la fonction 'file' de makefiles. Il vous permet d'écrire (avec> spécificateur) ou de lire (avec <spécificateur) vers / depuis des fichiers. Ensuite, vous pouvez couper (avec filtrage) vos variables dans votre makefile. Source: https://www.gnu.org/software/make/manual/html_node/File-Function.html#File-Function
Relisez votre question, quelle version de marque utilisez-vous? la fonction de fichier ne fonctionne qu'avec 4.2 et au-dessus
Comme je l'ai noté ci-dessus dans ma question, j'ai déjà essayé la fonction de fichier $(file < version.h)
, mais si je n'ai pas le '#' dans le #define, make 4.3 crache une erreur 'make: define: No such file or directory ', et si je préfère le # devant define, les lignes semblent être ignorées en tant que commentaires. Je pense que la fonction de fichier lit les données comme s'il s'agissait de commandes Makefile, et donc tout ce qui a un '#' devant peut être simplement ignoré en tant que commentaire.
la seule solution de contournement à laquelle je peux penser est d'utiliser cat ou type en fonction de l'os cat := $(if $(filter $(OS),Windows_NT),type,cat)
variable := $(shell $(cat) filename)
Vous pouvez utiliser la fonction $(shell ...)
GNU make pour extraire les extensions de macro. En supposant que VERSION
est définie dans src.c
et que les jetons sont délimités par des espaces (pas des tabulations):
VERSION := $(shell sed -n -e "s/^\#define VERSION *\(.*\)/\1/p" src.c) .PHONY: all all: @echo VERSION=$(VERSION)
Comme indiqué dans la demande originale, je préfère ne pas utiliser le shell, car il n'y a aucune garantie qu'un ensemble complet d'outils Unix sera disponible. Je préfère créer le moins de pré-demandes d'outils possible.
Vous pouvez jeter un oeil à gmtt qui a été conçu exactement pour votre cas d'utilisation. Dans gmtt
les éléments suivants devraient lire et analyser votre fichier d'en-tête:
include gmtt.mk # create a 3-column table from the header file. The first column is just the "#define" VNR_TABLE := 3 $(file < version.h) # Extract the values from the table: select column 3 from VNR_TABLE where column 2 equals a string constant. # Be careful not to introduce spaces in the compare! VER := $(call select,3,$(VNR_TABLE),$$(call str-eq,$$2,VERSION)) REL := $(call select,3,$(VNR_TABLE),$$(call str-eq,$$2,RELEASE)) MODF := $(call select,3,$(VNR_TABLE),$$(call str-eq,$$2,MODIFICATION)) FIX := $(call select,3,$(VNR_TABLE),$$(call str-eq,$$2,FIX))
Je n'ai pas pu le tester mais je pense que vous avez compris l'idée.
PS: utiliser une bibliothèque GNUmake signifie simplement placer le fichier include
d à côté du makefile
.
Merci beaucoup. Cela fonctionne très bien et ne recourt pas à un piratage de shell laid.
Utilisez-vous GNU make ou une autre marque?
J'utilise gnu make