【问题标题】:Autotools cross compilation and generated sourcesAutotools 交叉编译和生成源
【发布时间】:2014-08-03 18:33:54
【问题描述】:

我正在尝试使用 autotools(autoconf、automake、libtool)作为构建系统来创建一个库。该库必须是可交叉编译的,但构建它的步骤之一是在整个过程中通过从源构建的可执行文件生成源。

问题是我不能使用 automake 的系统来构建中间二进制文件,因为当它交叉编译时,它不会在“--build”上运行来生成源代码。

解决这个问题的一种方法是创建单独的 autools 项目来构建中间二进制文件,但我想避免它,因为中间可执行文件和最终库有很多头文件和其他“数据”文件,所以我想保留它一个地方,除了那些中间二进制文件应该是“noinst”。

有没有其他方法可以让它正常工作并保持可移植性?我尝试使用ax_prog_cxx_for_build,但在交叉编译时找不到--build的EXEEXT。

这是一个问题示例,只是为了说明我的问题:

配置.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_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;
}

【问题讨论】:

    标签: cross-compiling gnu autotools autoconf automake


    【解决方案1】:

    如果您使用的是AX_PROG_CXX_FOR_BUILD,那么您应该使用的EXEEXTBUILD_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
    

    【讨论】:

      【解决方案2】:

      这会有所帮助。 Autotools 仍然将 --host 的 $(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 中,我直接引用工具目录中的二进制文件:

      SUBDIRS = tools
      
      foobar.h: tools/gencpu$(BUILD_EXEEXT)
          ./$< >$@
      
      BUILT_SOURCES: foobar.h
      
      CLEANFILES = foobar.h
      

      除非我找到更好、更“优雅”的解决方案,否则我会坚持下去。

      【讨论】:

        猜你喜欢
        • 2015-03-28
        • 1970-01-01
        • 1970-01-01
        • 2010-12-08
        • 1970-01-01
        • 2015-12-07
        • 1970-01-01
        • 2019-06-11
        • 2014-09-20
        相关资源
        最近更新 更多