为什么这个makefile只适用于单个作业?

时间:2017-01-28 18:48:15

标签: multithreading makefile download cross-compiling

我试图编写一个编译交叉编译器的Makefile。 它会下载GCCbinutils,提取存档,运行configure脚本并运行make。

这是我写的Makefile

# Versions
GCC_VERSION := 6.3.0
BINUTILS_VERSION := 2.27

# Build
TARGET ?= i686-elf
PREFIX := $(realpath build)

# Phony tasks
.PHONY: all clean gcc binutils

# Targets
BINUTILS_TARGETS := build/bin/${TARGET}-addr2line build/bin/${TARGET}-ar \
    build/bin/${TARGET}-as build/bin/${TARGET}-c++filt \
    build/bin/${TARGET}-elfedit build/bin/${TARGET}-gprof \
    build/bin/${TARGET}-ld build/bin/${TARGET}-ld.bfd build/bin/${TARGET}-nm \
    build/bin/${TARGET}-objcopy build/bin/${TARGET}-objdump \
    build/bin/${TARGET}-ranlib build/bin/${TARGET}-readelf \
    build/bin/${TARGET}-size build/bin/${TARGET}-strings \
    build/bin/${TARGET}-strip
GCC_TARGETS := build/bin/${TARGET}-cpp build/bin/${TARGET}-gcc \
    build/bin/${TARGET}-gcc-${GCC_VERSION} build/bin/${TARGET}-gcc-ar \
    build/bin/${TARGET}-gcc-nm build/bin/${TARGET}-gcc-ranlib \
    build/bin/${TARGET}-gcov build/bin/${TARGET}-gcov-tool

# Aliases
all: binutils gcc
gcc: ${GCC_TARGETS}
binutils: ${BINUTILS_TARGETS}

# Download the packages
packages/gcc-${GCC_VERSION}.tar.bz2:
    curl ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.bz2 \
        -o $@
packages/binutils-${BINUTILS_VERSION}.tar.bz2:
    curl ftp://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2 \
        -o $@

# Extract them
packages/gcc-${GCC_VERSION}/configure: packages/gcc-${GCC_VERSION}.tar.bz2
    tar -xmjf $< -C packages
packages/binutils-${BINUTILS_VERSION}/configure: packages/binutils-${BINUTILS_VERSION}.tar.bz2
    tar -xmjf $< -C packages

# Build them
${GCC_TARGETS}: packages/gcc-${GCC_VERSION}/configure
    mkdir -p build/gcc
    cd build/gcc && ../../packages/gcc-${GCC_VERSION}/configure \
        --target=${TARGET} --prefix=${PREFIX} --disable-nls \
        --enable-languages=c --without-headers && make all-gcc && \
        make all-target-libgcc && make install-gcc && make install-target-libgcc
${BINUTILS_TARGETS}: packages/binutils-${BINUTILS_VERSION}/configure
    mkdir -p build/binutils
    cd build/binutils && ../../packages/binutils-${BINUTILS_VERSION}/configure \
        --target=${TARGET} --prefix=${PREFIX} --with-sysroot --disable-nls \
        --disable-werror && make && make install

# Clean everything
clean:
    rm -rf build/*
    rm -rf packages/*

在没有选项的情况下运行make时有效,但是当我使用jobs选项时,它会失败(但不是每次都失败):它会并行下载binutilsGCC

当binutils完全下载后,它会将其解压缩并编译,然后GCC下载结束,但它没有做任何事情并且没有错误。

有时候GCCbinutils的编辑会因奇怪的错误而失败(我会用其中一些编辑这篇文章)。

2 个答案:

答案 0 :(得分:0)

不确定特定构建失败的确切来源,但Makefile存在问题:2构建规则有多个目标。 Make不支持此功能,请参阅here以获取解释。

答案 1 :(得分:0)

使用作业失败,因为它启动了相同配方的多个实例,但这些实例无法正确运行。

${GCC_TARGETS}: packages/gcc-${GCC_VERSION}/configure
    mkdir -p build/gcc
    cd build/gcc && ../../packages/gcc-${GCC_VERSION}/configure ... make ...

我猜这是麻烦制造者,因为Make with jobs会在同一目录中启动多个配置调用以异步运行。因此,您运行多个配置脚本并将位添加到同一目录。然后在同一个构建目录中调用Make的多个实例。完美的混乱。

类似的东西:

${GCC_TARGETS}: packages/gcc-${GCC_VERSION}/configure
    mkdir -p build/gcc/$(nodir $@) && cd build/gcc/$(nodir $@) ...

应该通过启动configure&amp; amp;来解决问题。在不同的目录中制作序列。你也需要类似的$ {BINUTILS_TARGETS}修复。