1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
###
# Ancestor-less class intended to be a mixin
# which defines a family of build related behaviors
# that are modified when targetting either gcc or msvc
###
::clay::define ::practcl::toolset {
###
# find or fake a key/value list describing this project
###
method config.sh {} {
return [my read_configuration]
}
# Compute the location where the product will be built
method BuildDir {PWD} {
set name [my define get name]
set debug [my define get debug 0]
if {[my <project> define get LOCAL 0]} {
return [my define get builddir [file join $PWD local $name]]
}
if {$debug} {
return [my define get builddir [file join $PWD debug $name]]
} else {
return [my define get builddir [file join $PWD pkg $name]]
}
}
# Return where the Makefile is located relative to [emph srcdir].
# For this implementation the MakeDir is always srcdir.
method MakeDir {srcdir} {
return $srcdir
}
# Read information about the build process for this package.
# For this implementation, data is sought in the following locations
# in the following order:
# config.tcl (generated by practcl.) PKGConfig.sh. The Makefile
# [para]
# If the Makefile needs to be consulted, but does not exist, the
# Configure method is invoked
method read_configuration {} {
my variable conf_result
if {[info exists conf_result]} {
return $conf_result
}
set result {}
set name [my define get name]
set PWD $::CWD
set builddir [my define get builddir]
my unpack
set srcdir [my define get srcdir]
if {![file exists $builddir]} {
my Configure
}
set filename [file join $builddir config.tcl]
# Project uses the practcl template. Use the leavings from autoconf
if {[file exists $filename]} {
set dat [::practcl::read_configuration $builddir]
foreach {item value} [::practcl::sort_dict $dat] {
dict set result $item $value
}
set conf_result $result
return $result
}
set filename [file join $builddir ${name}Config.sh]
if {[file exists $filename]} {
set l [expr {[string length $name]+1}]
foreach {field dat} [::practcl::read_Config.sh $filename] {
set field [string tolower $field]
if {[string match ${name}_* $field]} {
set field [string range $field $l end]
}
switch $field {
version {
dict set result pkg_vers $dat
}
lib_file {
set field libfile
}
}
dict set result $field $dat
}
set conf_result $result
return $result
}
###
# Oh man... we have to guess
###
if {![file exists [file join $builddir Makefile]]} {
my Configure
}
set filename [file join $builddir Makefile]
if {![file exists $filename]} {
error "Could not locate any configuration data in $srcdir"
}
foreach {field dat} [::practcl::read_Makefile $filename] {
dict set result $field $dat
}
if {![dict exists $result PRACTCL_PKG_LIBS] && [dict exists $result LIBS]} {
dict set result PRACTCL_PKG_LIBS [dict get $result LIBS]
}
set conf_result $result
cd $PWD
return $result
}
## method DEFS
# This method populates 4 variables:
# name - The name of the package
# version - The version of the package
# defs - C flags passed to the compiler
# includedir - A list of paths to feed to the compiler for finding headers
#
method build-cflags {PROJECT DEFS namevar versionvar defsvar} {
upvar 1 $namevar name $versionvar version NAME NAME $defsvar defs
set name [string tolower [${PROJECT} define get name [${PROJECT} define get pkg_name]]]
set NAME [string toupper $name]
set version [${PROJECT} define get version [${PROJECT} define get pkg_vers]]
if {$version eq {}} {
set version 0.1a
}
set defs $DEFS
foreach flag {
-DPACKAGE_NAME
-DPACKAGE_VERSION
-DPACKAGE_TARNAME
-DPACKAGE_STRING
} {
if {[set i [string first $flag $defs]] >= 0} {
set j [string first -D $flag [expr {$i+[string length $flag]}]]
set predef [string range $defs 0 [expr {$i-1}]]
set postdef [string range $defs $j end]
set defs "$predef $postdef"
}
}
append defs " -DPACKAGE_NAME=\"${name}\" -DPACKAGE_VERSION=\"${version}\""
append defs " -DPACKAGE_TARNAME=\"${name}\" -DPACKAGE_STRING=\"${name}\x5c\x20${version}\""
return $defs
}
# Invoke critcl in an external process
method critcl args {
if {![info exists critcl]} {
::practcl::LOCAL tool critcl env-load
set critcl [file join [::practcl::LOCAL tool critcl define get srcdir] main.tcl
}
set srcdir [my SourceRoot]
set PWD [pwd]
cd $srcdir
::practcl::dotclexec $critcl {*}$args
cd $PWD
}
}
oo::objdefine ::practcl::toolset {
# Perform the selection for the toolset mixin
method select object {
###
# Select the toolset to use for this project
###
if {[$object define exists toolset]} {
return [$object define get toolset]
}
set class [$object define get toolset]
if {$class ne {}} {
$object clay mixinmap toolset $class
} else {
if {[info exists ::env(VisualStudioVersion)]} {
$object clay mixinmap toolset ::practcl::toolset.msvc
} else {
$object clay mixinmap toolset ::practcl::toolset.gcc
}
}
}
}
|