我正在尝试使用autotools(autoconf,automake,libtool)创建一个库作为构建系统。该库必须是可交叉编译的,但构建它的步骤之一是通过在整个过程中从源构建的可执行文件生成源。
问题是我不能使用automake的系统来构建中间二进制文件,因为当它进行交叉编译时,它不能在'--build'上运行来生成源代码。
解决这个问题的一种方法是创建单独的autools项目来构建中间二进制文件但是我想避免它,因为有许多标题和其他“数据”文件对于中间可执行文件和最终库是常见的所以我想保留它一个地方,除了那些中间二进制文件应该是“noinst”。
还有其他方法可以使其正常工作并保持可移植性吗?我试图使用ax_prog_cxx_for_build,但在交叉编译时我找不到--build的EXEEXT。
以下是解释我问题的问题示例:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
AC_INIT([libfoobar], [0.1.0], [<NOBUGS>])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_CONFIG_SRCDIR([src/bar.cpp])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_FILES([Makefile
src/Makefile])
# Checks for programs.
AC_PROG_CXX
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
bin_PROGRAMS = bar
lib_LTLIBRARIES = libfoo.la
noinst_bar_SOURCES = bar.cpp
libfoo_la_SOURCES = foo.cpp
nodist_libfoo_la_SOURCES = foobar.h
BUILT_SOURCES: foobar.h
foobar.h: bar$(EXEEXT) Makefile
./$< >$@
CLEANFILES = foobar.h
#include "foobar.h"
extern "C" int foo() {
return foobar_value;
}
#include <iostream>
int main() {
std::cout << "#ifndef FOOBAR_H" << std::endl;
std::cout << "#define FOOBAR_H" << std::endl;
std::cout << std::endl;
std::cout << "static const int foobar_value = 0xdeadbeef;" << std::endl;
std::cout << std::endl;
std::cout << "#endif" << std::endl;
}
答案 0 :(得分:6)
如果你正在使用AX_PROG_CXX_FOR_BUILD
,那么你应该使用的EXEEXT
是BUILD_EXEEXT
,它是在宏AX_PROG_CC_FOR_BUILD
中定义的AX_PROG_CXX_FOR_BUILD
}要求)。对EXEEXT
构建的内容使用CXX_FOR_BUILD
将是一个错误,因为它是主机工具链的扩展。所以在这种情况下,你需要更多的东西:
<强> configure.ac 强>
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68])
AC_INIT([libfoobar], [0.1.0], [<NOBUGS>])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CONFIG_SRCDIR([src/bar.cpp])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_FILES([Makefile
src/Makefile])
# Checks for programs.
AC_PROG_CXX
AX_PROG_CXX_FOR_BUILD
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
<强>的src / Makefile.am 强>
noinst_PROGRAMS = bar
lib_LTLIBRARIES = libfoo.la
bar_SOURCES = bar.cpp
LINK_FOR_BUILD.cpp = $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) $(CPPFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) $(TARGET_ARCH_FOR_BUILD)
bar$(BUILD_EXEEXT) : $(bar_OBJECTS)
$(LINK_FOR_BUILD.cpp) $^ $(LOADLIBES_FOR_BUILD) $(LDLIBS_FOR_BUILD) -o $@
$(bar_OBJECTS) : CC=$(CC_FOR_BUILD)
$(bar_OBJECTS) : CXXFLAGS=$(CXXFLAGS_FOR_BUILD)
$(bar_OBJECTS) : CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
libfoo_la_SOURCES = foo.cpp
nodist_libfoo_la_SOURCES = foobar.h
BUILT_SOURCES: foobar.h
foobar.h: bar$(BUILD_EXEEXT) Makefile
./$< >$@
CLEANFILES = foobar.h
答案 1 :(得分:0)
这将有所帮助,但部分原因。 Autotools仍然后缀--host&#39; $(EXEEXT)到_PROGRAMS所以在交叉编译期间我无法使用autotools功能。
我找到了另一种解决方案。它真的很脏,但有效。我在适当的源代码中创建了autotools子项目,并在文件的最底部将其链接并添加到我的configure.ac中:
if [[ "x$cross_compiling" != "xyes" ]]; then
AC_CONFIG_SUBDIRS(src/tools)
fi
AC_OUTPUT
if [[ "x$cross_compiling" = "xyes" ]]; then
mkdir -p src/tools
cd src/tools && ../../"$srcdir"/src/tools/configure --cache-file=/dev/null --host=$build --target=$host
fi
在Makefile.am中,我直接引用tools目录中的二进制文件:
SUBDIRS = tools
foobar.h: tools/gencpu$(BUILD_EXEEXT)
./$< >$@
BUILT_SOURCES: foobar.h
CLEANFILES = foobar.h
除非我找到更好,更优雅&#34;解决方案我会坚持下去。