2010-02-16 12 views
12

Tôi có một Makefile.am mà sẽ chịu trách nhiệm xây dựng một ứng dụng nhị phân thức:Làm cách nào để chỉ định trong tập lệnh Makefile.am mà tôi chỉ muốn biên dịch các tệp .o đối tượng có thể được liên kết sau này?

dự án/src/Makefile.am

cũng trong thư mục src là một thư mục con gọi là ctrnn chứa thêm Makefile.am:

dự án/src/ctrnn/Makefile.am

Bây giờ, ctrnn/Makefile.am chỉ nên tạo ra đối tượng .o files với ý tưởng được rằng cấp cao nhất Makefile.am nên sử dụng các tệp đối tượng được tạo trong thư mục con ctrnn để tạo tệp nhị phân.

Đây là ctrnn/Makefile.am

SOURCES = network.cpp\ 
    neuron.cpp 

AM_CPPFLAGS= @[email protected] 

Dựa trên tập tin Makefile.am này, tôi muốn kết thúc với network.o và neuron.o. Tôi tạo ra Makefile theo sử dụng automake vv, nhưng khi tôi cố gắng và sau đó thực hiện làm cho tập tin, nó không làm bất cứ điều gì và chỉ nói:

thực hiện: Không có gì phải làm cho `tất cả'

tôi biết tại sao điều này là, tôi cần phải xác định mục tiêu xây dựng. Nhưng làm thế nào để tôi làm điều này trong kịch bản ctrnn/Makefile.am cho rằng tôi không muốn xây dựng một nhị phân mà sẽ yêu cầu bin_PROGRAMS nhưng các tập tin đối tượng thực tế network.o và neuron.o?

(Lưu ý nếu tôi chỉ định tên bin_PROGRAMS, nó sẽ kết thúc đúng khi khiếu nại về tham chiếu chưa được xác định cho chính).

Tôi làm gì sai?

Xin cảm ơn, Ben.

Trả lời

25

Tự động không thể xây dựng các đối tượng mà không có mục tiêu rõ ràng (chương trình, thư viện) sẽ sử dụng các đối tượng này. Một lý do là tùy chọn biên dịch được chỉ định cho mỗi mục tiêu. Nếu hai mục tiêu, ví dụ: hai tập tin nhị phân sử dụng cùng một đối tượng nhưng có tùy chọn biên dịch khác nhau, cùng một đối tượng có thể phải được biên dịch hai lần.

Bạn có ba cách để thực hiện những gì bạn muốn, tất cả đều liên quan đến việc buộc các tệp nguồn của bạn vào một số mục tiêu.

  1. Không sử dụng một src/ctrnn/Makefile.am, chỉ cần đảm tham chiếu đến các file nguồn thư mục con từ src/Makefile.am của bạn:

     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c crtnn/network.cpp crtnn/neuron.cpp 
    
    Lưu ý rằng điều này sẽ xây dựng network.oneuron.o trong cùng thư mục với main.o. Nếu bạn muốn các đối tượng trong thư mục con, hãy sử dụng AUTOMAKE_OPTIONS = subdir-objects.

  2. Sử dụng thư viện tiện lợi. Trong src/crtnn/Makefile.am tạo một thư viện của hai đối tượng của bạn:

     
    noinst_LIBRARIES = libcrtnn.a 
    libcrtnn_a_SOURCES = network.cpp neuron.cpp 
    
    và trong src/Makefile.am, liên kết thực thi của bạn đến thư viện:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.a 
    SUBDIRS = crtnn 
    
    Nó được gọi là "thuận tiện" khi nó sẽ không được cài đặt (bạn có thể nói vì tiền tố noinst_): nó chỉ được sử dụng trong quá trình xây dựng. Và đây là thư viện tĩnh, do đó kết quả cũng giống như nếu bạn đã thay thế crtnn/libcrtnn.a bằng cách crtnn/network.ocrtn/neuro.o khi liên kết foo.

  3. Sử dụng thư viện tiện lợi Libtool. Điều này đòi hỏi nhiều thiết lập hơn nếu bạn không sử dụng Libtool. Bạn nên thêm một cuộc gọi LT_INIT trong configure.ac và chạy lại autoreconf để cài đặt các tệp libtool. Sau đó, bạn có thể cập nhật src/crtnn/Makefile.am để tạo thư viện cho hai đối tượng của mình như sau:

     
    noinst_LTLIBRARIES = libcrtnn.la 
    libcrtnn_la_SOURCES = network.cpp neuron.cpp 
    
    src/Makefile.am như sau:
     
    bin_PROGRAMS = foo 
    foo_SOURCES = main.c 
    foo_LDADD = crtnn/libcrtnn.la 
    SUBDIRS = crtnn 
    
    Sự khác biệt là gì? bạn có thể hỏi, hầu như không có gì. Một lợi thế của việc sử dụng thư viện tiện lợi Libtool là chúng có thể lồng nhau: một thư viện Libtool có thể bao gồm một thư viện Libtool khác (điều này thuận tiện khi bạn có một hệ thống phân cấp sâu của mã nguồn và bạn đang xây dựng một thư viện ở mỗi cấp). Ngoài ra thư viện tiện lợi Libtool có thể được sử dụng để xây dựng một thư viện chia sẻ nếu bạn muốn. Các thư viện tĩnh của Automake không thể.

+1

Cảm ơn! Tôi đã kết thúc bằng cách sử dụng phương pháp libtool, hoạt động hoàn hảo :-) –

+2

Cảm ơn một bàn tay giúp đỡ cho tôi phấn đấu trong autotools/libtool địa ngục. Và làm tất cả chúng ta một ân huệ: sống lâu và thịnh vượng! – rockdaboot

+0

foo_LDADD? Không phải là nghĩa vụ phải là foo_LIBADD –

2

Bạn chỉ có thể chỉ định file nguồn trong dự án/src/Makefile.am và không có một Makefile.am trong ctrnn:

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

hoặc bạn có thể sử dụng một thư viện libtool tiện lợi. Trong ctrnn/Makefile.am, đưa:

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

và trong src/Makefile.am, đặt

 
LDADD = ctrnn/libmylib.la 

Nếu bạn chưa sử dụng libtool, bạn cũng sẽ cần phải thêm LT_INIT để configure.ac.

0

Hơn thế nữa, bạn có thể buộc một làm cho sử dụng một mục tiêu nguồn ít bằng cách làm này:

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

Các gravy bí mật là nodist_EXTRA_xxxx_la_SOURCES.

Thêm chi tiết tại đây: https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html