简体   繁体   English

将Autotools用于具有特定于平台的源代码的项目

[英]Using Autotools for a project with platform specific source code

I'm developing a project that is currently written in C but I plan to write some of the functions in ASM for at least two platforms (x86_64 and arm). 我正在开发一个目前用C语言编写的项目,但我计划在ASM中为至少两个平台(x86_64和arm)编写一些函数。 So I might have some source files: 所以我可能有一些源文件:

  • generic/one.c 通用/ one.c
  • generic/two.c 通用/ two.c
  • generic/three.c 通用/ three.c
  • arm/one.s ARM / one.s
  • x86_64/two.s x86_64的/ two.s

I'd like it so that the configure script chooses the .s files over the .c files when possible. 我喜欢它,以便配置脚本在可能的情况下选择.s文件.c文件。 So building on arm will be one.s, two.c, three.c etc. 所以建立在arm上将是one.s,two.c,three.c等。

It seems difficult or impossible to do this nicely with Automake. 使用Automake很难或不可能做到这一点。 But if I ditch Automake I'll have to track my own dependencies (ugh). 但如果我放弃Automake,我将不得不追踪自己的依赖(呃)。

What's the best way to do this? 最好的方法是什么?

Here's what I do. 这就是我的工作。

configure.ac 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 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

The Conditional Sources section of the automake manual should point you in the right direction. automake手册的“ 条件来源”部分应指向正确的方向。 You're going to want AC_CANONICAL_HOST in configure.ac and then make decisions based on the value of $host . 您将在configure.ac想要AC_CANONICAL_HOST ,然后根据$host的值进行决策。

automake won't like it if two files can compile to the same object. 如果两个文件可以编译到同一个对象, automake将不会喜欢它。 If you can't rename the sources like in the linked part of the manual, you may want to try something like this (make sure you have subdir-objects in AM_INIT_AUTOMAKE : 如果你不能像手册的链接部分那样重命名源代码,你可能想尝试这样的事情(确保在AM_INIT_AUTOMAKEsubdir-objects

# 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])

In Makefile.am : 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)

You can use AC_CANONICAL_HOST and then conditionally select the correct subdirectory. 您可以使用AC_CANONICAL_HOST,然后有条件地选择正确的子目录。 For example, in configure.ac : 例如,在configure.ac

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

and then in Makefile.am : 然后在Makefile.am

SUBDIRS = $(USE_DIR) common

and in common/Makefile.am : common/Makefile.am

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

and in each ${host_cpu}/Makefile.am : 并在每个${host_cpu}/Makefile.am

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

This uses a slightly different directory structure than you describe. 这使用的目录结构与您描述的略有不同。 C files that are used on all platforms would go in common and be linked to a convenience library constructed in the platform specific directory. 在所有平台上使用的C文件将common并链接到在特定于平台的目录中构建的便捷库。 If some c files are used on only some platforms, you could put them in common and reference them explicitly in the Makefile.am for the platforms that need them. 如果某些c文件仅在某些平台上使用,则可以将它们放在一起,并在Makefile.am中为需要它们的平台显式引用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM