Question

En supposant que nous ayons la règle:

a: b c d e

et b, c, d et e sont indépendants l'un de l'autre.

L'ordre de fabrication des <=>, <=>, <=>, <=> est-il défini? Il semble qu’en règle générale, elles seront fabriquées dans l’ordre <=>, <=>, <=>, <=>, mais cela peut-il parfois arriver que l’ordre soit différent?

Était-ce utile?

La solution

Bien sûr, si j'utilise make -j a, ils peuvent tous être construits en même temps (selon que b, c, d ou e ont à leur tour des dépendances autres / interdépendantes).

Autres conseils

Non, la commande n'est pas définie. C’est tout le point dans l’utilisation de la programmation déclarative orientée sur la dépendance: l’ordinateur peut choisir l’ordre d’évaluation optimal, ou même l’évaluer en même temps .

  

Dans quel ordre les conditions préalables seront-elles définies par la marque GNU?

Cela dépend du type de prérequis. Selon le Manuel de GNU Make , section 4.2:

  

Il existe en réalité deux types de prérequis compris par   GNU make: conditions préalables normales telles que décrites dans la précédente   section, et prérequis de commande seulement. Un prérequis normal fait deux   déclarations: tout d'abord, il impose un ordre dans lequel les recettes seront   invoqué: les recettes pour tous les prérequis d'une cible seront   terminé avant que la recette de la cible ne soit exécutée. Deuxièmement, il impose   une relation de dépendance: si une condition préalable est plus récente que la   cible, la cible est considérée comme obsolète et doit être reconstruite.

     

Normalement, c’est exactement ce que vous voulez: si la condition préalable d’une cible & # 8217; est   mis à jour, la cible doit également être mise à jour.

     

Parfois, toutefois, vous souhaitez imposer une   ordre spécifique sur les règles à invoquer sans forcer le   cible à mettre à jour si l’une de ces règles est exécutée. Dans ce cas,   vous souhaitez définir des conditions préalables sur commande uniquement. Commande seulement   les prérequis peuvent être spécifiés en plaçant un symbole de conduite (|) dans le champ   liste des conditions préalables: toutes les conditions préalables à gauche du symbole de tuyau   sont normaux; les conditions préalables à droite sont d'ordre uniquement:

   targets: normal-prerequisites | order-only-prerequisites
     

La section des conditions préalables normales peut bien sûr être vide. Aussi, vous pouvez   déclarez toujours plusieurs lignes de prérequis pour la même cible:   ils sont ajoutés de manière appropriée (les conditions préalables normales sont ajoutées à   la liste des conditions préalables normales; les conditions préalables de commande sont   ajouté à la liste des conditions préalables de commande uniquement). Notez que si vous   déclarer le même fichier comme étant à la fois normal et sur commande uniquement   condition préalable, la condition préalable normale prévaut (car ils   sur-ensemble strict du comportement d'un prérequis d'ordre uniquement).

     

Prenons un exemple où vos cibles doivent être placées dans un emplacement séparé.   répertoire, et ce répertoire peut ne pas exister avant que make soit exécuté. Dans   Dans cette situation, vous voulez que le répertoire soit créé avant toute   les cibles y sont placées mais, car les horodatages des répertoires   changer chaque fois qu'un fichier est ajouté, supprimé ou renommé, nous avons certainement   don & # 8217; ne veut pas reconstruire toutes les cibles chaque fois que le répertoire & # 8217; s   changements d'horodatage. Une façon de gérer cela est avec commande seulement   conditions préalables: faire du répertoire une condition préalable à la commande uniquement   les cibles:

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
    mkdir $(OBJDIR)
     

Maintenant la règle pour créer le & # 8216; objdir & # 8217; le répertoire sera exécuté, si nécessaire,   avant tout & # 8216; .o & # 8217; est construit, mais pas & # 8216; .o & # 8217; sera construit parce que le   & # 8216; objdir & # 8217; horodatage du répertoire modifié.

Dans l'ordre droit , en fonction des règles que vous fournissez. Pour votre exemple particulier, cela peut signifier n'importe lequel d'un nombre différent de commandes (4! = 24, de mémoire).

Tous les make programmes sont libres de choisir l'ordre de leur choix tant que les dépendances sont respectées. Si votre exemple contenait d’autres règles, par exemple c: b, alors c serait créé avant b (mais ce n’est pas le cas, comme vous le signalez).

Si vous devez vous fier à un ordre spécifique, vous aurez besoin de plus de règles pour l’appliquer. Sinon, <=> peut faire ce qui lui plaît. La documentation sur GNU Make indique uniquement comment les règles sont traités, pas l'ordre dans lequel les dépendances d'une règle sont traitées. L'ordre le plus logique (pour moi, en tout cas) serait l'ordre dans lequel ils sont listés, mais ce n'est pas garanti.

Non, vous ne pouvez pas compter sur l'ordre s'il n'y a pas de relations de dépendance.

  • make doit faire une sorte topologique , car les dépendances peuvent avoir des relations supplémentaires et multiples. Le type que fait make est potentiellement assez complexe, car les nœuds du graphique peuvent être liés plusieurs fois à différents niveaux
  • En général, les algorithmes de tri ne sont pas naturellement stables . , même pour les tris simples basés sur des clés

Si l'ordre est important, vous pouvez l'appliquer de manière sélective à l'aide de make récursif . Par exemple, supposons que vous ne vous souciez pas de l'ordre dans lequel b et c sont fabriqués, tant qu'ils sont tous deux fabriqués avant que d et d soient créés avant e. Ensuite, vous pouvez écrire votre règle comme suit:

a: b c
    $(MAKE) d
    $(MAKE) e
    # Additional steps to make a

Sachez que, selon la complexité de d et e, cette approche peut être préjudiciable à votre temps de génération: voir Rendre récursif considéré comme préjudiciable (PDF) pour les arguments contre le faire de cette manière.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top