2010-11-08 56 views
42

Je souhaite désactiver les règles intégrées et les variables en passant le -r and -R options à GNU make, à partir du fichier make. D'autres solutions qui me permettent de le faire implicitement et de manière transparente sont également les bienvenues.Désactiver les règles et les variables intégrées à l'intérieur du fichier make

J'ai trouvé several references pour utiliser MAKEFLAGS, et ai eu des problèmes similaires.

+2

Vous n'êtes pas faire un système de construction cthulhoid, êtes-vous Joiner? –

+0

Un parmi beaucoup, cette fois il génère des fichiers pour le parallélisme libre. La conversion en C++ a décuplé les temps de construction, ce qui est inacceptable. –

+4

"La conversion en C++ ... est inacceptable." - Matt Joiner. ;-) –

Répondre

29

Désactivation des règles intégrées se fait par writing an empty rule for .SUFFIXES:

.SUFFIXES: 

Après avoir effacé les règles intégrées, je ne suis pas sûr que l'effacement des variables intégré vous aide beaucoup plus que juste se souvenir de définissez-les vous-même ou ne les utilisez pas, mais vous pourriez utiliser quelque chose comme

$(foreach V 
    $(shell make -p -f/dev/null 2>/dev/null | sed -n '/^[^:#= ]* *=/s/ .*//p'), 
    $(if $(findstring default,$(origin $V)),$(eval $V=))) 

... ce qui est certes assez dingue. S'il existe un moyen d'obtenir une liste des variables définies à partir de make (au lieu de passer à une autre make), ce serait viable. Comme il est, ce n'est pas vraiment beaucoup mieux que

CC= 
CXX= 
# etc, for each likely built-in variable 
+0

C'est sympa, mais un peu trop hacky. –

+2

Je ne pense pas que cela gère les règles [match n'importe quoi] (http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Rules) –

+1

[Il semble] (https: //savannah.gnu.org/bugs/?20501) que dans certaines versions de GNU Make, l'effacement de '.SUFFIXES' désactive les règles intégrées _suffix_ mais pas les règles _pattern_ (voir la réponse de Brandon). Dans ma version de GNU Make (3.81), '.SUFFIXES' semble suffisant. –

1

Vous pouvez commencer la Makefile avec un #! et appeler quelque chose de différent pour que les gens ne cherchent pas à utiliser make directement:

#!/usr/bin/make -rRf 
# ... 

Cette volonté causer des problèmes horribles si GNU make n'est pas le système make. Peut-être un script d'emballage?

Vous pouvez également lire $(MAKEFLAGS) et vous assurer que les indicateurs requis sont présents.

+3

Je pense que vous voulez '#!/Usr/bin/env make -rRf'. Oh, je vois ce que tu veux dire maintenant. –

+0

'/ usr/bin/env' est probablement mieux. –

+0

Cela ne fonctionnera pas et donnera '/ usr/bin/env: 'make -rRf': Aucun fichier ou répertoire' sur de nombreux systèmes (comme par exemple Linux) car un seul argument optionnel est supporté sur la ligne shebang et aucune division de commande n'est faite. Voir [ici] (https://en.wikipedia.org/wiki/Shebang_ (Unix) #Portability). –

4

Cela fonctionne pour moi:

# Disable implicit rules to speedup build 
.SUFFIXES: 
SUFFIXES := 
%.out: 
%.a: 
%.ln: 
%.o: 
%: %.o 
%.c: 
%: %.c 
%.ln: %.c 
%.o: %.c 
%.cc: 
%: %.cc 
%.o: %.cc 
%.C: 
%: %.C 
%.o: %.C 
%.cpp: 
%: %.cpp 
%.o: %.cpp 
%.p: 
%: %.p 
%.o: %.p 
%.f: 
%: %.f 
%.o: %.f 
%.F: 
%: %.F 
%.o: %.F 
%.f: %.F 
%.r: 
%: %.r 
%.o: %.r 
%.f: %.r 
%.y: 
%.ln: %.y 
%.c: %.y 
%.l: 
%.ln: %.l 
%.c: %.l 
%.r: %.l 
%.s: 
%: %.s 
%.o: %.s 
%.S: 
%: %.S 
%.o: %.S 
%.s: %.S 
%.mod: 
%: %.mod 
%.o: %.mod 
%.sym: 
%.def: 
%.sym: %.def 
%.h: 
%.info: 
%.dvi: 
%.tex: 
%.dvi: %.tex 
%.texinfo: 
%.info: %.texinfo 
%.dvi: %.texinfo 
%.texi: 
%.info: %.texi 
%.dvi: %.texi 
%.txinfo: 
%.info: %.txinfo 
%.dvi: %.txinfo 
%.w: 
%.c: %.w 
%.tex: %.w 
%.ch: 
%.web: 
%.p: %.web 
%.tex: %.web 
%.sh: 
%: %.sh 
%.elc: 
%.el: 
(%): % 
%.out: % 
%.c: %.w %.ch 
%.tex: %.w %.ch 
%: %,v 
%: RCS/%,v 
%: RCS/% 
%: s.% 
%: SCCS/s.% 
.web.p: 
.l.r: 
.dvi: 
.F.o: 
.l: 
.y.ln: 
.o: 
.y: 
.def.sym: 
.p.o: 
.p: 
.txinfo.dvi: 
.a: 
.l.ln: 
.w.c: 
.texi.dvi: 
.sh: 
.cc: 
.cc.o: 
.def: 
.c.o: 
.r.o: 
.r: 
.info: 
.elc: 
.l.c: 
.out: 
.C: 
.r.f: 
.S: 
.texinfo.info: 
.c: 
.w.tex: 
.c.ln: 
.s.o: 
.s: 
.texinfo.dvi: 
.el: 
.texinfo: 
.y.c: 
.web.tex: 
.texi.info: 
.DEFAULT: 
.h: 
.tex.dvi: 
.cpp.o: 
.cpp: 
.C.o: 
.ln: 
.texi: 
.txinfo: 
.tex: 
.txinfo.info: 
.ch: 
.S.s: 
.mod: 
.mod.o: 
.F.f: 
.w: 
.S.o: 
.F: 
.web: 
.sym: 
.f: 
.f.o: 

Mettre cela dans un fichier nommé disable_implicit_rules.mk et include dans tous les makefile.

4
################################################################ 
# DISABLE BUILT-IN RULES 
# 
.SUFFIXES: 
    MAKEFLAGS += -r 
+4

Je ne suis pas sûr de savoir pourquoi cette affectation de variable est imbriquée .... –

20

@hseldon a la bonne idée car .SUFFIXES ne couvre pas les règles implicites de type "match-tout". Cependant, je ne pense pas que sa syntaxe soit exacte.

MAKEFLAGS += --no-builtin-rules 

.SUFFIXES: 
.SUFFIXES: .you .own .here 

Voir http://www.gnu.org/software/make/manual/make.html#Match_002dAnything-Rules et http://www.gnu.org/software/make/manual/make.html#index-g_t_002eSUFFIXES-998

+0

Cela ne le fait pas pour moi. J'ai une règle. %: foo.o bar.o et à l'exécution make fait "rm foo.o bar.o". Cela ne disparaît pas avec votre paramètre de drapeau proposé. –

+2

@VictorEijkhout: Ce n'est pas causé par des règles intégrées, mais par [chaînage des règles] (https://www.gnu.org/software/make/manual/html_node/Chained-Rules.html). Utilisez '.SECONDARY' pour empêcher le retrait automatique. –

5

Désactivation des règles intégrées en écrivant une règle vide pour .SUFFIXES ne fonctionne pas si l'on écrit alors une autre règle .SUFFIXES d'ajouter des suffixes déjà connus - les règles intégrées sont réactivé. Exemple: On veut définir des règles pour .c.i et .i.o, et pour désactiver la règle intégrée .c.o. L'écriture

.SUFFIXES: 
.SUFFIXES: .o .i .c 

ne fonctionne pas - il ne l'empêche pas d'être appliqué la règle intégrée .c.o.

La solution est celle utilisée par Marc Eaddy et documenté dans le GNU make manuel, 10.5.6 Canceling Implicit Rules:

Vous pouvez remplacer une règle implicite intégrée (ou celui que vous avez défini vous ) par définir une nouvelle règle de modèle avec la même cible et prérequis, mais une recette différente. Lorsque la nouvelle règle est définie, , la version intégrée est remplacée. La position de la nouvelle règle dans la séquence des règles implicites est déterminée par l'endroit où vous écrivez la nouvelle règle.

Vous pouvez annuler une règle implicite intégrée en définissant une règle de modèle avec la même cible et les mêmes prérequis, mais sans recette. Par exemple, ce qui suit annulerait la règle qui exécute l'assembleur:

%.o : %.s