Comment puis-je spécifier dans un script Makefile.am que je veux seulement compiler objet .o?

StackOverflow https://stackoverflow.com/questions/2272697

  •  20-09-2019
  •  | 
  •  

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?

Était-ce utile?

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.

  1. Ne pas utiliser src/ctrnn/Makefile.am, simplement faire référence aux fichiers sources sous-répertoire de votre src/Makefile.am:

    bin_PROGRAMS = foo
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp
    
    Notez que cela construira network.o et neuron.o dans le même répertoire que main.o. Si vous voulez des objets dans les sous-répertoires, utilisez AUTOMAKE_OPTIONS = subdir-objects.

  2. 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
    
    et src/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éfixe noinst_): 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é par crtnn/libcrtnn.a crtnn/network.o et crtn/neuro.o lors de la liaison foo.

  3. 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 dans configure.ac et exécutez à nouveau autoreconf pour installer les fichiers libtool. Ensuite, vous pouvez mettre à jour src/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
    
    et src/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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top