2010-12-16 123 views
1

Je suis en train de mettre à jour des Makefiles pour passer de Make 3.81 à 3.82. En plusieurs endroits, l'auteur original utilisé quelque chose comme ceci pour construire libs statiques:

all: lib$(library).a($objects) 

Cela semble construire chaque fichier .o à son tour et l'insérer dans le .a en utilisant ar:

g++ -O2 <snip> -o some_obj.o some_cpp.cpp 
ar rv libsome_lib.a some_obj.o 
etc... 

cette nouvelle version marque, cependant, selfs avec:

*** No rule to make target 'libsome_lib.a()', needed by 'all' 

suis-je sûr de remplacer ce raccourci avec la façon dont je suis habitué à faire:

lib$(library).a: $(objects) 
    ar -rs lib$(library).a $objects 

Merci.

EDIT

On dirait que je besoin d'une meilleure éducation Makefile. Voici un extrait de la plus grande Makefile d'origine:

CXXFLAGS += -O2 -g -Wall -Wunused-parameter \ 
    `pkg-config --cflags gthread-2.0 glibmm-2.4 gtkmm-2.4` 

libs += `pkg-config --libs gthread-2.0 glibmm-2.4` -lc 

%.d: %.cpp 
    $(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \ 
         | sed '\''s/\($*\)\.o[ :]*/\1.o [email protected] : /g'\'' > [email protected]; \ 
         [ -s [email protected] ] || rm -f [email protected]' 
%.d: %.c 
    $(SHELL) -ec '$(CXX) -M $(CPPFLAGS) $(CXXFLAGS) $< \ 
         | sed '\''s/\($*\)\.o[ :]*/\1.o [email protected] : /g'\'' > [email protected]; \ 
         [ -s [email protected] ] || rm -f [email protected]' 

from_sources = $(patsubst %.c,$(2),$(filter %.c, $(1))) $(patsubst %.cpp,$(2),$(filter %.cpp, $(1))) 

sources = $(shell cat sources.inc) 
objects = $(call from_sources,$(sources),%.o) 
depends = $(call from_sources,$(sources),%.d) 

library = some_lib 

.PHONY: all clean fresh 

all: lib$(library).a($(objects)) 

clean: 
    <SNIP> 

if neq($(MAKECMDGOALS),clean) 
    include $(depends) 
endif 

Lorsque cela fonctionne sous 3.81, je reçois tous les .d créés dépendances, puis faire commence g ++ les fichiers OBJ ing. Sous 3.82, j'obtiens les fichiers .d mais pas .o et make échoue avec "*** Aucune règle à faire ..."

+0

Par souci d'exhaustivité, voulez-vous dire GNU Make? – beldaz

+0

@beldaz, oui désolé GNU Make. – Mark

+0

Ce que la [fonction d'appel] (http://www.gnu.org/software/make/manual/make.html#Call-Function) est censée faire. Notez la façon dont les variables type = (par opposition à: = type) se lient tard, provoquant ainsi des choses intéressantes. Trop intelligent pour mon petit cerveau fatigué. – dmckee

Répondre

4

Il s'agit de la syntaxe "membre d'archive" gnu make. C'est un peu trop intime avec les outils à mon goût, mais ça y est. L'erreur d'origine peut être provoquée par $ (objets) étant vide. Mais je ne suis pas vraiment sûr. Voici quelques documents:

http://www.gnu.org/software/make/manual/make.html#Archive-Members

11.1 Les membres Archives comme cibles

Un membre individuel d'un fichier d'archive peut être utilisé comme une cible ou condition sine qua non à faire. Vous spécifiez le membre nommé membre dans l'archive fichier archive comme suit:

archive(member) 

Cette construction est disponible uniquement dans les objectifs et les conditions préalables, et non dans les recettes! La plupart des programmes que vous pouvez utiliser dans les recettes ne supportent pas cette syntaxe et ne peuvent pas agir directement sur les membres de l'archive . Seul Ar et d'autres programmes spécialement conçus pour fonctionner sur les archives peuvent le faire. Par conséquent, des recettes valides pour mettre à jour une cible membre d'archive doivent probablement utiliser ar. Par exemple, cette règle dit créer un hack.o membre dans foolib archives en copiant le fichier hack.o:

foolib(hack.o) : hack.o 
     ar cr foolib hack.o 

En fait, la quasi-totalité des objectifs membres archives sont mis à jour en seulement cette façon et il y a une règle implicite à le faire pour vous. Remarque: Le drapeau 'c' à ar est requis si le fichier archive n'existe pas.

1

Peut-être, mais vous n'avez aucune règle explicite pour convertir quelque chose comme xyz.cpp en xyz.o, qui vous pourriez avoir besoin de vos sources avant d'essayer d'injecter leurs objets dans la bibliothèque. Il peut être une règle implicite appropriée pour cela, vérifiez d'abord.

La première question que je voudrais poser est: ce qui est arrivé à $objects qui vous a d'essayer de cibler libsome_lib.a() (à savoir, avec rien entre les parenthèses) en premier lieu?

Pour être honnête, j'ai tendance à éviter autant que possible ces règles englobantes, préférant les déclarations explicites de dépendances (à moins qu'il y ait un lot de dépendances, bien sûr). Oui, je sais que cela rend les makefiles plus grands et me marque comme un luddite au moins partiel, mais je préfère avoir des choses qui fonctionnent juste sur des choses qui fonctionnent intelligemment.

Cut'n'paste est l'un des outils les plus puissants dans ma boîte à outils :-)

+0

s'il vous plaît voir ci-dessus, on dirait que j'ai besoin de moi un peu plus d'apprentissage. – Mark

+0

Luddite! Luddite! Bien sûr, le mécanisme particulier utilisé ici est complètement nouveau pour moi. Je dois aller lire des docs maintenant ... – dmckee

+0

Sauf qu'une fois que vous obtenez la génération automatique de dépendances de gcc, vous n'avez plus jamais à vous soucier de la maintenance des makefiles complexes. –

3

Votre semble bon, mais il doit être plus à l'ancienne makefile si l'ancienne a travaillé du tout.

Oh, et juste pour la bonne forme, je vous suggère ceci:

lib$(library).a: $(objects) 
    ar -rs [email protected] $^ 

EDIT
Ne vous sentez pas mal de ne pas comprendre très bien faire; il a tout à fait une courbe d'apprentissage.

Il n'est pas encore assez pour aller ici, mais si sources.inc n'est pas trop énorme, vous pouvez essayer ce qui suit en 3.81 et 3.82 et rechercher des différences:

experiment: 
    @echo sources: $(sources) 
    @echo objects: $(objects) 
    @echo depends: $(depends) 

La preuve à ce jour est que objects est vide sous 3,82, mais si les .d fichiers sont en cours de reconstruction sous 3,82 qui suggère que depends est pas vide, ce qui est très étrange.

+0

merci, s'il vous plaît voir des informations supplémentaires. – Mark