RFC: Big Makefile patch for WARNS settings

Ulrich Spörlein uqs at spoerlein.net
Fri Oct 16 13:15:17 UTC 2009


On Mon, 12.10.2009 at 18:37:38 +0200, Dag-Erling Smørgrav wrote:
> Ulrich Spörlein <uqs at spoerlein.net> writes:
> > Is there some easy way to do cross-compiles (like make universe) in just
> > one of the subdirs? That would help tremendously.
> 
> % cd /usr/src
> % make toolchain TARGET=powerpc
> % make buildenv TARGET=powerpc
> %% cd usr.sbin/rwhod
> %% make
> 
> ('make buildenv' starts a subshell)

Excellent, I now smashed together the following expect script, which can
be used to compile a single subdir with these toolchains. It requires
that you build all toolchains once, upfront.

It's a total hack, but hey it works for me, example usage would be:

$ cd /usr/src
$ universe-build -t
(builds toolchain for all targets, needs to be done every once in a while)
$ universe-build games/grdc WARNS=6 sparc64 amd64 i386
(build grdc with WARNS=6 for 3 archs specified, using the buildenv
target above)

Pardon my weak tcl/expect-fu

Regards,
Uli
-------------- next part --------------
#!/usr/local/bin/expect

# Does the following for variable subdirs and a given set of target archs,
# exits upon first failure.

# % cd /usr/src
# % make toolchain TARGET=powerpc
# % make buildenv TARGET=powerpc
# %% cd usr.sbin/rwhod
# %% make

set timeout -1
set toolchain 0

proc usage {argv0}  {
  send_user "usage: $argv0 -t \[target1 target2 ...\]\n"
  send_user "       $argv0 subdir \[make-args\] \[target1 target2 ...\]\n"
  exit
}

while {[llength $argv]>0} {
  set flag [lindex $argv 0]
    switch -- $flag \
      "-t" {
        set toolchain 1
        set argv [lrange $argv 1 end]
	set argc [expr ($argc - 1)]
      } default {
        break
      }
}

if {$toolchain!=1} {
  if {$argc<1} {
    usage $argv0
    exit 1
  }
  set subdir [lindex $argv 0]
  set argv [lrange $argv 1 end]
  set argc [expr ($argc - 1)]
  # if something is present, use it as make args
  if {$argc>=1} {
    set margs [lindex $argv 0]
    set argv [lrange $argv 1 end]
    set argc [expr ($argc - 1)]
  } else {
    set margs {}
  }
}

# if there is still something, use it as target list,
# else default to everything
if {$argc>=1} {
  set targets [lrange $argv 0 end]
} else {
  set input [open "|make universe -V TARGETS" r]
  set targets [split [string trimright [read $input]] " "]
  close $input
}

if {$toolchain==1} {
  foreach target $targets {
    spawn /bin/sh
    expect "$ "
    send "env MAKEOBJDIRPREFIX=/usr/obj/$target make toolchain __MAKE_CONF=/dev/null TARGET=$target\n"
    expect "$ "
    send "exit \$?\n"
    expect eof
  }
  puts "\n"
  exit
}

foreach target $targets {
  spawn /bin/sh
  set sid($target) $spawn_id
  expect "$ "
  send "env MAKEOBJDIRPREFIX=/usr/obj/$target make buildenv __MAKE_CONF=/dev/null TARGET=$target\n"
  expect "$ "
  send "make -C $subdir clean; make -C $subdir $margs\n"
  expect "$ "
  # Stupid buildenv is doing sh || true, so we cannot propagate by doing exit $rc :(
  # grab echo output instead 
  send "echo rc=\$?\n"
  expect -re "echo rc=..\r"
  expect -re "rc=(.*)\n"
  # TODO: save rc per target, don't exit below but print rcs for all archs on exit
  set rc $expect_out(1,string)
  send "exit \$?\n"
  expect "$ "
  send "exit \$?\n"
  expect eof
  if {$rc!=0} {
    puts ""
    exit $rc
  }

  ## if we expect eof, the wait below will not return, wtf?
  ## XXX sid($target) wont work here??
  #catch {close -i $spawn_id}
  ## wait returns PID, TYPE, CODE, grab code
  #set rc [lindex [wait sid($target)] 3]
}


More information about the freebsd-hackers mailing list