Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
355 views
in Technique[技术] by (71.8m points)

gnu - Autotools cross compilation and generated sources

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.

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.

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".

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:

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_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;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...