# syntax error near unexpected token `&&' [SOLVED]

## brundage

I'm trying to build linux-4.14.61-gentoo, but it fails pretty early.  This is an update from 4.12.12-gentoo via make oldconfig.  What's going on here?

```
0 blaze:0.0 src/linux # make -j5 all modules 

  HOSTCC  scripts/kconfig/conf.o

  HOSTCC  scripts/kconfig/zconf.tab.o

  HOSTLD  scripts/kconfig/conf

scripts/kconfig/conf  --silentoldconfig Kconfig

  CHK     include/config/kernel.release

  CHK     include/generated/uapi/linux/version.h

  HOSTCXX -fPIC scripts/gcc-plugins/latent_entropy_plugin.o

  GENSEED scripts/gcc-plugins/randomize_layout_seed.h

  HOSTCXX -fPIC scripts/gcc-plugins/randomize_layout_plugin.o

  DESCEND  objtool

/bin/sh: -c: line 0: syntax error near unexpected token `&&'

/bin/sh: -c: line 0: `set -e;   &&  /usr/src/linux-4.14.61-gentoo/tools/objtool//fixdep /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.d /usr/src/linux-4.14.61-gentoo/tools/objtool/exec-cmd.o '' > /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.tmp; rm -f /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.d; mv -f /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.tmp /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.cmd'

make[4]: *** [/usr/src/linux-4.14.61-gentoo/tools/build/Makefile.build:97: /usr/src/linux-4.14.61-gentoo/tools/objtool/exec-cmd.o] Error 1

make[3]: *** [Makefile:52: /usr/src/linux-4.14.61-gentoo/tools/objtool/libsubcmd-in.o] Error 2

make[2]: *** [Makefile:54: /usr/src/linux-4.14.61-gentoo/tools/objtool/libsubcmd.a] Error 2

make[1]: *** [Makefile:62: objtool] Error 2

make: *** [Makefile:1648: tools/objtool] Error 2

make: *** Waiting for unfinished jobs....

  HOSTLLD -shared scripts/gcc-plugins/latent_entropy_plugin.so

  HOSTLLD -shared scripts/gcc-plugins/randomize_layout_plugin.so

```

Last edited by brundage on Tue Aug 21, 2018 5:47 pm; edited 1 time in total

----------

## Hu

It looks like some expansion that was supposed to become a command instead expanded to the empty string, causing && to be the first non-empty token in that subexpression.  It is not legal as an initial token, hence the shell error.  Do you have any unusual environment variables set?  Why are you building the kernel as root?  If you can find the specific Makefile and line responsible for that recipe, you should be able to identify what variable expanded to an empty string.

----------

## brundage

 *Hu wrote:*   

> It looks like some expansion that was supposed to become a command instead expanded to the empty string, causing && to be the first non-empty token in that subexpression.  It is not legal as an initial token, hence the shell error.  Do you have any unusual environment variables set?  Why are you building the kernel as root?  If you can find the specific Makefile and line responsible for that recipe, you should be able to identify what variable expanded to an empty string.

 

Yep. Been strace'ing around and found the Makefile

/usr/src/linux-4.14.61-gentoo/tools/build/Makefile.build

```
[pid 30488] execve("/bin/sh", ["/bin/sh", "-c", "set -e;   &&  /usr/src/linux-4.14.61-gentoo/tools/objtool//fixdep /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.d /usr/src/linux-4.14.61-gentoo/tools/objtool/exec-cmd.o '' > /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.tmp; rm -f /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.d; mv -f /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.tmp /usr/src/linux-4.14.61-gentoo/tools/objtool/.exec-cmd.o.cmd"], 0x55d81c22aad0 /* 155 vars */ <unfinished ...>
```

Here's the file:

```
# SPDX-License-Identifier: GPL-2.0

###

# Main build makefile.

#

#  Lots of this code have been borrowed or heavily inspired from parts

#  of kbuild code, which is not credited, but mostly developed by:

#

#  Copyright (C) Sam Ravnborg <sam@mars.ravnborg.org>, 2015

#  Copyright (C) Linus Torvalds <torvalds@linux-foundation.org>, 2015

#

PHONY := __build

__build:

ifeq ($(V),1)

  quiet =

  Q =

else

  quiet=quiet_

  Q=@

endif

ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)

  quiet=silent_

endif

build-dir := $(srctree)/tools/build

# Define $(fixdep) for dep-cmd function

ifeq ($(OUTPUT),)

  fixdep := $(build-dir)/fixdep

else

  fixdep := $(OUTPUT)/fixdep

endif

# Generic definitions

include $(build-dir)/Build.include

# do not force detected configuration

-include $(OUTPUT).config-detected

# Init all relevant variables used in build files so

# 1) they have correct type

# 2) they do not inherit any value from the environment

subdir-y     :=

obj-y        :=

subdir-y     :=

subdir-obj-y :=

# Build definitions

build-file := $(dir)/Build

-include $(build-file)

quiet_cmd_flex  = FLEX     $@

quiet_cmd_bison = BISON    $@

# Create directory unless it exists

quiet_cmd_mkdir = MKDIR    $(dir $@)

      cmd_mkdir = mkdir -p $(dir $@)

     rule_mkdir = $(if $(wildcard $(dir $@)),,@$(call echo-cmd,mkdir) $(cmd_mkdir))

# Compile command

quiet_cmd_cc_o_c = CC       $@

      cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<

quiet_cmd_host_cc_o_c = HOSTCC   $@

      cmd_host_cc_o_c = $(HOSTCC) $(host_c_flags) -c -o $@ $<

quiet_cmd_cxx_o_c = CXX      $@

      cmd_cxx_o_c = $(CXX) $(cxx_flags) -c -o $@ $<

quiet_cmd_cpp_i_c = CPP      $@

      cmd_cpp_i_c = $(CC) $(c_flags) -E -o $@ $<

quiet_cmd_cc_s_c = AS       $@

      cmd_cc_s_c = $(CC) $(c_flags) -S -o $@ $<

quiet_cmd_gen = GEN      $@

# Link agregate command

# If there's nothing to link, create empty $@ object.

quiet_cmd_ld_multi = LD       $@

      cmd_ld_multi = $(if $(strip $(obj-y)),\

                     $(LD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@)

quiet_cmd_host_ld_multi = HOSTLD   $@

      cmd_host_ld_multi = $(if $(strip $(obj-y)),\

                          $(HOSTLD) -r -o $@  $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@)

ifneq ($(filter $(obj),$(hostprogs)),)

  host = host_

endif

# Build rules

$(OUTPUT)%.o: %.c FORCE

   $(call rule_mkdir)

   $(call if_changed_dep,$(host)cc_o_c)

$(OUTPUT)%.o: %.cpp FORCE

   $(call rule_mkdir)

   $(call if_changed_dep,cxx_o_c)

$(OUTPUT)%.o: %.S FORCE

   $(call rule_mkdir)

   $(call if_changed_dep,$(host)cc_o_c)

$(OUTPUT)%.i: %.c FORCE

   $(call rule_mkdir)

   $(call if_changed_dep,cpp_i_c)

$(OUTPUT)%.s: %.S FORCE

   $(call rule_mkdir)

   $(call if_changed_dep,cpp_i_c)

$(OUTPUT)%.s: %.c FORCE

   $(call rule_mkdir)

   $(call if_changed_dep,cc_s_c)

# Gather build data:

#   obj-y        - list of build objects

#   subdir-y     - list of directories to nest

#   subdir-obj-y - list of directories objects 'dir/$(obj)-in.o'

obj-y        := $($(obj)-y)

subdir-y     := $(patsubst %/,%,$(filter %/, $(obj-y)))

obj-y        := $(patsubst %/, %/$(obj)-in.o, $(obj-y))

subdir-obj-y := $(filter %/$(obj)-in.o, $(obj-y))

# '$(OUTPUT)/dir' prefix to all objects

objprefix    := $(subst ./,,$(OUTPUT)$(dir)/)

obj-y        := $(addprefix $(objprefix),$(obj-y))

subdir-obj-y := $(addprefix $(objprefix),$(subdir-obj-y))

# Final '$(obj)-in.o' object

in-target := $(objprefix)$(obj)-in.o

PHONY += $(subdir-y)

$(subdir-y):

   $(Q)$(MAKE) -f $(build-dir)/Makefile.build dir=$(dir)/$@ obj=$(obj)

$(sort $(subdir-obj-y)): $(subdir-y) ;

$(in-target): $(obj-y) FORCE

   $(call rule_mkdir)

   $(call if_changed,$(host)ld_multi)

__build: $(in-target)

   @:

PHONY += FORCE

FORCE:

# Include all cmd files to get all the dependency rules

# for all objects included

targets   := $(wildcard $(sort $(obj-y) $(in-target) $(MAKECMDGOALS)))

cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))

ifneq ($(cmd_files),)

  include $(cmd_files)

endif

.PHONY: $(PHONY)

```

----------

## brundage

Been doing a little more digging and the only file that uses '&&' is Build.include

```
 71 ###

 72 # if_changed_dep  - execute command if any prerequisite is newer than

 73 #                   target, or command line has changed and update

 74 #                   dependencies in the cmd file

 75 if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)),         \

 76                   @set -e;                                         \

 77                   $(echo-cmd) $(cmd_$(1)) && $(dep-cmd))

```

So, looking for if_changed_dep I get a few results

```
0 blaze:0.0 tools/build # egrep -rn if_changed_dep .

./Build.include:72:# if_changed_dep  - execute command if any prerequisite is newer than

./Build.include:75:if_changed_dep = $(if $(strip $(any-prereq) $(arg-check)),         \

./Makefile.build:97:   $(call if_changed_dep,$(host)cc_o_c)

./Makefile.build:101:   $(call if_changed_dep,cxx_o_c)

./Makefile.build:105:   $(call if_changed_dep,$(host)cc_o_c)

./Makefile.build:109:   $(call if_changed_dep,cpp_i_c)

./Makefile.build:113:   $(call if_changed_dep,cpp_i_c)

./Makefile.build:117:   $(call if_changed_dep,cc_s_c)

```

----------

## mv

This seems to be the correct location. Do you perhaps have a variable "quiet" or "cmd_...." in your environment?

You might try to precede the make-command with env -i (though this might be too aggressive).

----------

## brundage

 *mv wrote:*   

> This seems to be the correct location. Do you perhaps have a variable "quiet" or "cmd_...." in your environment?
> 
> You might try to precede the make-command with env -i (though this might be too aggressive).

 

No "quiet" or "cmd_" in my environment. However, building with env -i solved the problem.

```
0 blaze:0.0 /root # env|sort

ANT_HOME=/usr/share/ant

COLORTERM=truecolor

CONFIG_PROTECT=/usr/share/gnupg/qualified.txt

CONFIG_PROTECT_MASK=/etc/sandbox.d /etc/fonts/fonts.conf /etc/gentoo-release /etc/gconf /etc/terminfo /etc/dconf /etc/ca-certificates.conf /etc/revdep-rebuild

DISPLAY=:0.0

EDITOR=vim

GCC_SPECS=

GSETTINGS_BACKEND=dconf

HISTDIR=/root/.histdir

HISTFILE=/root/.histdir/4346

HISTSIZE=1000

HOME=/root

INFOPATH=/usr/share/gcc-data/x86_64-pc-linux-gnu/7.3.0/info:/usr/share/binutils-data/x86_64-pc-linux-gnu/2.30/info:/usr/share/info

JAVAC=/etc/java-config-2/current-system-vm/bin/javac

JAVA_HOME=/etc/java-config-2/current-system-vm

JDK_HOME=/etc/java-config-2/current-system-vm

LANG=C

LESS=-XmsR -Pm ?f%f:stdio. ?lbLine ?lb%lb ?pb(?pb%pb\% of ?pb%B bytes)

LESSOPEN=|lesspipe %s

LOGNAME=root

MAILHOST=blaze

MAILNAME=remus root

MAILUSER=root

MANPAGER=manpager

MANPATH=/root/man:/usr/share/man

OLDPWD=/root

OPENCL_PROFILE=nvidia

OPENGL_PROFILE=nvidia

PAGER=less

PATH=/root/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/opt/bin

PGPPATH=/root/.pgp

PRELINK_PATH_MASK=/opt/eagle

PS1=%? %{%}%B%m:0.0%b%{%} %2C %# 

PWD=/root

QT_GRAPHICSSYSTEM=raster

SAVEHIST=1000

SHELL=/bin/zsh

SHLVL=1

TEMP=/root/tmp

TERM=xterm-256color

TMP=/root/tmp

TMPDIR=/root/tmp

USER=root

XDG_CONFIG_DIRS=/etc/xdg

XDG_DATA_DIRS=/usr/local/share:/usr/share

_=/bin/env

host=blaze

```

----------

## mv

There is nothing which looks suspicious except "host" and TEMP. TMP, TMPDIR (BTW, according to POSIX only the latter should be honored):

The problem with TMPDIR=/root/tmp is that processes with dropped privileges do not have access to it.

----------

## brundage

 *mv wrote:*   

> There is nothing which looks suspicious except "host" and TEMP. TMP, TMPDIR (BTW, according to POSIX only the latter should be honored):
> 
> The problem with TMPDIR=/root/tmp is that processes with dropped privileges do not have access to it.

 

The answer was $host.  That's a little cruft from my old sys admin days so I guess it's time to drop that.

Thanks for the help.

----------

