Comment puis-je spécifier dans un script Makefile.am que je veux seulement compiler objet .o?
Question
J'ai un Makefile.am
qui sera responsable de la construction d'un binaire d'application finale:
project/src/Makefile.am
également dans le répertoire src est un sous-répertoire appelé ctrnn
qui contient un Makefile.am
supplémentaire:
project/src/ctrnn/Makefile.am
Maintenant, ctrnn/Makefile.am
ne doit générer des fichiers .o
objet avec l'idée étant que le Makefile.am
haut niveau doit utiliser les fichiers objet générés dans sous-répertoire ctrnn
pour construire le binaire.
Ceci est le ctrnn/Makefile.am
:
SOURCES = network.cpp\
neuron.cpp
AM_CPPFLAGS= @CXXFLAGS@
Sur la base de ce fichier Makefile.am
, je veux finir avec network.o et neuron.o. Je générer les Makefile
selon l'utilisation Automake etc, mais lorsque je tente puis exécutez le fichier makefile, il ne fait rien et dit simplement:
make: Nothing to be done for `all'
Je sais pourquoi est-ce, je dois préciser la cible de construction. Mais comment dois-je faire cela dans le script ctrnn/Makefile.am
étant donné que je ne veux pas construire un binaire qui nécessiterait des fichiers bin_PROGRAMS
mais l'objet réel network.o
et neuron.o
?
(Remarque si je spécifier un nom bin_PROGRAMS, elle finit par se plaindre à juste titre d'une référence non définie à principal).
Que suis-je fait de mal?
La solution
Automake ne peut pas construire des objets sans une cible explicite (programme, bibliothèque) qui utilisera ces objets. L'une des raisons est que les options de compilation sont spécifiées par cible. Si deux cibles, par exemple deux binaires utiliser le même objet, mais ont différentes options de compilation, le même objet peut être compilé deux fois.
Vous avez trois façons de faire ce que vous voulez, ils impliquent tous lacer vos fichiers source à une cible.
-
Ne pas utiliser
src/ctrnn/Makefile.am
, simplement faire référence aux fichiers sources sous-répertoire de votresrc/Makefile.am
:bin_PROGRAMS = foo foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
Notez que cela construiranetwork.o
etneuron.o
dans le même répertoire quemain.o
. Si vous voulez des objets dans les sous-répertoires, utilisezAUTOMAKE_OPTIONS = subdir-objects
. -
Utilisez une bibliothèque de commodité. En
src/crtnn/Makefile.am
faire une bibliothèque de vos deux objets:noinst_LIBRARIES = libcrtnn.a libcrtnn_a_SOURCES = network.cpp neuron.cpp
etsrc/Makefile.am
, lier votre exécutable à la bibliothèque:bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = crtnn/libcrtnn.a SUBDIRS = crtnn
Il est appelé « commodité » quand il ne va pas être installé (vous pouvez dire à cause du préfixenoinst_
): il est juste utilisé lors de la construction. Et ceci est une bibliothèque statique, de sorte que le résultat est le même que si vous aviez remplacé parcrtnn/libcrtnn.a
crtnn/network.o
etcrtn/neuro.o
lors de la liaisonfoo
. -
Utilisez une bibliothèque de proximité Libtool. Cela nécessite plus de configuration si vous ne l'utilisez Libtool déjà. Vous devez ajouter un
LT_INIT
d'appel dansconfigure.ac
et exécutez à nouveauautoreconf
pour installer les fichiers libtool. Ensuite, vous pouvez mettre à joursrc/crtnn/Makefile.am
pour faire une bibliothèque de vos deux objets comme suit:noinst_LTLIBRARIES = libcrtnn.la libcrtnn_la_SOURCES = network.cpp neuron.cpp
etsrc/Makefile.am
comme suit:bin_PROGRAMS = foo foo_SOURCES = main.c foo_LDADD = crtnn/libcrtnn.la SUBDIRS = crtnn
Quelle est la différence? vous pouvez demander, presque aucun. L'un des avantages de l'utilisation des bibliothèques de proximité libtool est qu'ils peuvent être imbriquées: une bibliothèque Libtool peut inclure une autre bibliothèque Libtool (ce qui est pratique lorsque vous avez une hiérarchie profonde du code source et que vous construisez une bibliothèque à chaque niveau). Aussi les bibliothèques de proximité libtool peuvent être utilisés pour construire une bibliothèque partagée si vous voulez. bibliothèques statiques de automake ne peut pas.
Autres conseils
Vous pouvez simplement spécifier les fichiers source dans le projet / src / Makefile.am et non un Makefile.am dans ctrnn:
maude_SOURCES = ctrnn/network.cpp ctrnn/neuron.cpp
ou vous pouvez utiliser une bibliothèque de proximité libtool. Dans ctrnn / Makefile.am, mettre:
noinst_LTLIBRARIES = libctrnn.la libctrnn_la_SOURCES = network.cpp neuron.cpp
et dans src / Makefile.am, mettre
LDADD = ctrnn/libmylib.la
Si vous n'êtes pas déjà utilisé libtool, vous aurez également besoin d'ajouter LT_INIT à configure.ac.
Mieux encore, vous pouvez forcer une marque en utilisant une cible de source moins en faisant ceci:
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 \
...
La sauce secrète est nodist_EXTRA_xxxx_la_SOURCES
.
Plus de détails dans ici: https: // www .gnu.org / logiciel / automake / manuel / html_node / Libtool-Convenience-libraries.html