2009-09-08 11 views
4

Nous avons un Makefile qui s'exécute sur une machine Windows 2003 et nous utilisons mingw32-make pour cela. Puisque le Makefile a de nombreux chemins d'inclusion, il dépasse la taille de tampon de 8K que le cmd peut gérer [Ref - http://support.microsoft.com/kb/830473/EN-US/ en raison de laquelle la compilation aboutit au problème "ligne d'entrée trop longue".mingw32-make: Problème de "ligne d'entrée trop longue"

Je voulais savoir ce qui suit -

  1. Quelle serait la meilleure façon d'optimiser le Makefile comme je l'ai déjà enlevé les commutateurs du compilateur indésirables, inclure les chemins etc.

  2. Est-il possible nous pouvons mettre tous les chemins INCLUDE dans un fichier .txt et l'importer dans le Makefile. Je n'ai pas trouvé de documentation mingw32 pour le même.

Toute autre entrées/conseils/liens de référence sont les bienvenus.

Merci,
-HJSblogger

Répondre

3

Une approche que nous avons pris (ce ne fut pas parce que nous avons couru hors de l'espace en ligne de commande, juste parce que nous voulions un système de construction propre) était d'avoir chaque « module » faire sa construction en passes.

Ainsi, par exemple, que vous avez 3 modules, A, B et C.

Votre makefile de commande appelle simplement chaque module Makefile avec la même cible.

Ensuite, nous définissons les cibles comme étant un nettoyage propre, en-tête, lib et exec.

Ainsi, le makefile de contrôle était quelque chose comme:

modules=A B C 
clean: 
    for i in $modules: 
     (cd $i ; make clean ; cd ..) 
header: 
    for i in $modules: 
     (cd $i ; make header ; cd ..) 
lib: 
    for i in $modules: 
     (cd $i ; make lib ; cd ..) 
exec: 
    for i in $modules: 
     (cd $i ; make exec ; cd ..) 

Chaque module qui avaient des fichiers d'en-tête nécessaires par d'autres modules copiés les fichiers d'en-tête dans un emplacement central pendant la phase d'en-tête. Ensuite, pendant la phase lib ou exec, chaque module n'a dû utiliser que cet emplacement central pour localiser tous ses en-têtes. Cela a également restreint les modules à n'utiliser que les en-têtes publiés à l'emplacement central par d'autres modules.

De même, chaque module qui a créé une bibliothèque nécessaire à la phase d'exécution a copié cette bibliothèque dans un emplacement central. Ceci a considérablement réduit les clauses -I (répertoire inclus) et -L (répertoire de bibliothèque) dans les commandes de construction. En utilisant ce schéma, vous pouvez reconstruire le tout simplement en exécutant make clean header lib exec au niveau supérieur (ou laisser clean pour une construction de make appropriée, en tenant compte des dépendances).

C'est une façon de contourner votre problème, mais je me demande réellement comment vous dépasserez la limite. 8K, même à 25 caractères par chemin, nécessiterait environ 300 chemins d'inclusion distincts. Votre hiérarchie est-elle vraiment si volumineuse?

Mise à jour 1:

Si vous êtes à la recherche d'un moyen de quick'n'dirty pour le faire fonctionner sans changer le makefile « architecture », vous écrivez un script qui, étant donné une liste de répertoires, copiera tous les fichiers d'en-tête de ces répertoires vers un emplacement central.

Exécutez ensuite cela comme première étape dans toutes vos règles et modifiez les instructions include dans vos lignes de compilation pour simplement référencer cet emplacement plutôt que la grande liste. Vous pouvez même faire la copie par étapes (par exemple, 20 répertoires à la fois x 20 fois peuvent gérer 400 répertoires au total). Cela vous donne le même effet que la solution proposée avec des changements plus petits dans les fichiers makefiles.

Mise à jour 2:

Une autre solution, comme vous l'avez dit dans vos commentaires, était un alias un chemin.

Vous devriez être en mesure de le faire avec subst.exe tels que:

> subst x: "c:\Documents and Settings\Pax\My Documents\Not my directory" 
> dir x: 
    Volume in drive X has no label. 
    Volume Serial Number is 8AA3-703A 

    Directory of X:\ 

    08/09/2009 10:12 AM <DIR>   . 
    08/09/2009 10:12 AM <DIR>   .. 
    24/08/2009 01:54 PM    6,409 p0rn_sites.txt 
    09/07/2008 02:49 PM <DIR>   downloaded_p0rn 
    : : : 
    09/07/2008 02:52 PM <DIR>   other_suspect_stuff 
       3 File(s)   18,520 bytes 
       18 Dir(s) 63,840,849,920 bytes free 

> subst x: /d 
> dir x: 
    The system cannot find the path specified. 
+1

Pax, Merci pour la réponse. Oui, la construction est assez volumineuse et comprend de nombreux chemins :) Pour être honnête, l'objectif est maintenant de faire fonctionner le système sans aucun blocage. Merci, -HJSBlogger – hjsblogger

+0

@hjsblogger, si vous cherchez un moyen rapide et efficace de le faire fonctionner, écrivez un script qui, avec une liste de répertoires, va copier tous les fichiers d'en-tête de ces répertoires vers un emplacement central. Exécutez ensuite cela comme première étape dans toutes vos règles et modifiez les instructions include dans vos lignes de compilation pour simplement référencer cet emplacement plutôt que la grande liste. Vous pouvez même faire la copie par étapes (par exemple, 20 répertoires à la fois x 20 fois peuvent gérer 400 répertoires au total). – paxdiablo

+1

@Pax: Merci pour l'extrait, j'essaierais certainement de m'emparer de celui-ci et de voir si cela fonctionne. En attendant, je cherchais aussi à savoir si nous pouvions faire un ALIAS pour un chemin eg.ALIAS de C: \ Inc_Folder \ src \ .. vers X: pour que tous mes chemins INC commencent à partir de X: \ résultant en moins d'utilisation du tampon cmd. J'ai redirigé la sortie cmd vers un fichier et trouvé que sur 8K, près de 3K arrive à cause du grand chemin de départ depuis lequel chaque composant démarre. Quelle est votre opinion sur la même.Je suis encore en train de googler et de vérifier si c'est possible. J'essaierais aussi de regarder en parallèle votre solution. – hjsblogger

0

en utilisant la version SDK problème NACL « make » J'ai eu la « ligne de commande est trop long ».

La cause du problème est que le shell Windows (cmd.exe) a une limitation de taille 8191 char dans la ligne de commande: http://support.microsoft.com/kb/830473/en

Le problème est que lorsque la compilation atteint le point de créer une bibliothèque en utilisant "ar", il y avait trop de fichiers source et la ligne de commande était trop longue.

Donc, pour résoudre ce problème, je devais changer le fichier « nacl_llvm.mk »:

# 
# LIB Macro 
# 
# $1 = Target Name 
# $2 = List of Sources 
# $3 = POSIX Link Flags 
# $4 = VC Link Flags (unused) 
define LIB_RULE 
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a 
    @echo "TOUCHED [email protected]" > $(STAMPDIR)/$(1).stamp 

all: $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a 
$(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src))) 
    $(MKDIR) -p $$(dir [email protected]) 
    $(RM) -f [email protected] 
# Comment this line!  
# $(call LOG,LIB,[email protected],$(PNACL_LIB) -cr [email protected] $$^ $(3)) 

# Add these other lines 
    $(shell echo cmd /C $(subst /,\,$(PNACL_LIB) -cr $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a) > create_lib.bat) 
    $(foreach src,$(2),$(shell echo cmd /C $(subst /,\,$(PNACL_LIB) -r $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a $(call SRC_TO_OBJ,$(src))) $(3) >> create_lib.bat)) 
    create_lib.bat 

endef 

L'idée est de créer un fichier « chauve-souris » avec toutes les commandes qui doivent être exécutées pour créer la fichier de bibliothèque, puis ajoutez les fichiers d'objet un par un. Ensuite, le fichier "bat" est exécuté au bon moment. Sincères salutations

Questions connexes