问题描述
我正在尝试使用自动工具(autoconf,automake,libtool)作为构建系统来创建一个库.该库必须是可交叉编译的,但是构建它的步骤之一是在整个过程中通过从源代码构建的可执行文件生成源代码.
I'm trying to create a library using autotools (autoconf, automake, libtool) as a build system. The library has to be cross-compileable, but one of the steps of building it is to generate sources by executable built from sources during the whole process.
问题是我不能使用automake的系统来构建中间二进制文件,因为当它被交叉编译时,它不会在'--build'上运行以生成源代码.
The problem is I cannot use automake's system to build the intermediate binary because when it's cross compile it wouldn't run on '--build' to generate sources.
解决此问题的一种方法是创建单独的autools项目以构建中间二进制文件,但我想避免使用它,因为中间可执行文件和最终库有很多头文件和其他数据"文件,因此我希望将其保留在其中除了那些中间二进制文件,还应该是"noinst".
One way to work this around it to create separate autools project to build intermediate binaries but I want to avoid it because there are many headers and other "data" files common for intermediate executable and final library so I want to keep it in one place, besides those intermediate binaries should be "noinst".
还有其他方法可以使其正常运行并保持可移植性吗?我试图使用 ax_prog_cxx_for_build ,但找不到--build交叉编译时为EXEEXT.
Is there any other way to make it work properly and retain portability? I was trying to use ax_prog_cxx_for_build but I couldn't find --build's EXEEXT when cross compiling.
以下是该问题的一个例子,目的只是为了说明我的问题:
Here's an example of the issue just to illustrate my problem:
# -*- 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
Makefile.am
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
src/Makefile.am
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
src/foo.cpp
#include "foobar.h"
extern "C" int foo() {
return foobar_value;
}
src/bar.cpp
#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;
}
推荐答案
如果您使用的是 AX_PROG_CXX_FOR_BUILD
,那么您应该使用的EXEEXT
是BUILD_EXEEXT
,它在宏 AX_PROG_CC_FOR_BUILD
(AX_PROG_CXX_FOR_BUILD
要求).将EXEEXT
用于由CXX_FOR_BUILD
构建的对象将是一个错误,因为这是宿主工具链的扩展.因此,在这种情况下,您将需要更多类似的东西:
If you're using AX_PROG_CXX_FOR_BUILD
, then the EXEEXT
you should be using is BUILD_EXEEXT
which is defined in the macro AX_PROG_CC_FOR_BUILD
(which AX_PROG_CXX_FOR_BUILD
requires). Using EXEEXT
for something built by CXX_FOR_BUILD
would be an error, since that's the extension for the host toolchain. So in this case you'll need something more like:
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
这篇关于Autotools交叉编译和生成的源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!