From 2903ccd887e1f9dc9503c2c7c46a7933e2394930 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Sat, 7 Jul 2018 09:15:58 +1000 Subject: build-jim-ext: Improvements when cross compiling, Tcl Detect when cross compiling (build != host) Tcl exec loses stderr if redirected and an error code is returned, so redo the approach to exec so that it works on both Tcl and Jim Signed-off-by: Steve Bennett --- auto.def | 7 +++ build-jim-ext.in | 132 ++++++++++++++++++++++++------------------------------- 2 files changed, 65 insertions(+), 74 deletions(-) diff --git a/auto.def b/auto.def index 81f70ea..248870d 100644 --- a/auto.def +++ b/auto.def @@ -456,6 +456,13 @@ if {[ext-get-status load] eq "n"} { define SH_LINKFLAGS "" } +# Are we cross compiling? +if {[get-define host] ne [get-define build]} { + define cross_compiling 1 +} else { + define cross_compiling 0 +} + msg-result "Jim static extensions: [lsort [concat $extinfo(static-tcl) $extinfo(static-c)]]" if {[llength $extinfo(module-tcl)]} { msg-result "Jim Tcl extensions: [lsort $extinfo(module-tcl)]" diff --git a/build-jim-ext.in b/build-jim-ext.in index 087ec23..ce9ddf6 100644 --- a/build-jim-ext.in +++ b/build-jim-ext.in @@ -5,25 +5,16 @@ set opts {} set sources {} proc usage {{msg {}}} { - puts stderr "Usage: build-jim-ext ?--notest? ?--install? ?--static? ?cc-options? ?-o modname? sources..." + puts stderr "Usage: build-jim-ext ?--notest? ?--cross? ?--install? ?--static? ?cc-options? ?-o modname? sources..." if {$msg ne ""} { puts stderr \n$msg } exit 1 } -proc readfile {filename {default_value ""}} { - set result $default_value - catch { - set f [open $filename] - set result [$f read -nonewline] - $f close - } - return $result -} - set linker "@CC@" set testmod 1 +set cross @cross_compiling@ set install 0 set static 0 set verbose 0 @@ -42,18 +33,26 @@ for {set i 0} {$i < [llength $argv]} {incr i} { set linker "@CXX@" } --notest { + # Don't test to see if the module can be loaded set testmod 0 } + --cross { + # Don't use standard include/lib paths if cross compiling + set cross 1 + } --install { + # Install to $DESTDIR/@prefix@/lib/jim set install 1 } --static { + # Build a static extension that can be linked set static 1 } --verbose { set verbose 1 } --keep { + # Don't remove intermediate files set keep 1 } --help { @@ -106,8 +105,39 @@ if {$static} { } puts "Building $target from $sources\n" -# Now add the standard location after any user include paths -lappend includepaths -I@prefix@/include +if {!$cross} { + # If not cross compiling, add the standard location after any user include paths + lappend includepaths -I@prefix@/include +} + +# Work around Tcl's strange behaviour of exec failing if stderr is produced +# +proc exec-catch {verbose cmdlist} { + if {$verbose} { + puts [join $cmdlist] + } + flush stdout + set rc [catch { + exec {*}$cmdlist + } msg errinfo] + + # Handle failed case. + # Note that Tcl returns rc=1 if there is any stderr, + # even if the exit code is 0 + if {$rc} { + if {[dict get $errinfo -errorcode] ne "NONE"} { + if {!$verbose} { + puts stderr [join $cmdlist] + } + puts stderr $msg + return 1 + } + } + if {$msg ne ""} { + puts stderr $msg + } + return 0 +} set CPPFLAGS "-D_GNU_SOURCE" @@ -137,31 +167,11 @@ foreach source $sources { set compile "$compiler @CFLAGS@ $CPPFLAGS $shobj_cflags $includepaths $opts -c -o $obj $source" puts "Compile: $obj" lappend objs $obj - flush stdout - set rc [catch { - if {$verbose} { - puts $compile - } - exec 2>jimerr.out {*}$compile - } msg] - - set errmsg [readfile jimerr.out] - file delete jimerr.out + set rc [exec-catch $verbose $compile] if {$rc} { - if {!$verbose} { - puts stderr $compile - } - puts stderr $msg - if {$errmsg ne ""} { - puts stderr $errmsg - } file delete {*}$objs - exit 1 - } else { - if {$errmsg ne ""} { - puts $errmsg - } + exit $rc } } @@ -170,65 +180,39 @@ if {$static} { set ranlib "@RANLIB@ $target" puts "Ar: $target" - set rc [catch { - file delete $target - exec {*}$ar - exec {*}$ranlib - if {$verbose} { - puts stderr $ar - } - } msg] - + set rc [exec-catch $verbose $ar] + if {rc == 0} { + set rc [exec-catch $verbose $ranlib] + } file delete {*}$objs - if {$rc} { - puts stderr $ar - puts stderr $ranlib - puts stderr $msg file delete $target - exit 1 + exit $rc } } else { - # Add the standard location after any user lib paths - lappend libpaths -L@prefix@/lib + if {!$cross} { + # If not cross compiling, add the standard location after any user lib paths + lappend libpaths -L@prefix@/lib + } set link "$linker @CFLAGS@ @LDFLAGS@ $shobj_ldflags $libpaths $opts -o $target $objs $ljim @LIBS@ $libs" puts "Link: $target" - set rc [catch { - if {$verbose} { - puts stderr $link - } - exec 2>jimerr.out {*}$link - } msg] - - set errmsg [readfile jimerr.out] - file delete jimerr.out - + set rc [exec-catch $verbose $link] if {!$keep} { file delete {*}$objs } - if {$rc} { file delete $target - puts stderr $link - puts stderr $msg - if {$errmsg ne ""} { - puts stderr $errmsg - } - exit 1 - } - if {$errmsg ne ""} { - puts $errmsg + exit $rc } - if {$testmod} { + if {$testmod && !$cross} { # Now, is testing even possible? # We must be running a compatible jimsh with the load command at least set testmod 0 set rc [catch { # This will avoid attempting on Tcl and on jimsh without load - # How to tell if we are cross compiling? if {[info version] > 0.73 && [exists -command load]} { set testmod 1 } @@ -236,7 +220,7 @@ if {$static} { } set rc [catch { - if {$testmod} { + if {$testmod && !$cross} { puts "Test: load $target" load ./$target } -- cgit v1.1