riscv-openocd-wch/jimtcl/build-jim-ext.in

240 lines
4.7 KiB
Plaintext

#!/usr/bin/env jimsh
# Separate command line arguments into options and source files
set opts {}
set sources {}
proc usage {{msg {}}} {
puts stderr "Usage: build-jim-ext ?--notest? ?--cross? ?--install? ?--static? ?cc-options? ?-o modname? sources..."
if {$msg ne ""} {
puts stderr \n$msg
}
exit 1
}
set linker "@CC@"
set testmod 1
set cross @cross_compiling@
set install 0
set static 0
set verbose 0
set keep 0
set includepaths {}
set libpaths {}
set libs {}
for {set i 0} {$i < [llength $argv]} {incr i} {
set arg [lindex $argv $i]
switch -glob -- $arg {
*.c {
lappend sources $arg
}
*.cpp {
lappend sources $arg
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 {
usage "Easily builds dynamic (loadable) modules for jim"
}
-o {
incr i
set modname [file rootname [lindex $argv $i]]
if {$modname eq ""} {
usage "Option -o requires an argument"
}
}
-I* {
lappend includepaths $arg
if {$arg eq "-I"} {
lappend includepaths [lindex $argv $i]
}
}
-L* {
lappend libpaths $arg
if {$arg eq "-L"} {
lappend libpaths [lindex $argv $i]
}
}
-l* {
lappend libs $arg
}
-* {
lappend opts $arg
}
default {
usage "Unexpected '$arg'"
}
}
}
if {$sources eq ""} {
usage "No sources provided"
}
if {![info exists modname]} {
set modname [file rootname [file tail [lindex $sources 0]]]
# Remove jim- prefix if one exists
regsub "^jim-" $modname "" modname
}
if {$static} {
set target libjim-$modname.a
} else {
set target $modname.so
}
puts "Building $target from $sources\n"
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"
set ljim ""
set shobj_cflags ""
set shobj_ldflags ""
if {!$static} {
set shobj_cflags "@SHOBJ_CFLAGS@"
if {"@JIM_STATICLIB@" eq "1"} {
puts stderr "Warning: libjim is static. Dynamic module may not work on some platforms.\n"
set shobj_ldflags "@SHOBJ_LDFLAGS@"
} else {
# If shared, link against the shared libjim to resolve symbols
set ljim -ljim
set shobj_ldflags "@SHOBJ_LDFLAGS_R@"
}
}
set objs {}
foreach source $sources {
set obj [file rootname [file tail $source]].o
if {[string match *.c $source]} {
set compiler "@CC@"
} else {
set compiler "@CXX@"
}
set compile "$compiler @CFLAGS@ $CPPFLAGS $shobj_cflags $includepaths $opts -c -o $obj $source"
puts "Compile: $obj"
lappend objs $obj
set rc [exec-catch $verbose $compile]
if {$rc} {
file delete {*}$objs
exit $rc
}
}
if {$static} {
set ar "@AR@ cq $target $objs"
set ranlib "@RANLIB@ $target"
puts "Ar: $target"
set rc [exec-catch $verbose $ar]
if {rc == 0} {
set rc [exec-catch $verbose $ranlib]
}
file delete {*}$objs
if {$rc} {
file delete $target
exit $rc
}
} else {
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 [exec-catch $verbose $link]
if {!$keep} {
file delete {*}$objs
}
if {$rc} {
file delete $target
exit $rc
}
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
if {[info version] > 0.73 && [exists -command load]} {
set testmod 1
}
} msg]
}
set rc [catch {
if {$testmod && !$cross} {
puts "Test: load $target"
load ./$target
}
if {$install} {
set dest [env DESTDIR ""]@prefix@/lib/jim
puts "Install: $target => $dest"
file mkdir $dest
file copy $target $dest/$target
}
puts "\nSuccess!"
} msg]
if {$rc} {
puts stderr $msg
exit 1
}
}