linuxmakefilegnu-makegnu-toolchain

(make) Recipes breaks after definding PATH


I am trying to automate the building of my toolchain, however every time I set my PATH using a recipe, it breaks the future recipes to ignore the prefix of @ and passes all commands after that directory from shell.

Here is one of my constructs:

%-build-glibc:
    @echo "Building glibc"
    @mkdir -p $(DIR_BUILD)/glibc
    @export PATH=$(PATH):$(DIR_INSTALL)/bin && \
    @cd $(DIR_BUILD)/glibc && \
    $(call cmd,$(DIR_BUILD)/glibc-$(VER_GLIBC)/configure \
      --host=$(TARGET_MACH) \
      --prefix=/usr \
      --libdir=/usr/lib \
      --with-headers=$(DIR_SYSROOT)/usr/include \
      --enable-bind-now \
      --enable-kernel=$(VER_LINUX) \
      --enable-stack-protector=strong \
      --disable-profile \
      --disable-werror \
      libc_cv_c_cleanup=yes \
      libc_cv_ctors_header=yes \
      libc_cv_forced_unwind=yes \
      libc_cv_slibdir=/lib \
      CFLAGS="-O2") && \
    $(call cmd,make -k install-headers cross_compiling=yes install_root=$(DIR_SYSROOT)) && \
    $(call cmd,make -j8) && \
    $(call cmd,make install install_root=$(DIR_SYSROOT))

And here is the output:

Building glibc

/bin/sh: 2: @cd: not found

make: *** [Rules.mk:166: aarch64-build-glibc] Error 1

I've tried echoing the result of PATH to see if it somehow just broke PATH itself, however once I get to that stage itself its like the whole shell doesn't work.


Solution

  • The use of @ to suppress command echoing is an aspect of make syntax that operates on a per-logical-line basis. It is not a shell feature, and make does not attribute special significance to @ other than at the beginning of a logical line.

    I interpret the question as saying that you inserted

        @export PATH=$(PATH):$(DIR_INSTALL)/bin && \
    

    before the following physical line:

        @cd $(DIR_BUILD)/glibc && \
    

    . But that backslash (\) at the end is a line-continuation marker, indicating that the next physical line is part of the same logical line. You need that in this case. But it means that the cd does not appear at the start of a logical line, so make does nothing with the @ preceding it. As a result, the shell is trying to execute a command named @cd, which does not exist.

    Note how none of the physical lines following the cd have @ prefixes. Since the cd no longer appears at the beginning of a logical line, you want it to be like all the subsequent lines, without an @:

    %-build-glibc:
        @echo "Building glibc"
        @mkdir -p $(DIR_BUILD)/glibc
        @export PATH=$(PATH):$(DIR_INSTALL)/bin && \
          cd $(DIR_BUILD)/glibc && \
          $(call cmd,$(DIR_BUILD)/glibc-$(VER_GLIBC)/configure \
          ...