2013-03-13 49 views
5

Tôi đang phát triển một dự án hiện đang được viết bằng C nhưng tôi định viết một số hàm trong asm cho ít nhất hai nền tảng (x86_64 và cánh tay) . Vì vậy, tôi có thể có một số file nguồn:Sử dụng autotools cho dự án có mã nguồn cụ thể nền tảng (nhiều nền tảng)

generic/one.c generic/two.c generic/three.c

cánh tay/one.s

x86_64/two.s

Tôi thích nó để kịch bản cấu hình chọn tệp .s trên các tệp .c khi có thể. Vì vậy, xây dựng trên cánh tay sẽ là một, hai, ba, v.v.

Có vẻ như khó khăn hoặc không thể làm điều này độc đáo với automake. Nhưng nếu tôi tự động mương tôi sẽ phải theo dõi sự phụ thuộc của chính mình (ugh).

Cách tốt nhất để làm điều này là gì?

+1

"Nhưng nếu tôi tự động mương tôi sẽ phải theo dõi các phụ thuộc của riêng mình (ugh)". đó là một sự phân đôi giả! Đừng quên các công cụ như CMake. Trong thực tế, đây là [danh sách lớn] (https://en.wikipedia.org/wiki/List_of_build_automation_software#Build_script_generation_tools) – congusbongus

Trả lời

2

Phần Conditional Sources của hướng dẫn sử dụng tự động sẽ hướng bạn đi đúng hướng. Bạn sẽ muốn AC_CANONICAL_HOST trong configure.ac và sau đó đưa ra quyết định dựa trên giá trị của $host.

automake sẽ không thích nếu hai tệp có thể biên dịch cho cùng một đối tượng. Nếu bạn không thể đổi tên các nguồn như ở phần liên kết của thủ công, bạn có thể muốn thử một cái gì đó như thế này (chắc chắn rằng bạn có subdir-objects trong AM_INIT_AUTOMAKE:

# Note the $() isn't a shell command substitution. 
# The quoting means it'll be expanded by `make'. 
MODULE_ONE_OBJ='generic/one.$(OBJEXT)' 
MODULE_TWO_OBJ='generic/two.$(OBJEXT)' 
case $host in 
    # ... 
    arm*) 
    MODULE_ONE='arm/one.$(OBJEXT)' 
    ;; 
    x86_64) 
    MODULE_TWO='x86/two.$(OBJEXT)' 
    ;; 
esac 
AC_SUBST([MODULE_ONE]) 
AC_SUBST([MODULE_TWO]) 

Trong Makefile.am:

bin_PROGRAMS = foo 
foo_SOURCES = foo.c 
EXTRA_foo_SOURCES = arm/one.s x86/two.c 
foo_LDADD = $(MODULE_ONE) $(MODULE_TWO) 
foo_DEPENDENCIES = $(MODULE_ONE) $(MODULE_TWO) 
+2

Tôi đã tìm ra cách để làm điều đó một chút trong configure.ac, rắc rối là ngay cả khi bạn thêm one.c và one.s để build_SOURCES có điều kiện trong Makefile.am, automake sẽ phàn nàn rằng cả hai đều tạo ra one.o. – Borbus

2

Bạn có thể sử dụng AC_CANONICAL_HOST và sau đó có điều kiện chọn thư mục con đúng Ví dụ, trong configure.ac:.

AC_CANONICAL_HOST 
AC_SUBST([USE_DIR],[$host_cpu]) 
test -d $srcdir/$USE_DIR || USE_DIR=generic 

và sau đó trong Makefile.am:

SUBDIRS = $(USE_DIR) common 

và trong common/Makefile.am:

LDADD = ../$(USE_DIR)/libfoo.a 

và trong mỗi ${host_cpu}/Makefile.am:

noinst_LIBRARIES = libfoo.a 
libfoo_a_SOURCES = one.s ../common/two.c 

này sử dụng một cấu trúc thư mục hơi khác so với bạn mô tả. Các tệp C được sử dụng trên tất cả các nền tảng sẽ có trong common và được liên kết với thư viện tiện lợi được tạo trong thư mục nền tảng cụ thể. Nếu một số tệp c chỉ được sử dụng trên một số nền tảng, bạn có thể đặt chúng chung và tham chiếu chúng một cách rõ ràng trong Makefile.am cho các nền tảng cần chúng.

+1

Điều đó sẽ phá vỡ 'làm cho dist'? –

+0

Nó phải là $ host_cpu không phải $ target_cpu nhưng một cái gì đó như thế này có thể làm việc. Mục tiêu là cho những thứ như trình biên dịch có thể được cấu hình để được xây dựng để biên dịch cho các nền tảng khác (trình biên dịch chéo). Tôi đã nghĩ về một cái gì đó tương tự nhưng lại gặp rắc rối một lần nữa. – Borbus

+1

Ngoài ra: 'AC_CANONICAL_TARGET' không phải là thứ bạn muốn. '--target' là để thiết lập kiến ​​trúc đích của trình biên dịch. '--host' là máy chạy các tệp nhị phân được xây dựng. –

2

Đây là những gì tôi làm.

configure.ac

... 
AC_CANONICAL_SYSTEM 
AM_PROG_AS 
AC_PROG_CC 
... 
PROC="" 
AS_CASE([$host_cpu], [x86_64], [PROC="x86_64"], [arm*], [PROC="arm"]) 

AM_CONDITIONAL([CPU_X86_64], [test "$PROC" = "x86_64"]) 
AM_CONDITIONAL([CPU_ARM], [test "$PROC" = "arm"]) 
AM_CONDITIONAL([CPU_UNDEFINED], [test "x$PROC" = "x"]) 

Makefile.am

lib_LTLIBRARIES = libfoo.la 
libfoo_la_SOURCES = \ 
$(top_srcdir)/generic/three.c 

if CPU_ARM 
libfoo_la_SOURCES += $(top_srcdir)/arm/one.s \ 
$(top_srcdir)/generic/two.c 
endif 

if CPU_X86_64 
libfoo_la_SOURCES += $(top_srcdir)/generic/one.c \ 
$(top_srcdir)/x86_64/two.s 
endif 

if CPU_UNDEFINED 
libfoo_la_SOURCES += $(top_srcdir)/generic/one.c \ 
$(top_srcdir)/generic/two.c 
endif 
Các vấn đề liên quan