2010-02-16 12 views
12

Mam Makefile.am, który będzie odpowiedzialny za budowę ostatecznej binarnego aplikacji:Jak określić w skrypcie Makefile.am, że chcę kompilować tylko pliki .o, które można później połączyć?

projekt/src/Makefile.am

również w katalogu src jest podkatalog o nazwie ctrnn który zawiera dalsze Makefile.am:

projekt/src/ctrnn/Makefile.am

teraz ctrnn/Makefile.am powinien generować tylko obiekt .o plików z ideą jest, że najwyższego poziomu Makefile.am powinien użyć pliki obiektowe wygenerowane w podkatalogu ctrnn w celu zbudowania pliku binarnego.

To ctrnn/Makefile.am

SOURCES = network.cpp\ 
    neuron.cpp 

AM_CPPFLAGS= @[email protected] 

Na podstawie tego pliku Makefile.am, chcę skończyć z network.o i neuron.o. Jestem generowania Makefile według użyciem automake etc, ale gdy próbuję, a następnie uruchomić plik make, to nie robić nic i po prostu mówi:

Producent: Nic do zrobienia w `all”

I wiem, dlaczego tak jest, muszę określić cel kompilacji. Ale jak to zrobić w skrypcie ctrnn/Makefile.am, biorąc pod uwagę, że nie chcę budować pliku binarnego, który wymagałby bin_PROGRAMS, ale rzeczywistych plików obiektowych network.o i neuron.o?

(Uwaga, jeśli określę nazwę bin_PROGRAMS, słusznie kończy się narzekaniem na niezdefiniowane odniesienie do głównej).

Co robię źle?

Dzięki, Ben.

Odpowiedz

25

Automake nie może budować obiektów bez wyraźnego celu (programu, biblioteki), który będzie używał tych obiektów. Jednym z powodów jest to, że opcje kompilacji są określone dla celu. Jeśli dwa cele, np. dwa pliki binarne używają tego samego obiektu, ale mają inną opcję kompilacji, ten sam obiekt może być skompilowany dwa razy.

Masz trzy sposoby robienia tego, co chcesz, wszystkie one wiążą twoje pliki źródłowe z jakimś celem.

  1. Nie używaj src/ctrnn/Makefile.am, tylko odnieść się do podkatalogu plików źródłowych z src/Makefile.am:

     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp 
    
    Zauważ, że to zbuduje network.o i neuron.o w tym samym katalogu co main.o. Jeśli chcesz obiektów w podkatalogach, użyj AUTOMAKE_OPTIONS = subdir-objects.

  2. Skorzystaj z biblioteki wygody. W src/crtnn/Makefile.am zrobić bibliotekę swoimi dwoma obiektami:

     
    noinst_LIBRARIES = libcrtnn.a 
    libcrtnn_a_SOURCES = network.cpp neuron.cpp 
    
    iw src/Makefile.am, połączyć swój plik wykonywalny do biblioteki:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.a 
    SUBDIRS = crtnn 
    
    To się nazywa „wygoda”, gdy nie zostanie zainstalowany (można powiedzieć, bo prefiksu noinst_): to jest właśnie używany podczas kompilacji. Jest to biblioteka statyczna, więc wynik jest taki sam jak w przypadku zastąpienia crtnn/libcrtnn.a przez crtnn/network.o i crtn/neuro.o podczas łączenia foo.

  3. Użyj biblioteki wygody Libtool. To wymaga więcej konfiguracji, jeśli nie używasz już Libtool. Powinieneś dodać numer LT_INIT w configure.ac i ponownie uruchomić autoreconf, aby zainstalować pliki libtool. Następnie można zaktualizować src/crtnn/Makefile.am, aby utworzyć bibliotekę dwóch obiektów w następujący sposób:

     
    noinst_LTLIBRARIES = libcrtnn.la 
    libcrtnn_la_SOURCES = network.cpp neuron.cpp 
    
    i src/Makefile.am w następujący sposób:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.la 
    SUBDIRS = crtnn 
    
    Jaka jest różnica? możesz zapytać, prawie żaden. Zaletą korzystania z bibliotek wygody Libtool jest to, że można je zagnieżdżać: biblioteka Libtool może zawierać inną bibliotekę Libtool (jest to wygodne, gdy masz głęboką hierarchię kodu źródłowego i budujesz bibliotekę na każdym poziomie). Również biblioteki wygody Libtool mogą być używane do budowania biblioteki współdzielonej, jeśli chcesz. Biblioteki statyczne Automake nie mogą tego zrobić.

+1

Dzięki! Skończyłem z użyciem metody libtool, działa idealnie :-) –

+2

Dzięki za pomocną dłoń dla mnie dążenie do autotools/libtool hell. I zrób nam wszystkim przysługę: żyj długo i szczęśliwie! – rockdaboot

+0

foo_LDADD? Czy to nie ma być foo_LIBADD –

2

Można po prostu określić plików źródłowych w projekcie/src/Makefile.am i nie mają Makefile.am w ctrnn:

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

czy można korzystać z biblioteki libtool ogólnospożywczy. W ctrnn/Makefile.am, umieścić:

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

w src/Makefile.am, umieścić

 
LDADD = ctrnn/libmylib.la 

Jeżeli nie korzysta już z libtool, będzie trzeba także dodać do LT_INIT configure.ac.

0

Jeszcze lepiej, można wymusić ułatwiają korzystanie cel źródłowy mniej w ten sposób:

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 \ 
... 

Sekret sos jest nodist_EXTRA_xxxx_la_SOURCES.

Więcej szczegółów tutaj: https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html

Powiązane problemy