2010-02-16 10 views
12

Ich habe eine Makefile.am, die für den Aufbau einer Endanwendung binär verantwortlich sein wird:Wie lege ich in einem Makefile.am-Skript fest, dass ich nur Objekt-O-Dateien kompilieren möchte, mit denen später verlinkt werden kann?

Projekt/src/Makefile.am

auch im src Verzeichnis ein Unterverzeichnis ctrnn denen enthält eine weitere namens Makefile.am:

Projekt/src/ctrnn/Makefile.am

Nun ctrnn/Makefile.am nur Objekt .o Dateien mit der Idee ist, dass die Top-Level-Makefile.am die erzeugen sollte verwendet werden soll Objektdateien, die im Unterverzeichnis ctrnn generiert werden, um die Binärdatei zu erstellen.

Dies ist die ctrnn/Makefile.am

SOURCES = network.cpp\ 
    neuron.cpp 

AM_CPPFLAGS= @[email protected] 

auf dieser Makefile.am Datei auf, ich will mit network.o und neuron.o enden. Ich erzeuge die nach Makefile auto usw. verwenden, aber wenn ich versuche, und dann die Make-Datei auszuführen, ist es nicht nichts tun und nur sagt:

machen: Nichts für `all‘

mich getan werden Ich weiß, warum das so ist, ich muss das Build-Ziel angeben. Aber wie mache ich das im Skript ctrnn/Makefile.am, da ich keine Binärdatei erstellen möchte, die bin_PROGRAMS benötigt, sondern die eigentlichen Objektdateien network.o und neuron.o?

(Hinweis, wenn ich einen bin_PROGRAMS-Namen angeben, beschwert er sich zu Recht über einen undefinierten Verweis auf main).

Was mache ich falsch?

Danke, Ben.

Antwort

25

Automake kann keine Objekte ohne explizites Ziel (Programm, Bibliothek) erstellen, das diese Objekte verwendet. Ein Grund ist, dass die Kompilierungsoptionen pro Ziel angegeben werden. Wenn zwei Ziele, z.B. Zwei Binärdateien verwenden dasselbe Objekt, haben jedoch eine andere Kompilierungsoption. Dasselbe Objekt muss möglicherweise zweimal kompiliert werden.

Sie haben drei Möglichkeiten zu tun, was Sie wollen, sie alle binden Ihre Quelldateien an ein Ziel.

  1. Sie ein src/ctrnn/Makefile.am nicht verwenden, nur Bezug auf die Unterverzeichnis-Quelldateien von src/Makefile.am machen:

     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp 
    
    Beachten Sie, dass diese network.o und neuron.o im selben Verzeichnis wie main.o bauen. Wenn Sie Objekte in Unterverzeichnissen verwenden möchten, verwenden Sie AUTOMAKE_OPTIONS = subdir-objects.

  2. Verwenden Sie eine Komfortbibliothek. In src/crtnn/Makefile.am eine Bibliothek Ihrer zwei Objekte machen:

     
    noinst_LIBRARIES = libcrtnn.a 
    libcrtnn_a_SOURCES = network.cpp neuron.cpp 
    
    und in src/Makefile.am, verknüpfen die ausführbare Datei in die Bibliothek:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.a 
    SUBDIRS = crtnn 
    
    It „Convenience“ genannt wird, wenn es nicht installiert gehen werden (Sie wegen des noinst_ Präfix sagen kann): es wird nur während des Builds verwendet. Und dies ist eine statische Bibliothek, so dass das Ergebnis das gleiche ist, als ob Sie crtnn/libcrtnn.a durch crtnn/network.o und crtn/neuro.o beim Verknüpfen foo ersetzt hätten.

  3. Verwenden Sie eine Libtool-Convenience-Bibliothek. Dies erfordert mehr Setup, wenn Sie Libtool nicht bereits verwenden. Sie sollten einen Anruf LT_INIT in configure.ac hinzufügen und autoreconf erneut ausführen, um die Libtool-Dateien zu installieren. Dann können Sie src/crtnn/Makefile.am aktualisieren, um eine Bibliothek Ihrer zwei Objekte wie folgt zu erstellen:

     
    noinst_LTLIBRARIES = libcrtnn.la 
    libcrtnn_la_SOURCES = network.cpp neuron.cpp 
    
    und src/Makefile.am wie folgt:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.la 
    SUBDIRS = crtnn 
    
    Was ist der Unterschied? Sie können fragen, fast keine. Ein Vorteil der Verwendung von Libtool-Convenience-Bibliotheken besteht darin, dass sie verschachtelt werden können: Eine Libtool-Bibliothek kann eine andere Libtool-Bibliothek enthalten (dies ist praktisch, wenn Sie eine tiefe Hierarchie des Quellcodes haben und auf jeder Ebene eine Bibliothek erstellen). Auch Libtool Convenience-Bibliotheken können verwendet werden, um eine gemeinsame Bibliothek zu erstellen, wenn Sie möchten. Die statischen Bibliotheken von Automake können nicht.

+1

Danke! Ich benutze die Libtool-Methode, funktioniert perfekt :-) –

+2

Danke für eine helfende Hand für mich in der Autotools/Libtool Hölle streben. Und tu uns allen einen Gefallen: lebe lang und gedeihe! – rockdaboot

+0

foo_LDADD? Soll das nicht sein foo_LIBADD –

2

Sie könnten einfach Quelldateien im Projekt/src/Makefile.am angeben und keinen Makefile.am in ctrnn haben:

 
maude_SOURCES = ctrnn/network.cpp ctrnn/neuron.cpp 

oder Sie können eine libtool Bequemlichkeit Bibliothek verwenden. In ctrnn/Makefile.am setzen:

 
noinst_LTLIBRARIES = libctrnn.la 
libctrnn_la_SOURCES = network.cpp neuron.cpp 

und in src/Makefile.am,

setzen
 
LDADD = ctrnn/libmylib.la 

Wenn Sie nicht bereits verwenden libtool, müssen Sie auch LT_INIT hinzufügen Konfigurieren.ac.

0

Noch besser wäre es, könnte man eine Marke FORCE eine Quelle lose Ziel verwendet, indem Sie diese:

SUBDIRS = sub1 sub2 … 
lib_LTLIBRARIES = libtop.la 
libtop_la_SOURCES = 
# Dummy C++ source to cause C++ linking. 
nodist_EXTRA_libtop_la_SOURCES = dummy.cxx 
libtop_la_LIBADD = \ 
    sub1/libsub1.la \ 
    sub2/libsub2.la \ 
... 

Das Geheimnis Soße nodist_EXTRA_xxxx_la_SOURCES ist.

Weitere Details hier: https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html