Mercurial > flash_v2
annotate packages/pkgconf.tcl @ 64:c38311975d4f ecos-sw-2000-01-28
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
| author | jlarmour |
|---|---|
| date | Fri, 28 Jan 2000 04:59:39 +0000 |
| parents | 797268ecc331 |
| children | bf00f99aec69 |
| rev | line source |
|---|---|
| 0 | 1 # {{{ Banner |
| 2 | |
| 3 #=============================================================================== | |
| 4 # | |
| 5 # pkgconf.tcl | |
| 6 # | |
| 7 # A temporary build system for target-side software. | |
| 8 # | |
| 9 #=============================================================================== | |
| 10 #####COPYRIGHTBEGIN#### | |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
11 # |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
12 # ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
13 # The contents of this file are subject to the Red Hat eCos Public License |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
14 # Version 1.0 (the "License"); you may not use this file except in |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
15 # compliance with the License. You may obtain a copy of the License at |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
16 # http://sourceware.cygnus.com/ecos |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
17 # |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
18 # Software distributed under the License is distributed on an |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
19 # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
20 # License for the specific language governing rights and limitations under |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
21 # the License. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
22 # |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
23 # The Original Code is eCos - Embedded Configurable Operating System, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
24 # released September 30, 1998. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
25 # |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
26 # The Initial Developer of the Original Code is Red Hat. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
27 # Portions created by Red Hat are |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
28 # Copyright (C) 1998, 1999, 2000 Red Hat, Inc. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
29 # All Rights Reserved. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
30 # ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
46
diff
changeset
|
31 # |
| 0 | 32 #####COPYRIGHTEND#### |
| 33 #=============================================================================== | |
| 34 ######DESCRIPTIONBEGIN#### | |
| 35 # | |
| 36 # Author(s): bartv | |
| 37 # Contributors: bartv | |
| 38 # Date: 1998-04-10 | |
| 39 # Purpose: To generate a build tree (aka a configuration directory) | |
| 40 # and fill in basic configurability information. | |
| 41 # Description: | |
| 42 # Usage: | |
| 43 # | |
| 44 #####DESCRIPTIONEND#### | |
| 45 #=============================================================================== | |
| 46 # | |
| 47 | |
| 48 # }}} | |
| 49 | |
| 50 # {{{ Version check | |
| 51 | |
| 52 # ---------------------------------------------------------------------------- | |
| 53 # pkgconf.tcl requires at least version 8.0 of Tcl, since it makes use of | |
| 54 # namespaces. It is possible that some users still have older versions. | |
| 55 | |
| 56 if { [info tclversion] < 8.0 } { | |
| 57 puts "You are running Tcl version [info tclversion], patchlevel [info patchlevel]" | |
| 58 puts "The pkgconf.tcl script requires version 8.0 or later." | |
| 59 puts "Tcl is open source software and can be readily obtained via the internet." | |
| 60 puts "Good starting places for more information include www.tclconsortium.org" | |
| 61 puts "and www.scriptics.com" | |
| 62 exit 0 | |
| 63 } | |
| 64 | |
| 65 # }}} | |
| 66 # {{{ Namespace definition | |
| 67 | |
| 68 # ---------------------------------------------------------------------------- | |
| 69 # Namespaces. All code and variables in this script are kept in the namespace | |
| 70 # "pkgconf". This is not really necessary for stand-alone operation, but if it | |
| 71 # ever becomes desirable to embed this script in a larger application then | |
| 72 # using a namespace is a lot easier. | |
| 73 # | |
| 74 # As a fringe benefit, all global variables can be declared inside this | |
| 75 # namespace and initialised. | |
| 76 # | |
| 77 | |
| 78 namespace eval pkgconf { | |
| 79 | |
| 80 # Is this program running on a real operating system or under Windows ? | |
| 81 variable windows_host [expr {$tcl_platform(platform) == "windows"}] | |
| 82 | |
| 83 # Is this script running in command-line or GUI mode ? This is determined | |
| 84 # in large part by the command used to invoke the script. | |
| 85 variable gui_mode 0 | |
| 86 | |
| 87 # Keep track of whether or not GUI mode is possible at all. If | |
| 88 # TK is not loaded into the current interpreter then only | |
| 89 # command-line operation is possible. | |
| 90 variable gui_possible 0 | |
| 91 | |
| 92 # Where is the component repository ? The following input sources | |
| 93 # are available: | |
| 94 # 1) the command line argument --srcdir. This requires | |
| 95 # the arguments to be parsed early on. | |
| 96 # 2) the environment variable PKGCONF_COMPONENT_REPOSITORY. | |
| 97 # 3) $argv0 should correspond to the location of the pkgconf.tcl | |
| 98 # script. | |
| 99 # | |
| 100 variable component_repository "" | |
| 101 if { [info exists ::env(PKGCONF_COMPONENT_REPOSITORY)] } { | |
| 102 set component_repository $::env(PKGCONF_COMPONENT_REPOSITORY) | |
| 103 } else { | |
| 104 # Care has to be taken not to end up with a spurious /. at the end, | |
| 105 # since that would confuse later checks of component_repository != build_tree | |
| 106 set component_repository [pwd] | |
| 107 if { [file dirname $argv0] != "." } { | |
| 108 set component_repository [file join $component_repository [file dirname $argv0]] | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 # Where is the build tree ? This can be specified using the command | |
| 113 # line argument --builddir, the environment variable PKGCONF_BUILD_TREE, | |
| 114 # or it defaults to the current directory (in accordance with the | |
| 115 # normal behaviour of configure scripts). | |
| 116 variable build_tree "" | |
| 117 if { [info exists ::env(PKGCONF_BUILD_TREE)] } { | |
| 118 set build_tree $::env(PKGCONF_BUILD_TREE) | |
| 119 } else { | |
| 120 set build_tree [pwd] | |
| 121 } | |
| 122 | |
| 123 # Details of the command line arguments, if any. | |
| 124 variable list_targets_arg 0; # --targets | |
| 125 variable list_packages_arg 0; # --packages | |
| 126 variable list_pkgdata_arg 0; # --pkgdata | |
| 127 variable list_flags_arg 0; # --flags | |
| 128 variable no_windows_arg 0; # --nw | |
| 129 variable target_arg ""; # --target=abc | |
| 130 variable platform_arg ""; # --platform=sim | |
| 131 variable startup_arg ""; # --platform=rom | |
| 132 variable prefix_arg ""; # --prefix=/tmp/install | |
| 133 variable disable_args ""; # --disable-uitron | |
| 134 # This is a list of all disabled packages. | |
| 135 variable enable_args ""; # --enable-uitron, as above. | |
| 136 array set version_args {}; # --kernel_version=v0.3 | |
| 137 # This is an array indexed by package name. | |
| 138 array set cflags_args {}; # DBGFLAGS="-Wall -Werror" | |
| 139 # This is an array indexed by flag name. | |
| 140 variable force_arg 0; # Forcibly overwrite configuration files. | |
| 141 variable defaults_arg 0; # Do not use the values from the save file. | |
| 142 variable use_links_arg 0; # Make use of symbolic links. | |
| 143 variable use_copies_arg 0; # The inverse. | |
| 2 | 144 variable debug_arg 0; # --debug, control infrastructure options |
| 145 variable nodebug_arg 0; # --nodebug, ditto | |
| 0 | 146 |
| 147 # Details of all known packages. These come out of the packages file. | |
| 148 # The variable known_packages is a simple list, and the rest of the | |
| 149 # data is held in an array package_data(). | |
| 150 variable known_packages "" | |
| 151 array set package_data {}; | |
| 152 | |
| 153 # Details of all known targets, as supplied by the targets file. | |
| 154 # The variable known_targets is a simple list, and the rest of the | |
| 155 # data is held in an array target_data. | |
| 156 variable known_targets "" | |
| 157 array set target_data {}; | |
| 158 | |
| 159 # Details of all the compiler flags that can be used within the | |
| 160 # build system. | |
| 161 variable known_compiler_flags { | |
| 162 ARCHFLAGS CARCHFLAGS CXXARCHFLAGS LDARCHFLAGS | |
| 163 ERRFLAGS CERRFLAGS CXXERRFLAGS LDERRFLAGS | |
| 164 LANGFLAGS CLANGFLAGS CXXLANGFLAGS LDLANGFLAGS | |
| 165 DBGFLAGS CDBGFLAGS CXXDBGFLAGS LDDBGFLAGS | |
| 166 EXTRAFLAGS CEXTRAFLAGS CXXEXTRAFLAGS LDEXTRAFLAGS | |
| 167 } | |
| 168 | |
| 169 # Details of the current configuration values. It is convenient | |
| 170 # to store these in an array as well. The array gets filled in by | |
| 171 # pkgconf::setup_defaults | |
| 172 array set config_data {}; | |
| 173 | |
| 174 # Contents of the current save file, if any. | |
| 175 array set saved_data {}; | |
| 176 | |
| 177 # These variables are used by the code that creates the build tree | |
| 178 variable inc_dirs; # For each package with exported header | |
| 179 # files, the path to those header files | |
| 180 # relative to either the component repository | |
| 181 # or the build tree. | |
| 2 | 182 variable misc_dirs; # Ditto for package misc directories. |
| 0 | 183 variable tests_dirs; # Ditto for package tests directories. |
| 184 variable src_dirs; # Ditto for src directories. | |
| 185 | |
| 186 variable install_inc_dirs; # Names of all the directories that should | |
| 187 # exist below install/include, including pkgconf. | |
| 188 variable install_inc_files; # Ditto for all the files, but excluding | |
| 189 # ones in pkgconf. | |
| 190 variable pkgconf_files; # Names of all the configuration headers | |
| 191 variable install_test_dirs; # What directories should be created in install/tests | |
| 192 | |
| 193 # What routines should be invoked for outputting fatal errors and | |
| 194 # for warning messages ? | |
| 195 variable fatal_error_handler pkgconf::cli_fatal_error | |
| 196 variable warning_handler pkgconf::cli_warning | |
| 197 variable report_handler pkgconf::cli_report | |
| 198 } | |
| 199 | |
| 200 # }}} | |
| 201 # {{{ Infrastructure | |
| 202 | |
| 203 # ---------------------------------------------------------------------------- | |
| 204 # Minimal infrastructure support. | |
| 205 # | |
| 206 # There must be some way of reporting fatal errors, of outputting warnings, | |
| 207 # and of generating report messages. The implementation of these things | |
| 208 # obviously depends on whether or not TK is present. In addition, if this | |
| 209 # script is being run inside a larger application then that larger | |
| 210 # application must be able to install its own versions of the routines. | |
| 211 # | |
| 212 # Once it is possible to report fatal errors, an assertion facility becomes | |
| 213 # feasible. | |
| 214 # | |
| 215 | |
| 216 # | |
| 217 # These routines output fatal errors, warnings or miscellaneous messages. | |
| 218 # Their implementations depend on the mode in which this script is operating. | |
| 219 # | |
| 220 proc pkgconf::fatal_error { msg } { | |
| 221 $pkgconf::fatal_error_handler "$msg" | |
| 222 } | |
| 223 | |
| 224 proc pkgconf::warning { msg } { | |
| 225 $pkgconf::warning_handler "$msg" | |
| 226 } | |
| 227 | |
| 228 proc pkgconf::report { msg } { | |
| 229 $pkgconf::report_handler "$msg" | |
| 230 } | |
| 231 | |
| 232 # | |
| 233 # Command line versions. | |
| 234 # NOTE: some formatting so that there are linebreaks at ~72 columns would be | |
| 235 # a good idea. | |
| 236 # | |
| 237 proc pkgconf::cli_fatal_error_handler { msg } { | |
| 238 puts "pkgconf fatal error: $msg" | |
| 239 exit 1 | |
| 240 } | |
| 241 | |
| 242 proc pkgconf::cli_warning_handler { msg } { | |
| 243 puts "pkgconf warning: $msg" | |
| 244 } | |
| 245 | |
| 246 proc pkgconf::cli_report_handler { msg } { | |
| 247 puts "$msg" | |
| 248 } | |
| 249 | |
| 250 # | |
| 251 # Determine the default destination for warnings and for fatal errors. | |
| 252 # In GUI mode message boxes should be used, otherwise the text should just | |
| 253 # go to stdout (stderr is more dubious). | |
| 254 # | |
| 255 # This routine gets invoked before any command line arguments have | |
| 256 # been processed, to set up a sensible default. It gets invoked again | |
| 257 # afterwards, since there may have been a change between GUI and CLI | |
| 258 # mode. | |
| 259 # | |
| 260 # After the first call to this function it is possible to use assertions. | |
| 261 # | |
| 262 proc pkgconf::initialise_error_handling { } { | |
| 263 | |
| 264 if { $pkgconf::gui_mode } { | |
| 265 set pkgconf::fatal_error_handler pkgconf::gui_fatal_error_handler | |
| 266 set pkgconf::warning_handler pkgconf::gui_warning_handler | |
| 267 set pkgconf::report_handler pkgconf::gui_report_handler | |
| 268 } else { | |
| 269 set pkgconf::fatal_error_handler pkgconf::cli_fatal_error_handler | |
| 270 set pkgconf::warning_handler pkgconf::cli_warning_handler | |
| 271 set pkgconf::report_handler pkgconf::cli_report_handler | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 # | |
| 276 # These routines can be used by containing programs to provide their | |
| 277 # own error handling. | |
| 278 # | |
| 279 proc pkgconf::set_fatal_error_handler { fn } { | |
| 280 ASSERT { $fn != "" } | |
| 281 set pkgconf::fatal_error_handler $fn | |
| 282 } | |
| 283 | |
| 284 proc pkgconf::set_warning_handler { fn } { | |
| 285 ASSERT { $fn != "" } | |
| 286 set pkgconf::warning_handler $fn | |
| 287 } | |
| 288 | |
| 289 proc pkgconf::set_report_handler { fn } { | |
| 290 ASSERT { $fn != "" } | |
| 291 set pkgconf::report_handler $fn | |
| 292 } | |
| 293 | |
| 294 # | |
| 295 # A very simple assertion facility. It takes a single argument, an expression | |
| 296 # that should be evaluated in the calling function's scope, and on failure it | |
| 297 # should generate a fatal error. | |
| 298 # | |
| 299 proc pkgconf::ASSERT { condition } { | |
| 300 | |
| 301 set result [uplevel 1 [list expr $condition]] | |
| 302 | |
| 303 if { $result == 0 } { | |
| 304 fatal_error "Assertion failure.\nPredicate \"$condition\"\nThe failure occurred in \"[info level -1]\"" | |
| 305 } | |
| 306 } | |
| 307 | |
| 308 # }}} | |
| 309 # {{{ Utilities | |
| 310 | |
| 311 # ---------------------------------------------------------------------------- | |
| 312 # cdl_compare_version. This is a partial implementation of the full | |
| 313 # cdl_compare_version facility defined in the product specification. Its | |
| 314 # purpose is to order the various versions of a given package with | |
| 315 # the most recent version first. As a special case, "current" is | |
| 316 # always considered the most recent. | |
| 317 # | |
| 318 # There are similarities between cdl_compare_version and with Tcl's | |
| 319 # package vcompare, but cdl_compare_version is more general. | |
| 320 # | |
| 321 | |
| 322 proc pkgconf::cdl_compare_version { arg1 arg2 } { | |
| 323 | |
| 324 if { $arg1 == $arg2 } { | |
| 325 return 0 | |
| 326 } | |
| 327 if { $arg1 == "current"} { | |
| 328 return -1 | |
| 329 } | |
| 330 if { $arg2 == "current" } { | |
| 331 return 1 | |
| 332 } | |
| 333 | |
| 334 set index1 0 | |
| 335 set index2 0 | |
| 336 set ch1 "" | |
| 337 set ch2 "" | |
| 338 set num1 "" | |
| 339 set num2 "" | |
| 340 | |
| 341 while { 1} { | |
| 342 | |
| 343 set ch1 [string index $arg1 $index1] | |
| 344 set ch2 [string index $arg2 $index2] | |
| 345 set num1 "" | |
| 346 set num2 "" | |
| 347 | |
| 348 if { ($ch1 == "") && ($ch2 == "") } { | |
| 349 | |
| 350 # Both strings have terminated at the same time. There may have | |
| 351 # been some spurious leading zeroes in numbers. | |
| 352 return 0 | |
| 353 | |
| 354 } elseif { $ch1 == "" } { | |
| 355 | |
| 356 # The first string has ended first. If ch2 is a separator then | |
| 357 # arg2 is a derived version, e.g. v0.3.p1 and hence newer. Otherwise ch2 | |
| 358 # is an experimental version v0.3beta and hence older. | |
| 359 if { [string match \[-._\] $ch2] } { | |
| 360 return 1 | |
| 361 } else { | |
| 362 return -1 | |
| 363 } | |
| 364 } elseif { $ch2 == "" } { | |
| 365 | |
| 366 # Equivalent to the above. | |
| 367 if { [string match \[-._\] $ch1] } { | |
| 368 return -1 | |
| 369 } else { | |
| 370 return 1 | |
| 371 } | |
| 372 } | |
| 373 | |
| 374 # There is still data to be processed. | |
| 375 # Check for both strings containing numbers at the current index. | |
| 376 if { ( [string match \[0-9\] $ch1] ) && ( [string match \[0-9\] $ch2] ) } { | |
| 377 | |
| 378 # Extract the entire numbers from the version string. | |
| 379 while { [string match \[0-9\] $ch1] } { | |
| 380 set num1 "$num1$ch1" | |
| 381 incr index1 | |
| 382 set ch1 [string index $arg1 $index1] | |
| 383 } | |
| 384 while { [string match \[0-9\] $ch2] } { | |
| 385 set num2 "$num2$ch2" | |
| 386 incr index2 | |
| 387 set ch2 [string index $arg2 $index2] | |
| 388 } | |
| 389 | |
| 390 if { $num1 < $num2 } { | |
| 391 return 1 | |
| 392 } elseif { $num1 > $num2 } { | |
| 393 return -1 | |
| 394 } | |
| 395 continue | |
| 396 } | |
| 397 | |
| 398 # This is not numerical data. If the two characters are the same then | |
| 399 # move on. | |
| 400 if { $ch1 == $ch2 } { | |
| 401 incr index1 | |
| 402 incr index2 | |
| 403 continue | |
| 404 } | |
| 405 | |
| 406 # Next check if both strings are at a separator. All separators can be | |
| 407 # used interchangeably. | |
| 408 if { ( [string match \[-._\] $ch1] ) && ( [string match \[-._\] $ch2] ) } { | |
| 409 incr index1 | |
| 410 incr index2 | |
| 411 continue | |
| 412 } | |
| 413 | |
| 414 # There are differences in the characters and they are not interchangeable. | |
| 415 # Just return a standard string comparison. | |
| 416 return [string compare $ch1 $ch2] | |
| 417 } | |
| 418 } | |
| 419 | |
| 420 if { 0 } { | |
| 421 | |
| 422 puts "compare current v0.1 : [pkgconf::cdl_compare_version current v0.1]" | |
| 423 puts "compare v0.1 current : [pkgconf::cdl_compare_version v0.1 current]" | |
| 424 puts "compare current current : [pkgconf::cdl_compare_version current current]" | |
| 425 puts "compare v0.1 v0.1 : [pkgconf::cdl_compare_version v0.1 v0.1]" | |
| 426 puts "compare v0_1 v0.1 : [pkgconf::cdl_compare_version v0_1 v0.1]" | |
| 427 puts "compare v0.1 v0_1 : [pkgconf::cdl_compare_version v0.1 v0_1]" | |
| 428 puts "compare v0_1 v0-1 : [pkgconf::cdl_compare_version v0_1 v0-1]" | |
| 429 puts "compare v0-1 v0_1 : [pkgconf::cdl_compare_version v0-1 v0_1]" | |
| 430 puts "compare v0.2 v0.1 : [pkgconf::cdl_compare_version v0.2 v0.1]" | |
| 431 puts "compare v0.1 v0.2 : [pkgconf::cdl_compare_version v0.1 v0.2]" | |
| 432 puts "compare v0.10 v0.2 : [pkgconf::cdl_compare_version v0.10 v0.2]" | |
| 433 puts "compare v0.2 v0.10 : [pkgconf::cdl_compare_version v0.2 v0.10]" | |
| 434 puts "compare 980410 980412 : [pkgconf::cdl_compare_version 980410 980412]" | |
| 435 puts "compare 980412 980410 : [pkgconf::cdl_compare_version 980412 980410]" | |
| 436 puts "compare ss980410 ss980412 : [pkgconf::cdl_compare_version ss980410 ss980412]" | |
| 437 puts "compare ss980412 ss980410 : [pkgconf::cdl_compare_version ss980412 ss980410]" | |
| 438 puts "compare v0.1.2 v0.1.3 : [pkgconf::cdl_compare_version v0.1.2 v0.1.3]" | |
| 439 puts "compare v0.1.3 v0.1.2 : [pkgconf::cdl_compare_version v0.1.3 v0.1.2]" | |
| 440 puts "compare v1.0 v0.1.3 : [pkgconf::cdl_compare_version v1.0 v0.1.3]" | |
| 441 puts "compare v0.1.3 v1.0 : [pkgconf::cdl_compare_version v0.1.3 v1.0]" | |
| 442 puts "compare v1.0beta v1.0 : [pkgconf::cdl_compare_version v1.0beta v1.0]" | |
| 443 puts "compare v1.0 v1.0beta : [pkgconf::cdl_compare_version v1.0 v1.0beta]" | |
| 444 puts "compare v1.0.p1 v1.0 : [pkgconf::cdl_compare_version v1.0.p1 v1.0]" | |
| 445 puts "compare v1.0 v1.0.p1 : [pkgconf::cdl_compare_version v1.0 v1.0.p1]" | |
| 446 } | |
| 447 | |
| 448 # }}} | |
| 449 # {{{ Argument parsing | |
| 450 | |
| 451 # ---------------------------------------------------------------------------- | |
| 452 # Parsing the arguments. The following arguments should be accepted for | |
| 453 # backwards compatibility reasons. | |
| 454 # | |
| 455 # --target=<arch_name> | |
| 456 # --platform=sim | |
| 457 # --startup=rom or --startup=ram | |
| 458 # --prefix=<directory> | |
| 459 # --disable-uitron | |
| 460 # --disable-libc | |
| 461 # | |
| 462 # There was also a --disable-kernel_c_api, but that is no longer supported. | |
| 463 # For now disabling only applies to entire packages, not to components | |
| 464 # within a package. The argument --release=debug has also been disabled | |
| 465 # because it affects too many things (the makevars file, various #define's, | |
| 466 # etc.). | |
| 467 # | |
| 468 # Also it was possible to use --disable-uitron=yes, but that was | |
| 469 # undocumented and is not worth supporting. | |
| 470 # | |
| 471 # Configure allowed --srcdir=xxx, although it did not need it. It is useful | |
| 472 # to support this, and to add --builddir. --installdir as a prefix alias | |
| 473 # then makes sense. | |
| 474 # | |
| 475 # --help should be supported if present as a single argument. | |
| 476 # | |
| 477 # It is desirable to support additional arguments of the form: | |
| 478 # | |
| 479 # --enable-uitron (to undo a disable in the saved data) | |
| 480 # --kernel-version=current | |
| 481 # --uitron-version=v0.3 | |
| 482 # | |
| 483 # Similarly it is desirable to allow users to control compiler flags, e.g. | |
| 484 # DBGFLAGS="-Wall -Werror" | |
| 485 # | |
| 2 | 486 # --debug can be used to set appropriate debug options in the |
| 487 # infrastructure. This should probably be --enable-debug, but that | |
| 488 # could cause confusion. There is also a --nodebug option. | |
| 489 # | |
| 0 | 490 # A new argument is --nw, to disable the GUI environment. Other new |
| 491 # arguments are: | |
| 492 # --targets and --packages to display the appropriate details | |
| 493 # --force to force files to be copied across from the repository | |
| 494 # --defaults to cause the program to ignore the values in the save file. | |
| 495 # --linkhdrs and --copyhdrs to control how header files should be handled. | |
| 496 # | |
| 497 # It is also a good idea to be a bit more flexible about the format | |
| 498 # of the command line arguments, for example -target=xxx should work, | |
| 499 # as should -target xxx | |
| 500 # | |
| 501 # The argv0 argument should be the name of this script. It can be used | |
| 502 # to get at the component repository location. If this script has been | |
| 503 # run incorrectly then currently it will fail: in future it may be | |
| 504 # desirable to check an environment variable instead. | |
| 505 # | |
| 506 # The argv argument is a string containing the rest of the arguments. | |
| 507 # If any of the arguments contain spaces then this argument will be | |
| 508 # surrounded by braces. If any of the arguments contain braces then | |
| 509 # things will break. | |
| 510 # | |
| 511 | |
| 512 proc pkgconf::parse_arguments { argv0 argv } { | |
| 513 | |
| 514 # First, check for --help or any of the variants. If this script | |
| 515 # is running in a larger program then it is assumed that the | |
| 516 # containing program will not pass --help as an argument. | |
| 517 if { ( $argv == "--help" ) || ( $argv == "-help" ) || | |
| 518 ( $argv == "--H" ) || ( $argv == "-H" ) } { | |
| 519 | |
| 520 argument_help | |
| 521 exit 0 | |
| 522 } | |
| 523 | |
| 524 if { $argv != "" } { | |
| 525 | |
| 526 # There are arguments. If any of the arguments contained | |
| 527 # spaces then these arguments will have been surrounded | |
| 528 # by braces, which is a nuisance. So start by turning the | |
| 529 # arguments into a numerically indexed array. | |
| 530 | |
| 531 set argc 0 | |
| 532 array set args { } | |
| 533 foreach arg $argv { | |
| 534 set args([incr argc]) $arg | |
| 535 } | |
| 536 | |
| 537 # Now examine each argument with regular expressions. It is | |
| 538 # useful to have some variables filled in by the regexp | |
| 539 # matching. | |
| 540 set dummy "" | |
| 541 set match1 "" | |
| 542 set match2 "" | |
| 543 for { set i 1 } { $i <= $argc } { incr i } { | |
| 544 | |
| 545 # Check for -nw. The regexp allows an optional -, followed by | |
| 546 # the text -nw, and nothing else. | |
| 547 if { [regexp -- {^-?-nw$} $args($i)] == 1 } { | |
| 548 set pkgconf::no_windows_arg 1 | |
| 549 continue | |
| 550 } | |
| 551 | |
| 552 # Check for --packages and the other simple ones. | |
| 553 if { [regexp -- {^-?-packages$} $args($i)] == 1 } { | |
| 554 set pkgconf::list_packages_arg 1 | |
| 555 continue | |
| 556 } | |
| 557 if { [regexp -- {^-?-pkgdata$} $args($i)] == 1 } { | |
| 558 set pkgconf::list_pkgdata_arg 1 | |
| 559 continue | |
| 560 } | |
| 561 if { [regexp -- {^-?-targets$} $args($i)] == 1 } { | |
| 562 set pkgconf::list_targets_arg 1 | |
| 563 continue | |
| 564 } | |
| 565 if { [regexp -- {^-?-flags$} $args($i)] == 1 } { | |
| 566 set pkgconf::list_flags_arg 1 | |
| 567 continue | |
| 568 } | |
| 569 if { [regexp -- {^-?-force$} $args($i)] == 1 } { | |
| 570 set pkgconf::force_arg 1 | |
| 571 continue | |
| 572 } | |
| 573 if { [regexp -- {^-?-defaults$} $args($i)] == 1 } { | |
| 574 set pkgconf::defaults_arg 1 | |
| 575 continue | |
| 576 } | |
| 577 if { [regexp -- {^-?-linkhdrs$} $args($i)] == 1 } { | |
| 578 set pkgconf::use_links_arg 1 | |
| 579 continue | |
| 580 } | |
| 581 if { [regexp -- {^-?-copyhdrs$} $args($i)] == 1 } { | |
| 582 set pkgconf::use_copies_arg 1 | |
| 583 continue | |
| 584 } | |
| 2 | 585 if { [regexp -- {^-?-debug$} $args($i)] == 1 } { |
| 586 set pkgconf::debug_arg 1 | |
| 587 continue | |
| 588 } | |
| 589 if { [regexp -- {^-?-nodebug$} $args($i)] == 1 } { | |
| 590 set pkgconf::nodebug_arg 1 | |
| 591 continue | |
| 592 } | |
| 0 | 593 |
| 594 # Now for the directories. srcdir and builddir will have | |
| 595 # been calculated already, but may be overridden here. | |
| 596 if { [regexp -- {^-?-src_?dir=?(.*)$} $args($i) dummy match1] == 1 } { | |
| 597 if { $match1 != "" } { | |
| 598 set pkgconf::component_repository $match1 | |
| 599 } else { | |
| 600 if { $i == $argc } { | |
| 601 fatal_error "pkgconf: missing argument after --srcdir" | |
| 602 } else { | |
| 603 set pkgconf::component_repository $args([incr i]) | |
| 604 } | |
| 605 } | |
| 606 continue | |
| 607 } | |
| 608 if { [regexp -- {^-?-build_?dir=?(.*)$} $args($i) dummy match1] == 1 } { | |
| 609 if { $match1 != "" } { | |
| 610 set pkgconf::build_tree $match1 | |
| 611 } else { | |
| 612 if { $i == $argc } { | |
| 613 fatal_error "pkgconf: missing argument after --builddir" | |
| 614 } else { | |
| 615 set pkgconf::build_tree $args([incr i]) | |
| 616 } | |
| 617 } | |
| 618 continue | |
| 619 } | |
| 620 | |
| 621 # And prefix, before moving on to the more interesting ones. | |
| 622 # Prefix is a pathname so spaces are legitimate, as are dots, | |
| 623 # directory separators, and drive indicators. | |
| 624 # | |
| 625 # NOTE: strictly speaking the pattern should be platform specific. | |
| 626 if { [regexp -- {^-?-prefix=?(.*)$} $args($i) dummy match1] == 1 } { | |
| 627 if { $match1 != "" } { | |
| 628 set pkgconf::prefix_arg $match1 | |
| 629 } else { | |
| 630 if { $i == $argc } { | |
| 631 fatal_error "pkgconf: missing argument after --prefix" | |
| 632 } else { | |
| 633 set pkgconf::prefix_arg $args([incr i]) | |
| 634 } | |
| 635 } | |
| 636 continue | |
| 637 } | |
| 638 | |
| 639 # --installdir is a useful alias for prefix. | |
| 640 if { [regexp -- {^-?-install_?dir=?(.*)$} $args($i) dummy match1] == 1 } { | |
| 641 if { $match1 != "" } { | |
| 642 set pkgconf::prefix_arg $match1 | |
| 643 } else { | |
| 644 if { $i == $argc } { | |
| 645 fatal_error "pkgconf: missing argument after --installdir" | |
| 646 } else { | |
| 647 set pkgconf::prefix_arg $args([incr i]) | |
| 648 } | |
| 649 } | |
| 650 continue | |
| 651 } | |
| 652 | |
| 653 | |
| 654 # Now check for a --target arg. The -target must match exactly, | |
| 655 # but there can be one leading hyphen that gets ignored. The | |
| 656 # target can be part of the same argument (with an = in between) | |
| 657 # or it can be all of the next argument. | |
| 658 # | |
| 659 # This code will match spuriously with --targetxxx, i.e. the | |
| 660 # = is optional. This is harmless. | |
| 661 # | |
| 662 # The target is not validated at this point, that happens after | |
| 663 # reading in the targets file. It is possible to specify | |
| 664 # several --target arguments, and only the last one takes | |
| 665 # effect. | |
| 666 if { [regexp -- {^-?-target=?([_a-zA-Z0-9]*)$} $args($i) dummy match1] == 1 } { | |
| 667 if { $match1 != "" } { | |
| 668 set pkgconf::target_arg $match1 | |
| 669 } else { | |
| 670 if { $i == $argc } { | |
| 671 fatal_error "pkgconf: missing argument after --target" | |
| 672 } else { | |
| 673 set pkgconf::target_arg $args([incr i]) | |
| 674 } | |
| 675 } | |
| 676 continue | |
| 677 } | |
| 678 | |
| 679 # Ditto for --platform. | |
| 680 if { [regexp -- {^-?-platform=?([_a-zA-Z0-9]*)$} $args($i) dummy match1] == 1 } { | |
| 681 if { $match1 != "" } { | |
| 682 set pkgconf::platform_arg $match1 | |
| 683 } else { | |
| 684 if { $i == $argc } { | |
| 685 fatal_error "pkgconf: missing argument after --platform" | |
| 686 } else { | |
| 687 set pkgconf::platform_arg $args([incr i]) | |
| 688 } | |
| 689 } | |
| 690 continue | |
| 691 } | |
| 692 | |
| 693 # And for --startup. | |
| 694 if { [regexp -- {^-?-startup=?([_a-zA-Z0-9]*)$} $args($i) dummy match1] == 1 } { | |
| 695 if { $match1 != "" } { | |
| 696 set pkgconf::startup_arg $match1 | |
| 697 } else { | |
| 698 if { $i == $argc } { | |
| 699 fatal_error "pkgconf: missing argument after --startup" | |
| 700 } else { | |
| 701 set pkgconf::startup_arg $args([incr i]) | |
| 702 } | |
| 703 } | |
| 704 continue | |
| 705 } | |
| 706 | |
| 707 # Now for --disable-<package>. The disabled packages are stored | |
| 708 # in a simple list. | |
| 709 if { [regexp -- {^-?-disable-?=?([_a-zA-Z0-9]*)$} $args($i) dummy match1] == 1 } { | |
| 710 if { $match1 != "" } { | |
| 711 lappend pkgconf::disable_args $match1 | |
| 712 } else { | |
| 713 if { $i == $argc } { | |
| 714 fatal_error "pkgconf: missing argument after --disable" | |
| 715 } else { | |
| 716 lappend pkgconf::disable_args $args([incr i]) | |
| 717 } | |
| 718 } | |
| 719 continue | |
| 720 } | |
| 721 | |
| 722 # The same for --enable-<package>. | |
| 723 if { [regexp -- {^-?-enable-?=?([_a-zA-Z0-9]*)$} $args($i) dummy match1] == 1 } { | |
| 724 if { $match1 != "" } { | |
| 725 lappend pkgconf::enable_args $match1 | |
| 726 } else { | |
| 727 if { $i == $argc } { | |
| 728 fatal_error "pkgconf: missing argument after --enable" | |
| 729 } else { | |
| 730 lappend pkgconf::enable_args $args([incr i]) | |
| 731 } | |
| 732 } | |
| 733 continue | |
| 734 } | |
| 735 | |
| 736 # And for --<package>-version=xxx | |
| 737 # These versions are stored in an array indexed by the | |
| 738 # package string. | |
| 739 if {[regexp -- {^-?-([_a-zA-Z0-9]+)-?version=?([_\.a-zA-Z0-9]*)$} $args($i) dummy match1 match2] == 1} { | |
| 740 if { $match2 != "" } { | |
| 741 set pkgconf::version_args($match1) $match2 | |
| 742 } else { | |
| 743 if { $i == $argc } { | |
| 744 fatal_error "pkgconf: missing argument after --$match1-version" | |
| 745 } else { | |
| 746 set pkgconf::version_args($match1) $args([incr i]) | |
| 747 } | |
| 748 } | |
| 749 continue | |
| 750 } | |
| 751 | |
| 752 # For each of the known compiler flags, check for a definition of | |
| 753 # this flag. The flags are stored in an array cflags_args(). | |
| 754 # Note that an empty string is legal, so that the default flags | |
| 755 # from the targets file can be disabled. | |
| 756 set its_a_flag 0 | |
| 757 foreach flag $pkgconf::known_compiler_flags { | |
| 758 if { [regexp -- "^[set flag]=(.*)\$" $args($i) dummy match1] == 1 } { | |
| 759 set pkgconf::cflags_args($flag) $match1 | |
| 760 set its_a_flag 1 | |
| 761 break | |
| 762 } | |
| 763 } | |
| 764 if { $its_a_flag != 0 } { | |
| 765 continue | |
| 766 } | |
| 767 | |
| 768 # An unrecognised argument. | |
| 769 fatal_error "pkgconf: invalid argument $args($i)" | |
| 770 } | |
| 771 } | |
| 772 | |
| 773 # Under Windows it is desirable to do some checking on any directories that | |
| 774 # have been provided. Some cygwin pathnames that a user might supply are | |
| 775 # not acceptable to Tcl. | |
| 776 if { $pkgconf::windows_host } { | |
| 777 set pkgconf::component_repository [get_pathname_for_tcl $pkgconf::component_repository] | |
| 778 set pkgconf::build_tree [get_pathname_for_tcl $pkgconf::build_tree] | |
| 779 if { $pkgconf::prefix_arg != "" } { | |
| 780 set pkgconf::prefix_arg [get_pathname_for_tcl $pkgconf::prefix_arg] | |
| 781 } | |
| 782 } | |
| 783 | |
| 784 # Enabling this facilitates testing of the parsing code. | |
| 785 if { 0 } { | |
| 786 puts "component repository is $pkgconf::component_repository" | |
| 787 puts "build tree is $pkgconf::build_tree" | |
| 788 puts "prefix_arg is $pkgconf::prefix_arg" | |
| 789 puts "list_targets_arg is $pkgconf::list_targets_arg" | |
| 790 puts "list_packages_arg is $pkgconf::list_packages_arg" | |
| 791 puts "list_pkgdata_arg is $pkgconf::list_pkgdata_arg" | |
| 792 puts "list_flags_arg is $pkgconf::list_flags_arg" | |
| 793 puts "no_windows_arg is $pkgconf::no_windows_arg" | |
| 794 puts "target_arg is $pkgconf::target_arg" | |
| 795 puts "platform_arg is $pkgconf::platform_arg" | |
| 796 puts "startup_arg is $pkgconf::startup_arg" | |
| 797 puts "disable_args is $pkgconf::disable_args" | |
| 798 puts "enable_args is $pkgconf::enable_args" | |
| 799 puts "force_arg is $pkgconf::force_arg" | |
| 800 puts "defaults_arg is $pkgconf::defaults_arg" | |
| 801 puts "use_links_arg is $pkgconf::use_links_arg" | |
| 802 puts "use_copies_arg is $pkgconf::use_copies_arg" | |
| 2 | 803 puts "debug_arg is $pkgconf::debug_arg" |
| 804 puts "nodebug_arg is $pkgconf::nodebug_arg" | |
| 0 | 805 foreach i [array names pkgconf::version_args] { |
| 806 puts "Package $i needs version $pkgconf::version_args($i)" | |
| 807 } | |
| 808 foreach flag [array names pkgconf::cflags_args] { | |
| 809 puts "Compiler flag $flag has value $pkgconf::cflags_args($flag)" | |
| 810 } | |
| 811 exit 0 | |
| 812 } | |
| 813 | |
| 814 } | |
| 815 | |
| 816 # | |
| 817 # Display help information if the user has typed --help, -H, --H, or -help. | |
| 818 # The help text uses two hyphens for consistency with configure. | |
| 819 # Arguably this should change. | |
| 820 # | |
| 821 # Not all legal command line arguments are listed. Some of the command | |
| 822 # line arguments like --flags are intended for internal use only. | |
| 823 # | |
| 824 # NOTE: if this command is being invoked from a shell script that sets | |
| 825 # the defaults for a particular architecture then the information will not | |
| 826 # be completely accurate. There is no easy solution for this problem. | |
| 827 # | |
| 828 # NOTE: it would be a really good idea to give an example command line. | |
| 829 # Unfortunately this command line must include a target architecture, | |
| 830 # and there is no sensible default for that. | |
| 831 # | |
| 832 proc pkgconf::argument_help { } { | |
| 833 | |
| 834 puts "Usage: pkgconf \[options\]" | |
| 835 puts "Available options are:" | |
| 836 puts " --help : display this text." | |
| 837 puts " --packages : list all packages." | |
| 838 puts " --targets : list all possible targets." | |
| 839 puts " --target=<arch> : target the specified architecture." | |
| 840 puts " --platform=sim : target the simulator rather than hardware." | |
| 841 puts " --startup=rom : generate code suitable for ROMming." | |
| 842 puts " --disable-<pkg> : disable a given package." | |
| 843 puts " --enable-<pkg> : enable a given package." | |
| 844 puts " --<pkg>-version=v0.3 : use a specific version of a package." | |
| 845 puts " --defaults : use default settings instead of the save file." | |
| 846 puts " --srcdir=<dir> : specify location of the component repository." | |
| 847 puts " --builddir=<dir> : specify location of the build directory." | |
| 848 puts " --prefix=<dir> : specify location of the install directory." | |
| 849 } | |
| 850 | |
| 851 # }}} | |
| 852 # {{{ Packages file | |
| 853 | |
| 854 # ---------------------------------------------------------------------------- | |
| 855 # The component repository should contain a file "packages" containing details | |
| 856 # of all supported packages. This file is actually an executable Tcl script | |
| 857 # containing instances of the "package" command, which takes three arguments. | |
| 858 # It is necessary to update the variables pkgconf::known_packages and | |
| 859 # pkgconf::package_data. | |
| 860 # | |
| 861 | |
| 862 proc pkgconf::read_packages { } { | |
| 863 | |
| 864 ASSERT { $pkgconf::component_repository != "" } | |
| 865 ASSERT { [array names pkgconf::package_data] == "" } | |
| 866 ASSERT { $pkgconf::known_packages == "" } | |
| 867 | |
| 868 # A safe interpreter is used to process the packages file. | |
| 869 # This is somewhat overcautious, but it is also harmless. | |
| 870 # The following two commands are made accessible to the slave | |
| 871 # interpreter and are responsible for updating the actual data. | |
| 872 proc set_package_data { name value } { | |
| 2 | 873 set ::pkgconf::package_data($name) $value |
| 0 | 874 } |
| 875 proc add_known_package { name } { | |
| 2 | 876 lappend ::pkgconf::known_packages $name |
| 0 | 877 } |
| 878 | |
| 879 # Create the parser, add the aliased commands, and then define | |
| 880 # the routines that do the real work. | |
| 881 set parser [interp create -safe] | |
| 882 $parser alias set_package_data pkgconf::set_package_data | |
| 883 $parser alias add_known_package pkgconf::add_known_package | |
| 884 | |
| 885 $parser eval { | |
| 886 | |
| 887 set current_package "" | |
| 888 | |
| 889 proc package { name body } { | |
| 890 | |
| 891 add_known_package $name | |
| 892 set_package_data "$name,alias" $name | |
| 893 set_package_data "$name,dir" "" | |
| 894 set_package_data "$name,versions" "" | |
| 895 set_package_data "$name,default" 0 | |
| 896 set_package_data "$name,incdir" "" | |
| 897 set_package_data "$name,hardware" 0 | |
| 898 | |
| 899 # Evaluate the body such that the commands know what the current package is. | |
| 900 set ::current_package $name | |
| 901 eval $body | |
| 902 set ::current_package "" | |
| 903 } | |
| 904 | |
| 905 proc alias { str } { | |
| 906 set_package_data "$::current_package,alias" $str | |
| 907 } | |
| 908 | |
| 909 # The remaining commands are basically clones of alias. | |
| 910 proc directory { dir } { | |
| 911 set_package_data "$::current_package,dir" $dir | |
| 912 } | |
| 913 | |
| 914 proc default_value { val } { | |
| 915 set_package_data "$::current_package,default" $val | |
| 916 } | |
| 917 | |
| 918 proc include_dir { dir } { | |
| 919 set_package_data "$::current_package,incdir" $dir | |
| 920 } | |
| 921 | |
| 922 proc hardware { } { | |
| 923 set_package_data "$::current_package,hardware" 1 | |
| 924 } | |
| 925 } | |
| 926 | |
| 927 # The parser is ready to evaluate the script. To avoid having to give the | |
| 928 # safe interpreter file I/O capabilities, the file is actually read in | |
| 929 # here and then evaluated. | |
| 930 set filename [file join $pkgconf::component_repository "packages"] | |
| 931 set status [ catch { | |
| 932 set fd [open $filename r] | |
| 933 set script [read $fd] | |
| 934 close $fd | |
| 935 $parser eval $script | |
| 936 } message] | |
| 937 | |
| 938 if { $status != 0 } { | |
| 939 pkgconf::fatal_error "Unexpected error while processing $filename\n$message" | |
| 940 } | |
| 941 | |
| 942 # The interpreter and the aliased commands are no longer required. | |
| 943 rename set_package_data {} | |
| 944 rename add_known_package {} | |
| 945 interp delete $parser | |
| 946 | |
| 947 # At this stage the packages file has been read in. It is a good idea to | |
| 948 # check that all of these packages are present and correct, and incidentally | |
| 949 # figure out which versions are present. | |
| 950 foreach pkg $pkgconf::known_packages { | |
| 951 | |
| 952 set pkgdir [file join $pkgconf::component_repository $pkgconf::package_data($pkg,dir)] | |
| 953 if { ![file exists $pkgdir] || ![file isdir $pkgdir] } { | |
| 954 fatal_error \ | |
| 955 "The file [file join $pkgconf::component_repository "packages"] lists a package\ | |
| 956 $pkg which should be present in $pkgdir. This package is missing." | |
| 957 } | |
| 958 | |
| 959 # Each subdirectory should correspond to a release. A utility routine | |
| 960 # is available for this. | |
| 961 set pkgconf::package_data($pkg,versions) [locate_subdirs $pkgdir] | |
| 962 if { $pkgconf::package_data($pkg,versions) == "" } { | |
| 963 fatal_error "The package $pkg does not contain any version directories." | |
| 964 } | |
| 965 | |
| 966 # Sort all the versions using a version-aware comparison version | |
| 967 set pkgconf::package_data($pkg,versions) [ | |
| 968 lsort -command pkgconf::cdl_compare_version $pkgconf::package_data($pkg,versions) | |
| 969 ] | |
| 970 } | |
| 971 | |
| 972 # Handle the --packages argument. | |
| 973 if { $pkgconf::list_packages_arg != 0 } { | |
| 974 | |
| 975 # The user wants to know about all the arguments. Just to be fancy | |
| 976 # this code does some alignment. | |
| 977 set name_maxlen 0 | |
| 978 | |
| 979 foreach pkg $pkgconf::known_packages { | |
| 980 if { [string length $pkg] > $name_maxlen} { | |
| 981 set name_maxlen [string length $pkg] | |
| 982 } | |
| 983 } | |
| 984 | |
| 985 puts "Known packages are:" | |
| 986 foreach pkg $pkgconf::known_packages { | |
| 987 puts "[format " %-*s : " $name_maxlen $pkg]" | |
| 988 puts " Available versions: $pkgconf::package_data($pkg,versions)" | |
| 989 puts " Aliases : $pkgconf::package_data($pkg,alias)" | |
| 990 if { $pkgconf::package_data($pkg,hardware) } { | |
| 991 puts " This package is only available on specific hardware." | |
| 992 } | |
| 993 if { $pkgconf::package_data($pkg,default) } { | |
| 994 puts " This package is enabled by default." | |
| 995 } else { | |
| 996 puts " This package is disabled by default." | |
| 997 } | |
| 998 } | |
| 999 } | |
| 1000 | |
| 1001 # Ditto for the --pkgdata argument. In this case the data is intended for use | |
| 1002 # by other programs, and is not necessarily intelligible to users. | |
| 1003 if { $pkgconf::list_pkgdata_arg != 0 } { | |
| 1004 foreach pkg $pkgconf::known_packages { | |
| 1005 set dir [file join $pkgconf::package_data($pkg,dir) [lindex $pkgconf::package_data($pkg,versions) 0]] | |
| 1006 set dir [file nativename $dir] | |
| 1007 if { $pkgconf::windows_host != 0 } { | |
| 1008 regsub -all {\\} $dir {\\\\} dir | |
| 1009 } | |
| 1010 set alias [get_build_alias $pkg] | |
| 1011 puts "\"$pkg\" \"$alias\" \"$dir\"" | |
| 1012 } | |
| 1013 } | |
| 1014 } | |
| 1015 | |
| 1016 # | |
| 1017 # Given a package name as supplied by the user, return the internal package name. | |
| 1018 # This involves searching through the list of aliases. | |
| 1019 # | |
| 1020 proc pkgconf::find_package { name } { | |
| 1021 | |
| 1022 foreach pkg $pkgconf::known_packages { | |
| 1023 | |
| 1024 if { [string toupper $pkg] == [string toupper $name] } { | |
| 1025 return $pkg | |
| 1026 } | |
| 1027 | |
| 1028 foreach alias $pkgconf::package_data($pkg,alias) { | |
| 1029 if { [string toupper $alias] == [string toupper $name] } { | |
| 1030 return $pkg | |
| 1031 } | |
| 1032 } | |
| 1033 } | |
| 1034 | |
| 1035 return "" | |
| 1036 } | |
| 1037 | |
| 1038 # | |
| 1039 # Given a package name, return the first alias string. This is useful for | |
| 1040 # output code. | |
| 1041 # | |
| 1042 proc pkgconf::get_package_alias { name } { | |
| 1043 | |
| 1044 pkgconf::ASSERT { [lsearch -exact $pkgconf::known_packages $name] != -1 } | |
| 1045 set alias [lindex $pkgconf::package_data($name,alias) 0] | |
| 1046 return $alias | |
| 1047 } | |
| 1048 | |
| 1049 # | |
| 1050 # Does a given package actually exist ? This copes with aliases | |
| 1051 # as well. | |
| 1052 proc pkgconf::is_package { name } { | |
| 1053 | |
| 1054 ASSERT { $name != "" } | |
| 1055 | |
| 1056 set result 0 | |
| 1057 set name [find_package $name] | |
| 1058 if { $name != "" } { | |
| 1059 set result 1 | |
| 1060 } | |
| 1061 return $result | |
| 1062 } | |
| 1063 | |
| 1064 # | |
| 1065 # Is a particular package a hardware-specific package ? This code | |
| 1066 # deals with aliases as well | |
| 1067 proc pkgconf::is_hardware_package { name } { | |
| 1068 | |
| 1069 ASSERT { $name != "" } | |
| 1070 | |
| 1071 set name [find_package $name] | |
| 1072 ASSERT { $name != "" } | |
| 1073 | |
| 1074 set result 0 | |
| 1075 if { $pkgconf::package_data($name,hardware) != 0 } { | |
| 1076 set result 1 | |
| 1077 } | |
| 1078 return $result | |
| 1079 } | |
| 1080 | |
| 1081 # | |
| 1082 # Is a particular version string valid for the given package ? | |
| 1083 proc pkgconf::is_valid_version { pkg version } { | |
| 1084 | |
| 1085 ASSERT { $pkg != "" } | |
| 1086 ASSERT { $version != "" } | |
| 1087 | |
| 1088 set pkg [find_package $pkg] | |
| 1089 ASSERT { $pkg != "" } | |
| 1090 | |
| 1091 set result 0 | |
| 1092 set index [lsearch -exact $pkgconf::package_data($pkg,versions) $version] | |
| 1093 if { $index != -1 } { | |
| 1094 set result 1 | |
| 1095 } | |
| 1096 return $result | |
| 1097 } | |
| 1098 | |
| 1099 # }}} | |
| 1100 # {{{ Targets file | |
| 1101 | |
| 1102 # ---------------------------------------------------------------------------- | |
| 1103 # The handling of the targets file is similar to that for the packages file, | |
| 1104 # but a targets file is a bit more complicated. | |
| 1105 # | |
| 1106 | |
| 1107 proc pkgconf::read_targets { } { | |
| 1108 | |
| 1109 ASSERT { $pkgconf::component_repository != "" } | |
| 1110 ASSERT { [array names pkgconf::target_data] == "" } | |
| 1111 ASSERT { $pkgconf::known_targets == "" } | |
| 1112 ASSERT { $pkgconf::known_compiler_flags != "" } | |
| 1113 | |
| 1114 proc add_known_target { name } { | |
| 2 | 1115 lappend ::pkgconf::known_targets $name |
| 1116 set ::pkgconf::target_data($name,alias) $name | |
| 1117 set ::pkgconf::target_data($name,prefix) "" | |
| 1118 set ::pkgconf::target_data($name,known_platforms) "" | |
| 1119 set ::pkgconf::target_data($name,packages) "" | |
| 0 | 1120 } |
| 1121 proc add_known_platform { arch name } { | |
| 2 | 1122 lappend ::pkgconf::target_data($arch,known_platforms) $name |
| 1123 set ::pkgconf::target_data($arch,$name,alias) "" | |
| 1124 set ::pkgconf::target_data($arch,$name,startup) "" | |
| 1125 set ::pkgconf::target_data($arch,$name,packages) "" | |
| 0 | 1126 } |
| 1127 proc set_target_data { name value } { | |
| 2 | 1128 set ::pkgconf::target_data($name) $value |
| 0 | 1129 } |
| 1130 | |
| 1131 set parser [interp create -safe] | |
| 1132 interp share {} stdout $parser | |
| 1133 $parser alias set_target_data pkgconf::set_target_data | |
| 1134 $parser alias add_known_target pkgconf::add_known_target | |
| 1135 $parser alias add_known_platform pkgconf::add_known_platform | |
| 1136 $parser eval [list set known_compiler_flags $pkgconf::known_compiler_flags] | |
| 1137 | |
| 1138 $parser eval { | |
| 1139 | |
| 1140 set current_target "" | |
| 1141 set current_platform "" | |
| 1142 | |
| 1143 proc target { name body } { | |
| 1144 | |
| 1145 add_known_target $name | |
| 1146 | |
| 1147 # Evaluate the body such that the commands know what the current target is. | |
| 1148 set ::current_target $name | |
| 1149 eval $body | |
| 1150 set ::current_target "" | |
| 1151 } | |
| 1152 | |
| 1153 proc alias { str } { | |
| 1154 | |
| 1155 # If processing a platform body, update the platform data. Otherwise update the | |
| 1156 # target data. There should be only one alias command per body. | |
| 1157 if { $::current_platform != "" } { | |
| 1158 set_target_data "$::current_target,$::current_platform,alias" $str | |
| 1159 } else { | |
| 1160 set_target_data "$::current_target,alias" $str | |
| 1161 } | |
| 1162 } | |
| 1163 | |
| 1164 proc command_prefix { str } { | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1165 # Allow the command prefix to be overridden on a per-platform basis |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1166 if { $::current_platform != "" } { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1167 set_target_data "$::current_target,$::current_platform,prefix" $str |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1168 } else { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1169 set_target_data "$::current_target,prefix" $str |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1170 } |
| 0 | 1171 } |
| 1172 | |
| 1173 proc packages { list } { | |
| 1174 if { $::current_platform != "" } { | |
| 1175 set_target_data "$::current_target,$::current_platform,packages" $list | |
| 1176 } else { | |
| 1177 set_target_data "$::current_target,packages" $list | |
| 1178 } | |
| 1179 } | |
| 1180 | |
| 1181 proc hal { dir } { | |
| 1182 if { $::current_platform != "" } { | |
| 1183 set_target_data "$::current_target,$::current_platform,haldir" $dir | |
| 1184 } else { | |
| 1185 set_target_data "$::current_target,haldir" $dir | |
| 1186 } | |
| 1187 } | |
| 1188 | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1189 proc base_platform { str } { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1190 if { $::current_platform != "" } { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1191 set_target_data "$::current_target,$::current_platform,base_platform" $str |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1192 } else { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1193 set_target_data "$::current_target,base_platform" $str |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1194 } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1195 } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1196 |
| 0 | 1197 proc platform { name body } { |
| 1198 | |
| 1199 add_known_platform $::current_target $name | |
| 1200 | |
| 1201 set ::current_platform $name | |
| 1202 eval $body | |
| 1203 set ::current_platform "" | |
| 1204 } | |
| 1205 | |
| 1206 proc startup { types } { | |
| 1207 set_target_data "$::current_target,$::current_platform,startup" $types | |
| 1208 } | |
| 1209 | |
| 1210 # The cflags command is much more complicated than the others. The argument | |
| 1211 # to cflags should be a list of paired data, e.g. ERRFLAGS -Wall. | |
| 1212 # The first entry in each pair should be one of the known compiler | |
| 1213 # flags, the second one should be its value. | |
| 1214 proc cflags { str } { | |
| 1215 | |
| 1216 set arg_count [llength $str] | |
| 1217 if { ($arg_count % 2) != 0 } { | |
| 1218 error "Invalid argument list to cflags command in $current_target" | |
| 1219 } | |
| 1220 for { set i 0 } { $i < $arg_count } { incr i 2 } { | |
| 1221 set flag [lindex $str $i] | |
| 1222 set value [lindex $str [expr $i + 1]] | |
| 1223 if { [lsearch -exact $::known_compiler_flags $flag] == -1 } { | |
| 1224 error "Invalid compiler flag $flag for target $::current_target" | |
| 1225 } | |
| 1226 if { $::current_platform != "" } { | |
| 1227 set_target_data "$::current_target,$::current_platform,cflags,$flag" $value | |
| 1228 } else { | |
| 1229 set_target_data "$::current_target,cflags,$flag" $value | |
| 1230 } | |
| 1231 } | |
| 1232 } | |
| 1233 | |
| 1234 } | |
| 1235 | |
| 1236 # The parser is ready to evaluate the script. To avoid having to give the | |
| 1237 # safe interpreter file I/O capabilities, the file is actually read in | |
| 1238 # here and then evaluated. | |
| 1239 set filename [file join $pkgconf::component_repository "targets"] | |
| 1240 set status [ catch { | |
| 1241 set fd [open $filename r] | |
| 1242 set script [read $fd] | |
| 1243 close $fd | |
| 1244 $parser eval $script | |
| 1245 } message] | |
| 1246 | |
| 1247 if { $status != 0 } { | |
| 1248 puts "Unexpected error while processing $filename\n$message" | |
| 1249 exit 1 | |
| 1250 } | |
| 1251 | |
| 1252 # The interpreter and the aliased commands are no longer required. | |
| 1253 rename add_known_target {} | |
| 1254 rename add_known_platform {} | |
| 1255 rename set_target_data {} | |
| 1256 interp delete $parser | |
| 1257 | |
| 1258 # The targets file has been read in, so it is time for some consistency checks. | |
| 1259 foreach target $pkgconf::known_targets { | |
| 1260 | |
| 1261 # If this target involves some special packages, check that these | |
| 1262 # packages were actually defined in the packages file. Also check | |
| 1263 # that these packages are listed as hardware packages so that | |
| 1264 # they will not be enabled by default. | |
| 1265 ASSERT { [info exists pkgconf::target_data($target,packages)] } | |
| 1266 foreach pkg $pkgconf::target_data($target,packages) { | |
| 1267 | |
| 1268 if { [is_package $pkg] == 0 } { | |
| 1269 fatal_error \ | |
| 1270 "The targets file $filename lists a package $pkg\ | |
| 1271 for the $target architecture. This package is not listed\ | |
| 1272 in the packages file." | |
| 1273 | |
| 1274 } elseif { [is_hardware_package $pkg] == 0 } { | |
| 1275 | |
| 1276 fatal_error \ | |
| 1277 "The targets file $filename lists a package $pkg\ | |
| 1278 for the $target architecture. According to the packages\ | |
| 1279 file this package is not hardware-specific." | |
| 1280 } | |
| 1281 } | |
| 1282 | |
| 1283 ASSERT { [info exists pkgconf::target_data($target,known_platforms)] } | |
| 1284 foreach platform $pkgconf::target_data($target,known_platforms) { | |
| 1285 | |
| 1286 ASSERT { [info exists pkgconf::target_data($target,$platform,packages)] } | |
| 1287 foreach pkg $pkgconf::target_data($target,packages) { | |
| 1288 | |
| 1289 if { [is_package $pkg] == 0 } { | |
| 1290 | |
| 1291 fatal_error \ | |
| 1292 "The target file $filename lists a package $pkg\ | |
| 1293 for the $target architecture and the $platform platform.\ | |
| 1294 This package is not listed in the packages file." | |
| 1295 | |
| 1296 } elseif { [is_hardware_package $pkg] == 0 } { | |
| 1297 | |
| 1298 fatal_error \ | |
| 1299 "The target file $filename lists a package $pkg\ | |
| 1300 for the $target architecture and the $platform platform.\ | |
| 1301 According to the packages file this package is not hardware-specific." | |
| 1302 } | |
| 1303 } | |
| 1304 } | |
| 1305 | |
| 1306 # Also check that all required data for all targets and platforms has | |
| 1307 # been supplied. A command prefix is required, as is a startup list. | |
| 1308 | |
| 1309 if { [llength $pkgconf::target_data($target,known_platforms)] == 0 } { | |
| 1310 warning "The targets file $filename lists the $target architecture but no platforms." | |
| 1311 set index [lsearch -exact $pkgconf::known_targets $target] | |
| 1312 ASSERT { $index != -1 } | |
| 1313 set pkgconf::known_targets [lreplace $pkgconf::known_targets $index $index] | |
| 1314 continue | |
| 1315 } | |
| 1316 | |
| 1317 foreach platform $pkgconf::target_data($target,known_platforms) { | |
| 1318 if { [llength $pkgconf::target_data($target,$platform,startup)] == 0 } { | |
| 1319 fatal_error \ | |
| 1320 "The targets file $filename does not list any startup options for target $target, platform $platform." | |
| 1321 } | |
| 1322 } | |
| 1323 } | |
| 1324 | |
| 1325 # At this stage there may be no targets left over. | |
| 1326 if { [llength $pkgconf::known_targets] == 0 } { | |
| 1327 fatal_error "The targets file $filename does not list any usable targets." | |
| 1328 } | |
| 1329 | |
| 1330 # All the directories exist. Did the user ask for a list of all targets ? | |
| 1331 if { $pkgconf::list_targets_arg } { | |
| 1332 | |
| 1333 # The user wants to know about all the targets. Just to be fancy | |
| 1334 # this code does some alignment. | |
| 1335 set name_maxlen 0 | |
| 1336 | |
| 1337 foreach target $pkgconf::known_targets { | |
| 1338 if { [string length $target] > $name_maxlen} { | |
| 1339 set name_maxlen [string length $target] | |
| 1340 } | |
| 1341 } | |
| 1342 | |
| 1343 puts "Known targets:" | |
| 1344 foreach target $pkgconf::known_targets { | |
| 1345 | |
| 1346 puts "[format " %-*s : aliases $pkgconf::target_data($target,alias)" $name_maxlen $target]" | |
| 1347 | |
| 1348 set packages $pkgconf::target_data($target,packages) | |
| 1349 if { [llength $packages] > 0 } { | |
| 1350 puts " Required packages" | |
| 1351 foreach package $packages { | |
| 1352 puts " [pkgconf::get_package_alias $package] ($package)" | |
| 1353 } | |
| 1354 } | |
| 1355 | |
| 1356 foreach platform $pkgconf::target_data($target,known_platforms) { | |
| 1357 puts " Platform $platform, supported startups $pkgconf::target_data($target,$platform,startup)" | |
| 1358 set packages $pkgconf::target_data($target,$platform,packages) | |
| 1359 if { [llength $packages] > 0 } { | |
| 1360 puts " Required packages" | |
| 1361 foreach package $packages { | |
| 1362 puts " [pkgconf::get_package_alias $package] ($package)" | |
| 1363 } | |
| 1364 } | |
| 1365 } | |
| 1366 } | |
| 1367 } | |
| 1368 } | |
| 1369 | |
| 1370 # | |
| 1371 # Given a target name as supplied by the user, return the internal target name. | |
| 1372 # This involves searching through the list of aliases. | |
| 1373 # | |
| 1374 proc pkgconf::find_target { name } { | |
| 1375 | |
| 1376 foreach target $pkgconf::known_targets { | |
| 1377 | |
| 1378 if { [string toupper $target] == [string toupper $name] } { | |
| 1379 return $target | |
| 1380 } | |
| 1381 | |
| 1382 foreach alias $pkgconf::target_data($target,alias) { | |
| 1383 if { [string toupper $alias] == [string toupper $name] } { | |
| 1384 return $target | |
| 1385 } | |
| 1386 } | |
| 1387 } | |
| 1388 | |
| 1389 return "" | |
| 1390 } | |
| 1391 | |
| 1392 # | |
| 1393 # Ditto but for a given platform name. The target name must be known already. | |
| 1394 # | |
| 1395 | |
| 1396 proc pkgconf::find_platform { target name } { | |
| 1397 | |
| 1398 pkgconf::ASSERT { [lsearch -exact $pkgconf::known_targets $target] != -1 } | |
| 1399 | |
| 1400 foreach platform $pkgconf::target_data($target,known_platforms) { | |
| 1401 | |
| 1402 if { [string toupper $platform] == [string toupper $name] } { | |
| 1403 return $platform | |
| 1404 } | |
| 1405 | |
| 1406 foreach alias $pkgconf::target_data($target,$platform,alias) { | |
| 1407 | |
| 1408 if { [string toupper $alias] == [string toupper $name] } { | |
| 1409 return $platform | |
| 1410 } | |
| 1411 } | |
| 1412 } | |
| 1413 return "" | |
| 1414 } | |
| 1415 | |
| 1416 # | |
| 1417 # Given a target name, return the first alias. This is useful for output | |
| 1418 # code. | |
| 1419 # | |
| 1420 proc pkgconf::get_target_alias { name } { | |
| 1421 | |
| 1422 pkgconf::ASSERT { [lsearch -exact $pkgconf::known_targets $name] != -1 } | |
| 1423 | |
| 1424 set alias [lindex $pkgconf::target_data($name,alias) 0] | |
| 1425 return $alias | |
| 1426 } | |
| 1427 | |
| 1428 # | |
| 1429 # Ditto for platforms. | |
| 1430 # | |
| 1431 proc pkgconf::get_platform_alias { target name } { | |
| 1432 | |
| 1433 pkgconf::ASSERT { [lsearch -exact $pkgconf::known_targets $target] != -1 } | |
| 1434 pkgconf::ASSERT { [lsearch -exact $pkgconf::target_data($target,known_platforms) $name] != -1 } | |
| 1435 | |
| 1436 set alias [lindex $pkgconf::target_data($target,$name,alias) 0] | |
| 1437 return $alias | |
| 1438 } | |
| 1439 | |
| 1440 # | |
| 1441 # For a given target and platform, return an appropriate set of compiler flags. | |
| 1442 # | |
| 1443 proc pkgconf::get_platform_cflags { target platform flag } { | |
| 1444 | |
| 1445 ASSERT { [lsearch -exact $pkgconf::known_targets $target] != -1 } | |
| 1446 ASSERT { [lsearch -exact $pkgconf::target_data($target,known_platforms) $platform] != -1 } | |
| 1447 ASSERT { [lsearch -exact $pkgconf::known_compiler_flags $flag] != -1 } | |
| 1448 | |
| 1449 # A particular flag may be defined specifically for a platform. | |
| 1450 # Or it may come from the target information. Or there may not be | |
| 1451 # a default value. | |
| 1452 if { [info exists pkgconf::target_data($target,$platform,cflags,$flag)] != 0 } { | |
| 1453 return $pkgconf::target_data($target,$platform,cflags,$flag) | |
| 1454 } elseif { [info exists pkgconf::target_data($target,cflags,$flag)] != 0 } { | |
| 1455 return $pkgconf::target_data($target,cflags,$flag) | |
| 1456 } else { | |
| 1457 return "" | |
| 1458 } | |
| 1459 } | |
| 1460 | |
| 1461 # | |
| 1462 # Is a given target or platform actually valid ? This code copes | |
| 1463 # with aliases as well. | |
| 1464 proc pkgconf::is_target { name } { | |
| 1465 | |
| 1466 ASSERT { $name != "" } | |
| 1467 | |
| 1468 set name [find_target $name] | |
| 1469 set result 0 | |
| 1470 if { $name != "" } { | |
| 1471 set result 1 | |
| 1472 } | |
| 1473 return $result | |
| 1474 } | |
| 1475 | |
| 1476 proc pkgconf::is_platform { target name } { | |
| 1477 | |
| 1478 ASSERT { $target != "" } | |
| 1479 ASSERT { $name != "" } | |
| 1480 | |
| 1481 set target [find_target $target] | |
| 1482 ASSERT { $target != "" } | |
| 1483 | |
| 1484 set name [find_platform $target $name] | |
| 1485 set result 0 | |
| 1486 if { $name != "" } { | |
| 1487 set result 1 | |
| 1488 } | |
| 1489 return $result | |
| 1490 } | |
| 1491 | |
| 1492 proc pkgconf::is_startup { target platform name } { | |
| 1493 | |
| 1494 ASSERT { $target != "" } | |
| 1495 ASSERT { $name != "" } | |
| 1496 | |
| 1497 set target [find_target $target] | |
| 1498 ASSERT { $target != "" } | |
| 1499 | |
| 1500 set platform [find_platform $target $platform] | |
| 1501 ASSERT { $platform != "" } | |
| 1502 | |
| 1503 set index [lsearch -exact $pkgconf::target_data($target,$platform,startup) $name] | |
| 1504 set result 0 | |
| 1505 if { $index != -1 } { | |
| 1506 set result 1 | |
| 1507 } | |
| 1508 return $result | |
| 1509 } | |
| 1510 | |
| 1511 # | |
| 1512 # Get hold of the default platform and startup for a given target. | |
| 1513 | |
| 1514 proc pkgconf::get_default_platform { target } { | |
| 1515 | |
| 1516 ASSERT { $target != "" } | |
| 1517 | |
| 1518 set target [find_target $target] | |
| 1519 ASSERT { $target != "" } | |
| 1520 | |
| 1521 set platform [lindex $pkgconf::target_data($target,known_platforms) 0] | |
| 1522 return $platform | |
| 1523 } | |
| 1524 | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1525 proc pkgconf::get_base_platform { target platform } { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1526 |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1527 ASSERT { $target != "" } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1528 ASSERT { $platform != "" } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1529 |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1530 set target [find_target $target] |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1531 ASSERT { $target != "" } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1532 set platform [find_platform $target $platform] |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1533 ASSERT { $platform != "" } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1534 |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1535 if [info exists pkgconf::target_data($target,$platform,base_platform) ] { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1536 set base_platform [lindex $pkgconf::target_data($target,$platform,base_platform) 0] |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1537 } else { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1538 set base_platform $platform |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1539 } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1540 return $base_platform |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1541 } |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1542 |
| 0 | 1543 proc pkgconf::get_default_startup { target platform } { |
| 1544 | |
| 1545 ASSERT { $target != "" } | |
| 1546 ASSERT { $platform != "" } | |
| 1547 | |
| 1548 set target [find_target $target] | |
| 1549 ASSERT { $target != "" } | |
| 1550 set platform [find_platform $target $platform] | |
| 1551 ASSERT { $platform != "" } | |
| 1552 | |
| 1553 set startup [lindex $pkgconf::target_data($target,$platform,startup) 0] | |
| 1554 return $startup | |
| 1555 } | |
| 1556 | |
| 1557 # }}} | |
| 1558 # {{{ Configuration Data | |
| 1559 | |
| 1560 # {{{ setup_defaults | |
| 1561 | |
| 1562 # ---------------------------------------------------------------------------- | |
| 1563 # The setup_defaults routine is responsible for deciding on default values. | |
| 1564 # If there is only one supported architecture then this can be selected, | |
| 1565 # and then it is also possible to select a platform and a startup mode. | |
| 1566 # All known packages can be enabled by default, and the latest version | |
| 1567 # of each package can be selected. | |
| 1568 # | |
| 1569 # All configuration data is held in the array config_data(). It is | |
| 1570 # important to make sure that all fields are initialised. | |
| 1571 # | |
| 1572 | |
| 1573 proc pkgconf::setup_defaults { } { | |
| 1574 | |
| 1575 ASSERT { [llength [array names pkgconf::config_data] ] == 0 } | |
| 1576 ASSERT { $pkgconf::known_packages != "" } | |
| 1577 ASSERT { $pkgconf::known_targets != "" } | |
| 1578 ASSERT { $pkgconf::build_tree != "" } | |
| 1579 | |
| 1580 set pkgconf::config_data(target) "" | |
| 1581 set pkgconf::config_data(platform) "" | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1582 set pkgconf::config_data(base_platform) "" |
| 0 | 1583 set pkgconf::config_data(startup) "" |
| 1584 set pkgconf::config_data(prefix) "" | |
| 1585 set pkgconf::config_data(use_links) 0 | |
| 1586 | |
| 1587 # Packages fall into a number of different categories. | |
| 1588 # | |
| 1589 # 1) some packages are hardware-specific. They should be enabled | |
| 1590 # by default if that hardware has been selected, but the user | |
| 1591 # must still be able to disable them in case they cause problems. | |
| 1592 # | |
| 1593 # 2) some packages are enabled by default, but can be disabled by | |
| 1594 # the user. There are actually some packages that should never | |
| 1595 # be disabled, especially infra, but that would complicate things. | |
| 1596 # | |
| 1597 # 3) some packages are disabled by default, but can be enabled by | |
| 1598 # the user. | |
| 1599 # | |
| 1600 # The easiest way to track this information is to store the target | |
| 1601 # and platform data, which gives us the hardware packages, plus | |
| 1602 # separate lists of which packages are explicitly enabled or disabled. | |
| 1603 # All other information can be derived from that. | |
| 1604 set pkgconf::config_data(enabled_packages) "" | |
| 1605 set pkgconf::config_data(disabled_packages) "" | |
| 1606 | |
| 1607 # For each package fill in a default version number. | |
| 1608 foreach pkg $pkgconf::known_packages { | |
| 1609 | |
| 1610 ASSERT { $pkgconf::package_data($pkg,versions) != "" } | |
| 1611 ASSERT { [info exists pkgconf::config_data($pkg,version)] == 0 } | |
| 1612 set pkgconf::config_data($pkg,version) [lindex $pkgconf::package_data($pkg,versions) 0] | |
| 1613 } | |
| 1614 | |
| 1615 # If there is only one target architecture, default to it. Also | |
| 1616 # default to the first platform for that target and the first | |
| 1617 # startup for that platform. | |
| 1618 if { [llength $pkgconf::known_targets] == 1 } { | |
| 1619 set pkgconf::config_data(target) [lindex $pkgconf::known_targets 0] | |
| 1620 | |
| 1621 ASSERT { $pkgconf::target_data($pkgconf::config_data(target),known_platforms) != "" } | |
| 1622 set pkgconf::config_data(platform) [get_default_platform $pkgconf::config_data(target)] | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1623 set pkgconf::config_data(base_platform) [get_base_platform $pkgconf::config_data(target) $pkgconf::config_data(platform)] |
| 0 | 1624 |
| 1625 ASSERT { $pkgconf::target_data($pkgconf::config_data(target),$pkgconf::config_data(platform),startup) != "" } | |
| 1626 set pkgconf::config_data(startup) [get_default_startup $pkgconf::config_data(target) $pkgconf::config_data(platform)] | |
| 1627 } | |
| 1628 | |
| 1629 if { [info exists ::env(PKGCONF_USE_LINKS)] } { | |
| 1630 set pkgconf::config_data(use_links) 1 | |
| 1631 } | |
| 1632 | |
| 1633 if { 0 } { | |
| 1634 foreach i [array names pkgconf::config_data] { | |
| 1635 puts "pkgconf::config_data($i) : $pkgconf::config_data($i)" | |
| 1636 } | |
| 1637 exit 0 | |
| 1638 } | |
| 1639 } | |
| 1640 | |
| 1641 # }}} | |
| 1642 # {{{ read_save_file | |
| 1643 | |
| 1644 # ---------------------------------------------------------------------------- | |
| 1645 # The build tree may have a save file. The aim here is that | |
| 1646 # if the user wants to change some aspects of the configuration, e.g. to | |
| 1647 # switch between the eval board and the simulator, it should not be | |
| 1648 # necessary to pass all the command line arguments again. Instead the | |
| 1649 # system should work out past settings and re-use those where possible. | |
| 1650 # | |
| 1651 # This routine should be invoked after the defaults are set up but | |
| 1652 # before the command line arguments take effect. | |
| 1653 # | |
| 1654 # There is a command line argument --defaults which stops the saved | |
| 1655 # values from taking effect. The save file is still read in because | |
| 1656 # it is useful to know what is in the build tree at the moment. | |
| 1657 # | |
| 1658 | |
| 1659 proc pkgconf::read_save_file { } { | |
| 1660 | |
| 1661 ASSERT { $pkgconf::build_tree != "" } | |
| 1662 | |
| 1663 # Get rid of any old settings that might be hanging around. | |
| 1664 foreach i [array names pkgconf::saved_data] { | |
| 1665 unset pkgconf::saved_data($i) | |
| 1666 } | |
| 1667 | |
| 1668 set filename [file join $pkgconf::build_tree "pkgconf.sav"] | |
| 1669 if { [file exists $filename] && [file isfile $filename] } { | |
| 1670 | |
| 1671 # Read in the saved data. A safe interpreter is used, just in case. | |
| 1672 proc set_saved_data { name value } { | |
| 1673 set pkgconf::saved_data($name) $value | |
| 1674 } | |
| 1675 set parser [interp create -safe] | |
| 1676 $parser alias set_saved_data pkgconf::set_saved_data | |
| 1677 | |
| 1678 set status [ catch { | |
| 1679 set fd [open $filename r] | |
| 1680 set script [read $fd] | |
| 1681 close $fd | |
| 1682 $parser eval $script | |
| 1683 } message] | |
| 1684 if { $status != 0 } { | |
| 1685 pkgconf::fatal_error "Unexpected error while reading back save file $filename\n$message" | |
| 1686 } | |
| 1687 | |
| 1688 rename set_saved_data {} | |
| 1689 interp delete $parser | |
| 1690 } | |
| 1691 | |
| 1692 # It is a good idea to check that the data read back is consistent. | |
| 1693 # It is also a good idea to check some aliases, in case something | |
| 1694 # has been renamed between releases. | |
| 1695 if { [info exists pkgconf::saved_data(target)] } { | |
| 1696 | |
| 1697 set target_name [find_target $pkgconf::saved_data(target)] | |
| 1698 if { $target_name == "" } { | |
| 1699 warning "The save file $filename contained an invalid target $pkgconf::saved_data(target). This has been ignored." | |
| 1700 } else { | |
| 1701 set pkgconf::saved_data(target) $target_name | |
| 1702 set pkgconf::config_data(target) $target_name | |
| 1703 set pkgconf::config_data(platform) [get_default_platform $pkgconf::config_data(target)] | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1704 set pkgconf::config_data(base_platform) [get_base_platform $pkgconf::config_data(target) $pkgconf::config_data(platform)] |
| 0 | 1705 set pkgconf::config_data(startup) \ |
| 1706 [get_default_startup $pkgconf::config_data(target) $pkgconf::config_data(platform)] | |
| 1707 } | |
| 1708 } | |
| 1709 | |
| 1710 # There is no point in validating platform or startup unless the target is known. | |
| 1711 if { $pkgconf::config_data(target) != "" } { | |
| 1712 | |
| 1713 ASSERT { $pkgconf::target_data($pkgconf::config_data(target),known_platforms) != "" } | |
| 1714 | |
| 1715 if { [info exists pkgconf::saved_data(platform)] } { | |
| 1716 | |
| 1717 set platform_name [find_platform $pkgconf::config_data(target) $pkgconf::saved_data(platform)] | |
| 1718 if { $platform_name == "" } { | |
| 1719 warning \ | |
| 1720 "The save file $filename specified an unknown platform $pkgconf::saved_data(platform).\ | |
| 1721 The platform $pkgconf::config_data(platform) has been substituted." | |
| 1722 } else { | |
| 1723 set pkgconf::saved_data(platform) $platform_name | |
| 1724 set pkgconf::config_data(platform) $platform_name | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1725 set pkgconf::config_data(base_platform) [get_base_platform $pkgconf::config_data(target) $pkgconf::saved_data(platform)] |
| 0 | 1726 set pkgconf::config_data(startup) [get_default_startup $pkgconf::config_data(target) $platform_name] |
| 1727 } | |
| 1728 | |
| 1729 } | |
| 1730 | |
| 1731 # Currently if there is a target then there is always a platform, | |
| 1732 # possibly the default one. | |
| 1733 ASSERT { $pkgconf::target_data($pkgconf::config_data(target),$pkgconf::config_data(platform),startup) != "" } | |
| 1734 | |
| 1735 if { [info exists pkgconf::saved_data(startup)] } { | |
| 1736 | |
| 1737 if { [is_startup $pkgconf::config_data(target) $pkgconf::config_data(platform) $pkgconf::saved_data(startup)] \ | |
| 1738 == 0 } { | |
| 1739 warning \ | |
| 1740 "The save file $filename specified an unknown startup $pkgconf::saved_data(startup).\ | |
| 1741 $pkgconf::config_data(startup) startup has been substituted." | |
| 1742 } else { | |
| 1743 set pkgconf::config_data(startup) $pkgconf::saved_data(startup) | |
| 1744 } | |
| 1745 } | |
| 1746 } | |
| 1747 | |
| 1748 # There should be an entry listing all packages for which there is | |
| 1749 # a version entry. This can be used to update the version numbers | |
| 1750 # which should be used in this configuration. | |
| 1751 if { [info exists pkgconf::saved_data(versioned_packages) ] != 0 } { | |
| 1752 foreach pkg $pkgconf::saved_data(versioned_packages) { | |
| 1753 | |
| 1754 # Check that there is a saved version string for this package. | |
| 1755 # There should be, but it is not worth worrying about. | |
| 1756 if { [info exists pkgconf::saved_data($pkg,version)] == 0 } { | |
| 1757 continue | |
| 1758 } | |
| 1759 set version $pkgconf::saved_data($pkg,version) | |
| 1760 | |
| 1761 # Does this package still exist ? | |
| 1762 if { [is_package $pkg] == 0 } { | |
| 1763 warning \ | |
| 1764 "The save file $filename specified version $version for package $pkg.\ | |
| 1765 This package does not exist in the current repository, so the version string\ | |
| 1766 has been ignored." | |
| 1767 continue | |
| 1768 } | |
| 1769 set pkg [find_package $pkg] | |
| 1770 ASSERT { $pkg != "" } | |
| 1771 | |
| 1772 # Is the version valid ? | |
| 1773 if { [is_valid_version $pkg $version] == 0 } { | |
| 1774 warning \ | |
| 1775 "The save file $filename specified version $version for package $pkg.\ | |
| 1776 This version is not present in the current repository so the version\ | |
| 1777 string has been ignored." | |
| 1778 } else { | |
| 1779 set pkgconf::config_data($pkg,version) $version | |
| 1780 } | |
| 1781 } | |
| 1782 } | |
| 1783 | |
| 1784 # Now check that all the packages listed in the save file are known. | |
| 1785 # If any are missing then they are just discarded. Known packages | |
| 1786 # are used to update the appropriate current configuration data. | |
| 1787 if { [info exists pkgconf::saved_data(enabled_packages)] == 0 } { | |
| 1788 set pkgconf::saved_data(enabled_packages) "" | |
| 1789 } | |
| 1790 if { [info exists pkgconf::saved_data(disabled_packages)] == 0 } { | |
| 1791 set pkgconf::saved_data(disabled_packages) "" | |
| 1792 } | |
| 1793 | |
| 1794 foreach pkg $pkgconf::saved_data(enabled_packages) { | |
| 1795 | |
| 1796 if { [is_package $pkg] == 0 } { | |
| 1797 warning \ | |
| 1798 "The save file $filename mentioned a package $pkg.\ | |
| 1799 This package does not exist in the current repository and | |
| 1800 has been ignored." | |
| 1801 continue | |
| 1802 } | |
| 1803 | |
| 1804 set pkg [find_package $pkg] | |
| 1805 set index [lsearch -exact $pkgconf::config_data(enabled_packages) $pkg] | |
| 1806 if { $index == -1 } { | |
| 1807 lappend pkgconf::config_data(enabled_packages) $pkg | |
| 1808 } | |
| 1809 } | |
| 1810 | |
| 1811 foreach pkg $pkgconf::saved_data(disabled_packages) { | |
| 1812 | |
| 1813 if { [is_package $pkg] == 0 } { | |
| 1814 warning \ | |
| 1815 "The save file $filename mentioned a package $pkg.\ | |
| 1816 This package does not exist in the current repository and | |
| 1817 has been ignored." | |
| 1818 continue | |
| 1819 } | |
| 1820 | |
| 1821 set pkg [find_package $pkg] | |
| 1822 set index [lsearch -exact $pkgconf::config_data(disabled_packages) $pkg] | |
| 1823 if { $index == -1 } { | |
| 1824 lappend pkgconf::config_data(disabled_packages) $pkg | |
| 1825 } | |
| 1826 | |
| 1827 # Better make sure that a package is not simultaneously enabled and disabled. | |
| 1828 set index [lsearch -exact $pkgconf::config_data(enabled_packages) $pkg] | |
| 1829 if { $index != -1 } { | |
| 1830 set pkgconf::config_data(enabled_packages) [lreplace $pkgconf::config_data(enabled_packages) $index $index] | |
| 1831 } | |
| 1832 } | |
| 1833 | |
| 1834 # Now check for any compiler flags | |
| 1835 foreach flag $pkgconf::known_compiler_flags { | |
| 1836 if { [info exists pkgconf::saved_data(cflags,$flag)] } { | |
| 1837 set pkgconf::config_data(cflags,$flag) $pkgconf::saved_data(cflags,$flag) | |
| 1838 } | |
| 1839 } | |
| 1840 | |
| 1841 # Update the install directory if appropriate. | |
| 1842 # There is not a lot of checking that can be done here. | |
| 1843 if { [info exists pkgconf::saved_data(prefix) ] } { | |
| 1844 set pkgconf::config_data(prefix) $pkgconf::saved_data(prefix) | |
| 1845 } | |
| 1846 | |
| 1847 # And check for the use_links option | |
| 1848 if { [info exists pkgconf::saved_data(use_links)] } { | |
| 1849 set pkgconf::config_data(use_links) $pkgconf::saved_data(use_links) | |
| 1850 } | |
| 1851 | |
| 1852 # Now, possibly undo all of this if the user specified --defaults. | |
| 1853 if { $pkgconf::defaults_arg != 0 } { | |
| 1854 foreach entry [array names pkgconf::config_data] { | |
| 1855 unset pkgconf::config_data($entry) | |
| 1856 } | |
| 1857 setup_defaults | |
| 1858 } | |
| 1859 | |
| 1860 if { 0 } { | |
| 1861 foreach i [array names pkgconf::config_data] { | |
| 1862 puts "pkgconf::config_data($i) : $pkgconf::config_data($i)" | |
| 1863 } | |
| 1864 exit 0 | |
| 1865 } | |
| 1866 } | |
| 1867 | |
| 1868 # }}} | |
| 1869 # {{{ write_save_file | |
| 1870 | |
| 1871 # ---------------------------------------------------------------------------- | |
| 1872 # Outputting the save file. This is a relatively simple operation assuming | |
| 1873 # no file I/O errors happen. The saved_data array is updated with the new | |
| 1874 # contents of the save file. It is not yet clear whether this will be useful, | |
| 1875 # but it should not cause any problems either. | |
| 1876 # | |
| 1877 | |
| 1878 proc pkgconf::write_save_file { } { | |
| 1879 | |
| 1880 # Check for minimal consistency. If any variables are missing then | |
| 1881 # this will be handled (poorly) by the catch statement. | |
| 1882 ASSERT { [info exists pkgconf::config_data(target)] } | |
| 1883 ASSERT { $pkgconf::build_tree != "" } | |
| 1884 | |
| 1885 set savename [file join $pkgconf::build_tree "pkgconf.sav"] | |
| 1886 set open_file "" | |
| 1887 | |
| 1888 set status [catch { | |
| 1889 | |
| 1890 set open_file [open $savename w] | |
| 1891 output_banner $open_file "pkgconf.sav" | |
| 1892 | |
| 1893 if { $pkgconf::config_data(target) != "" } { | |
| 1894 puts $open_file "set_saved_data target $pkgconf::config_data(target)" | |
| 1895 set pkgconf::saved_data(target) $pkgconf::config_data(target) | |
| 1896 } | |
| 1897 if { $pkgconf::config_data(platform) != "" } { | |
| 1898 puts $open_file "set_saved_data platform $pkgconf::config_data(platform)" | |
| 1899 set pkgconf::saved_data(platform) $pkgconf::config_data(platform) | |
| 1900 } | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1901 if { $pkgconf::config_data(base_platform) != "" } { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1902 puts $open_file "set_saved_data base_platform $pkgconf::config_data(base_platform)" |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1903 set pkgconf::saved_data(base_platform) $pkgconf::config_data(base_platform) |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
1904 } |
| 0 | 1905 if { $pkgconf::config_data(startup) != "" } { |
| 1906 puts $open_file "set_saved_data startup $pkgconf::config_data(startup)" | |
| 1907 set pkgconf::saved_data(startup) $pkgconf::config_data(startup) | |
| 1908 } | |
| 1909 if { $pkgconf::config_data(enabled_packages) != "" } { | |
| 1910 # The use of the list command here avoids problems with multiple | |
| 1911 # arguments when the file is read back. | |
| 1912 puts $open_file "set_saved_data enabled_packages [list $pkgconf::config_data(enabled_packages)]" | |
| 1913 set pkgconf::saved_data(enabled_packages) $pkgconf::config_data(enabled_packages) | |
| 1914 } | |
| 1915 if { $pkgconf::config_data(disabled_packages) != "" } { | |
| 1916 puts $open_file "set_saved_data disabled_packages [list $pkgconf::config_data(disabled_packages)]" | |
| 1917 set pkgconf::saved_data(disabled_packages) $pkgconf::config_data(disabled_packages) | |
| 1918 } | |
| 1919 foreach pkg $pkgconf::known_packages { | |
| 1920 ASSERT { [info exists pkgconf::config_data($pkg,version)] } | |
| 1921 puts $open_file "set_saved_data \"$pkg,version\" $pkgconf::config_data($pkg,version)" | |
| 1922 set pkgconf::saved_data($pkg,version) $pkgconf::config_data($pkg,version) | |
| 1923 } | |
| 1924 # This allows the versions to be read back in more easily, even if | |
| 1925 # there is a change to the number of packages. | |
| 1926 puts $open_file "set_saved_data versioned_packages [list $pkgconf::known_packages]" | |
| 1927 | |
| 1928 foreach flag $pkgconf::known_compiler_flags { | |
| 1929 if { [info exists pkgconf::config_data(cflags,$flag)] != 0 } { | |
| 1930 puts $open_file "set_saved_data \"cflags,$flag\" \"$pkgconf::config_data(cflags,$flag)\"" | |
| 1931 } | |
| 1932 } | |
| 1933 if { $pkgconf::config_data(use_links) != 0 } { | |
| 1934 puts $open_file "set_saved_data use_links 1" | |
| 1935 } | |
| 1936 | |
| 1937 puts $open_file "set_saved_data prefix \"$pkgconf::config_data(prefix)\"" | |
| 1938 set pkgconf::saved_data(prefix) $pkgconf::config_data(prefix) | |
| 1939 | |
| 1940 puts $open_file "\n# End of $savename" | |
| 1941 close $open_file | |
| 1942 } message ] | |
| 1943 | |
| 1944 if { $status != 0 } { | |
| 1945 | |
| 1946 if { $open_file != "" } { | |
| 1947 # Whatever error occurred, it happened after the file was opened. | |
| 1948 # This is bad news, the file may be corrupt. To avoid complications, | |
| 1949 # try to delete it. | |
| 1950 catch { | |
| 1951 close $open_file | |
| 1952 file delete $savename | |
| 1953 } | |
| 1954 # Also get rid of the saved_data array. | |
| 1955 foreach i [array names saved_data] { | |
| 1956 unset saved_data($i) | |
| 1957 } | |
| 1958 } | |
| 1959 fatal_error "An unexpected error occurred while generating the save file $savename: $message" | |
| 1960 } | |
| 1961 } | |
| 1962 | |
| 1963 # }}} | |
| 1964 # {{{ process_arguments() | |
| 1965 | |
| 1966 # ---------------------------------------------------------------------------- | |
| 1967 # This procedure takes care of updating the configuration information using | |
| 1968 # the command line arguments, for example if there was an argument specifying | |
| 1969 # a different version for a particular package then it is this procedure | |
| 1970 # which takes care of it. This procedure also takes care of validating the | |
| 1971 # arguments. | |
| 1972 # | |
| 1973 # This procedure should be invoked after setup_defaults has filled in the | |
| 1974 # default values for all configuration data, and after read_save_file | |
| 1975 # has updated them with saved data. | |
| 1976 # | |
| 1977 # There is a separate validation routine which gets invoked first. | |
| 1978 # This takes care of serious errors in the command line arguments. | |
| 1979 # | |
| 1980 | |
| 1981 proc pkgconf::process_arguments { } { | |
| 1982 | |
| 1983 variable known_compiler_flags | |
| 1984 variable known_packages | |
| 1985 variable package_data | |
| 1986 variable known_targets | |
| 1987 variable target_data | |
| 1988 | |
| 1989 variable config_data | |
| 1990 variable target_arg | |
| 1991 variable platform_arg | |
| 1992 variable startup_arg | |
| 1993 variable prefix_arg | |
| 1994 variable disable_args | |
| 1995 variable enable_args | |
| 1996 variable version_args | |
| 1997 variable use_links_arg | |
| 1998 variable use_copies_arg | |
| 1999 variable cflags_args | |
| 2000 | |
| 2001 # Constructing the file name strings here facilitates generating | |
| 2002 # error messages. | |
| 2003 set packages_file [file join $pkgconf::component_repository "packages"] | |
| 2004 set targets_file [file join $pkgconf::component_repository "targets"] | |
| 2005 | |
| 2006 # The target, platform, and startup values are used throughout so it | |
| 2007 # is convenient to have locals. | |
| 2008 set target $pkgconf::config_data(target) | |
| 2009 set platform $pkgconf::config_data(platform) | |
| 2010 set startup $pkgconf::config_data(startup) | |
| 2011 | |
| 2012 # Start by validating the --target argument This target must | |
| 2013 # be present in the known_targets list. If it is then the | |
| 2014 # target architecture can be updated. | |
| 2015 | |
| 2016 if { $pkgconf::target_arg != "" } { | |
| 2017 | |
| 2018 set target [find_target $pkgconf::target_arg] | |
| 2019 if { $target == "" } { | |
| 2020 fatal_error "Invalid argument --target=$target_arg, this target is not listed in $targets_file" | |
| 2021 } | |
| 2022 set pkgconf::config_data(target) $target | |
| 2023 | |
| 2024 # It is possible that the platform and startup data from the save file | |
| 2025 # are no longer valid because of a change in the target. If so then the | |
| 2026 # relevant fields have to be cleared. | |
| 2027 if { $platform != "" } { | |
| 2028 set platform [find_platform $target $platform] | |
| 2029 set pkgconf::config_data(platform) $platform | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
2030 set pkgconf::config_data(base_platform) [get_base_platform $target $platform] |
| 0 | 2031 if { ($platform != "") && ($startup != "") } { |
| 2032 if { [lsearch -exact $pkgconf::target_data($target,$platform,startup) $startup] == -1 } { | |
| 2033 set startup "" | |
| 2034 set pkgconf::config_data(startup) "" | |
| 2035 } | |
| 2036 } | |
| 2037 } | |
| 2038 | |
| 2039 # Next, if the platform and startup are not currently known then | |
| 2040 # it is possible to set up defaults for this target. | |
| 2041 if { $platform == "" } { | |
| 2042 set platform [lindex $pkgconf::target_data($target,known_platforms) 0] | |
| 2043 set pkgconf::config_data(platform) $platform | |
| 2044 } | |
| 2045 if { $startup == "" } { | |
| 2046 set startup [lindex $pkgconf::target_data($target,$platform,startup) 0] | |
| 2047 set pkgconf::config_data(startup) $startup | |
| 2048 } | |
| 2049 } | |
| 2050 | |
| 2051 # If the target is known then it is possible to verify platform and startup | |
| 2052 # arguments. Without a target these arguments are meaningless. | |
| 2053 | |
| 2054 if { ($target != "") && ($pkgconf::platform_arg != "") } { | |
| 2055 | |
| 2056 set platform [find_platform $target $pkgconf::platform_arg] | |
| 2057 if { $platform == "" } { | |
| 2058 fatal_error "Invalid argument --platform=$pkgconf::platform_arg, this platform is not listed in $targets_file" | |
| 2059 } | |
| 2060 set pkgconf::config_data(platform) $platform | |
| 2061 } | |
| 2062 | |
|
14
01ce82f3e11a
Merge from eCos master repository on 1999-06-11-17:05:41-BST
jlarmour
parents:
12
diff
changeset
|
2063 if { ($target != "") && ($platform != "") } { |
|
01ce82f3e11a
Merge from eCos master repository on 1999-06-11-17:05:41-BST
jlarmour
parents:
12
diff
changeset
|
2064 set pkgconf::config_data(base_platform) [get_base_platform $target $platform] |
|
01ce82f3e11a
Merge from eCos master repository on 1999-06-11-17:05:41-BST
jlarmour
parents:
12
diff
changeset
|
2065 } |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
2066 |
| 0 | 2067 if { ($target != "") && ($platform != "") && ($pkgconf::startup_arg != "" ) } { |
| 2068 | |
| 2069 if { [lsearch -exact $pkgconf::target_data($target,$platform,startup) $pkgconf::startup_arg] == -1 } { | |
| 2070 fatal_error "Invalid argument --startup=$startup_arg, this startup is not listed in $targets_file" | |
| 2071 } | |
| 2072 set startup $pkgconf::startup_arg | |
| 2073 set config_data(startup) $startup | |
| 2074 } | |
| 2075 | |
| 2076 # It is not really possible to validate the prefix argument. | |
| 2077 if { $pkgconf::prefix_arg != "" } { | |
| 2078 set pkgconf::config_data(prefix) $pkgconf::prefix_arg | |
| 2079 } | |
| 2080 | |
| 2081 # Cope with the use of symbolic links vs. copies | |
| 2082 if { $pkgconf::use_links_arg } { | |
| 2083 set pkgconf::config_data(use_links) 1 | |
| 2084 } | |
| 2085 if { $pkgconf::use_copies_arg } { | |
| 2086 set pkgconf::config_data(use_links) 0 | |
| 2087 } | |
| 2088 | |
| 2089 # For each package that is being disabled, make sure it is on the | |
| 2090 # list of disabled packages and not on the list of enabled packages. | |
| 2091 # The former operation is actually unnecessary if the package is | |
| 2092 # disabled by default, but harmless. | |
| 2093 foreach pkg $pkgconf::disable_args { | |
| 2094 set match [find_package $pkg] | |
| 2095 if { $match == "" } { | |
| 2096 fatal_error "Invalid argument --disable-$pkg, package $pkg is not listed in $packages_file." | |
| 2097 } | |
| 2098 | |
| 2099 set index [lsearch -exact $pkgconf::config_data(enabled_packages) $match] | |
| 2100 if { $index != -1 } { | |
| 2101 set pkgconf::config_data(enabled_packages) [lreplace $pkgconf::config_data(enabled_packages) $index $index] | |
| 2102 } | |
| 2103 set index [lsearch -exact $pkgconf::config_data(disabled_packages) $match] | |
| 2104 if { $index == -1 } { | |
| 2105 lappend pkgconf::config_data(disabled_packages) $match | |
| 2106 } | |
| 2107 } | |
| 2108 | |
| 2109 # For each package that should be enabled, add it to the list of enabled | |
| 2110 # packages and remove it from the list of disabled packages. Again the | |
| 2111 # former is actually unnecessary if the package is enabled by default. | |
| 2112 foreach pkg $pkgconf::enable_args { | |
| 2113 set match [find_package $pkg] | |
| 2114 if { $match == "" } { | |
| 2115 fatal_error "Invalid argument --enable-$pkg, package $pkg is not listed in $packages_file." | |
| 2116 } | |
| 2117 | |
| 2118 set index [lsearch -exact $pkgconf::config_data(disabled_packages) $match] | |
| 2119 if { $index != -1 } { | |
| 2120 set pkgconf::config_data(disabled_packages) [lreplace $pkgconf::config_data(disabled_packages) $index $index] | |
| 2121 } | |
| 2122 set index [lsearch -exact $pkgconf::config_data(enabled_packages) $match] | |
| 2123 if { $index == -1 } { | |
| 2124 lappend config_data(enabled_packages) $match | |
| 2125 } | |
| 2126 } | |
| 2127 | |
| 2128 # For each package where a version has been specified, validate this | |
| 2129 # version and use it. Also make sure that the package is enabled. | |
| 2130 foreach pkg [array names pkgconf::version_args] { | |
| 2131 | |
| 2132 set match [find_package $pkg] | |
| 2133 if { $match == "" } { | |
| 2134 fatal_error "Invalid argument --$pkg-version, package $pkg is not listed in $packages_file." | |
| 2135 } | |
| 2136 if { [lsearch -exact $pkgconf::package_data($match,versions) $pkgconf::version_args($pkg)] == -1 } { | |
| 2137 fatal_error "Invalid argument --$pkg-version=$pkgconf::version_args($pkg), that version is not available." | |
| 2138 } | |
| 2139 set pkgconf::config_data($match,version) $pkgconf::version_args($pkg) | |
| 2140 | |
| 2141 set index [lsearch -exact $pkgconf::config_data(disabled_packages) $match] | |
| 2142 if { $index != -1 } { | |
| 2143 set pkgconf::config_data(disabled_packages) [lreplace $pkgconf::config_data(disabled_packages) $index $index] | |
| 2144 } | |
| 2145 if { ($pkgconf::package_data($match,hardware) == 1) || ($pkgconf::package_data($match,default) == 0) } { | |
| 2146 set index [lsearch -exact $pkgconf::config_data(enabled_packages) $match] | |
| 2147 if { $index == -1 } { | |
| 2148 lappend config_data(enabled_packages) $match | |
| 2149 } | |
| 2150 } | |
| 2151 } | |
| 2152 | |
| 2153 # For each compiler flag that has been specified explicitly on the command line, | |
| 2154 # store it in the configuration data | |
| 2155 foreach flag [array names pkgconf::cflags_args] { | |
| 2156 set pkgconf::config_data(cflags,$flag) $pkgconf::cflags_args($flag) | |
| 2157 } | |
| 2158 } | |
| 2159 | |
| 2160 # }}} | |
| 2161 # {{{ reset_data() | |
| 2162 | |
| 2163 # ---------------------------------------------------------------------------- | |
| 2164 # This routine gets rid of all data. It can be used if the script is | |
| 2165 # switching from one configuration to a different one. | |
| 2166 # | |
| 2167 proc pkgconf::reset_data { } { | |
| 2168 | |
| 2169 foreach i [array names pkgconf::config_data] { | |
| 2170 unset pkgconf::config_data($i) | |
| 2171 } | |
| 2172 foreach i [array names pkgconf::saved_data] { | |
| 2173 unset pkgconf::saved_data($i) | |
| 2174 } | |
| 2175 } | |
| 2176 | |
| 2177 # }}} | |
| 2178 | |
| 2179 # }}} | |
| 2180 # {{{ GUI | |
| 2181 | |
| 2182 # {{{ GUI variables | |
| 2183 | |
| 2184 namespace eval pkgconf { | |
| 2185 | |
| 2186 namespace export gui | |
| 2187 | |
| 2188 # Which editor should be used for fine-grained configuration options ? | |
| 2189 # The VISUAL environment variable is the correct way to obtain this | |
| 2190 # information on Unix operating systems. Windows machines do not | |
| 2191 # seem to have an obvious equivalent. | |
| 2192 variable editor "" | |
| 2193 if { [info exists ::env(VISUAL)] } { | |
| 2194 set editor $::env(VISUAL) | |
| 2195 } | |
| 2196 | |
| 2197 # The names of the pages in the notebook. These names are | |
| 2198 # invented by the notebook widget. | |
| 2199 variable target_frame "" | |
| 2200 variable packages_frame "" | |
| 2201 variable options_frame "" | |
| 2202 variable flags_frame "" | |
| 2203 variable build_frame "" | |
| 2204 | |
| 2205 # It is convenient to keep track of whether or not certain information | |
| 2206 # has changed. This simplifies the task of deciding whether or not | |
| 2207 # a page in the notebook needs redrawing. | |
| 2208 # | |
| 2209 # Note: currently if the user makes a change and then undoes that | |
| 2210 # change the variable remains set. It is possible to get around this, | |
| 2211 # but that would require a bit more work. | |
| 2212 variable packages_page_needs_refresh 0 | |
| 2213 variable options_page_needs_refresh 0 | |
| 2214 variable build_page_needs_refresh 0 | |
| 2215 | |
| 2216 # Is it currently possible to do a build, or is it necessary to | |
| 2217 # update the build tree first. | |
| 2218 variable build_tree_needs_update 0 | |
| 2219 | |
| 2220 # Each notebook page is given its own array of global data. | |
| 2221 array set target_page_data {}; | |
| 2222 array set packages_page_data {}; | |
| 2223 array set options_page_data {}; | |
| 2224 array set flags_page_data {}; | |
| 2225 array set build_page_data {}; | |
| 2226 | |
| 2227 # The state of the build output window. There are two flags to consider: | |
| 2228 # whether the output window is visible or not; and whether the output | |
| 2229 # window is docked or not. | |
| 2230 variable output_docked 1 | |
| 2231 variable output_visible 0 | |
| 2232 | |
| 2233 # For gui mode, what is the name of the toplevel window ? | |
| 2234 # If this script is embedded in a larger application then it can | |
| 2235 # be made to run inside a frame in that window. | |
| 2236 namespace export set_toplevel_window | |
| 2237 variable toplevel ".pkgconf" | |
| 2238 } | |
| 2239 | |
| 2240 # }}} | |
| 2241 # {{{ Effective Tcl support | |
| 2242 | |
| 2243 # ---------------------------------------------------------------------------- | |
| 2244 # For now the intention is to allow this script to be run from a completely | |
| 2245 # standard wish or tclsh interpreter, version 8.0 or later. This means it is | |
| 2246 # not possible to use extensions such as TIX or ITCL. However in the GUI | |
| 2247 # it is still desirable to have a notebook widget, so here is an | |
| 2248 # implementation in vanilla TK. The balloon widget from the same source | |
| 2249 # is used as well. | |
| 2250 # | |
| 2251 # The code derives from the book Effective Tcl/Tk programming by Mark | |
| 2252 # Harrison and Michael McLennan. The actual source code was obtained from | |
| 2253 # the Addison-Wesley web site and contains the following copyright. | |
| 2254 # | |
| 2255 # This distribution contains examples from the "Effective Tcl/Tk | |
| 2256 # Programming" book. You can study these examples as you read | |
| 2257 # through the book, and you can steal the code for your own | |
| 2258 # applications! | |
| 2259 # | |
| 2260 # | |
| 2261 # The code is enclosed in a separate namespace. Also I have modified | |
| 2262 # the code in a number of places to make it more general-purpose. | |
| 2263 # | |
| 2264 namespace eval pkgconf::efftcl { | |
| 2265 | |
| 2266 # ---------------------------------------------------------------------- | |
| 2267 # EXAMPLE: tabnotebook that can dial up pages | |
| 2268 # ---------------------------------------------------------------------- | |
| 2269 # Effective Tcl/Tk Programming | |
| 2270 # Mark Harrison, DSC Communications Corp. | |
| 2271 # Michael McLennan, Bell Labs Innovations for Lucent Technologies | |
| 2272 # Addison-Wesley Professional Computing Series | |
| 2273 # ====================================================================== | |
| 2274 # Copyright (c) 1996-1997 Lucent Technologies Inc. and Mark Harrison | |
| 2275 # ====================================================================== | |
| 2276 | |
| 2277 # BLV fix: this script may execute in tclsh rather than in wish, | |
| 2278 # so the option command may not be available. | |
| 2279 if { [info command "option"] == "option"} { | |
| 2280 | |
| 2281 # BLV: I do not like this background colour for the tabs. | |
| 2282 if { 0 } { | |
| 2283 option add *Tabnotebook.tabs.background #666666 widgetDefault | |
| 2284 } | |
| 2285 option add *Tabnotebook.margin 6 widgetDefault | |
| 2286 option add *Tabnotebook.tabColor #a6a6a6 widgetDefault | |
| 2287 option add *Tabnotebook.activeTabColor #d9d9d9 widgetDefault | |
| 2288 option add *Tabnotebook.tabFont \ | |
| 2289 -*-helvetica-bold-r-normal--*-120-* widgetDefault | |
| 2290 } | |
| 2291 | |
| 2292 # BLV fix: replace global variables with per-namespace ones. | |
| 2293 array set tnInfo {} | |
| 2294 array set bhInfo {} | |
| 2295 | |
| 2296 proc tabnotebook_create {win} { | |
| 2297 variable tnInfo | |
| 2298 | |
| 2299 frame $win -class Tabnotebook | |
| 2300 canvas $win.tabs -highlightthickness 0 | |
| 2301 pack $win.tabs -fill x | |
| 2302 | |
| 2303 notebook_create $win.notebook | |
| 2304 pack $win.notebook -expand yes -fill both | |
| 2305 | |
| 2306 set tnInfo($win-tabs) "" | |
| 2307 set tnInfo($win-current) "" | |
| 2308 set tnInfo($win-pending) "" | |
| 2309 return $win | |
| 2310 } | |
| 2311 | |
| 2312 # | |
| 2313 # BLV fix: add three arguments, one specifying a function to be | |
| 2314 # invoked when the tab becomes visible, another for when the user | |
| 2315 # leaves the tab, and a text string for balloon help. This function can | |
| 2316 # be used to redraw a page if this is necessary due to changes in other | |
| 2317 # pages, and an empty string can be used if desired. An empty string | |
| 2318 # can also be used for the balloon help. | |
| 2319 # | |
| 2320 | |
| 2321 proc tabnotebook_page {win name enterfn leavefn help} { | |
| 2322 variable tnInfo | |
| 2323 | |
| 2324 set page [notebook_page $win.notebook $name] | |
| 2325 lappend tnInfo($win-tabs) $name | |
| 2326 set tnInfo($name-enterfn) $enterfn | |
| 2327 set tnInfo($name-leavefn) $leavefn | |
| 2328 set tnInfo($name-help) $help | |
| 2329 | |
| 2330 if {$tnInfo($win-pending) == ""} { | |
| 2331 set id [after idle [list pkgconf::efftcl::tabnotebook_refresh $win]] | |
| 2332 set tnInfo($win-pending) $id | |
| 2333 } | |
| 2334 return $page | |
| 2335 } | |
| 2336 | |
| 2337 proc tabnotebook_refresh {win} { | |
| 2338 variable tnInfo | |
| 2339 | |
| 2340 $win.tabs delete all | |
| 2341 | |
| 2342 set margin [option get $win margin Margin] | |
| 2343 set color [option get $win tabColor Color] | |
| 2344 set font [option get $win tabFont Font] | |
| 2345 set x 2 | |
| 2346 set maxh 0 | |
| 2347 | |
| 2348 foreach name $tnInfo($win-tabs) { | |
| 2349 set id [$win.tabs create text \ | |
| 2350 [expr $x+$margin+2] [expr -0.5*$margin] \ | |
| 2351 -anchor sw -text $name -font $font \ | |
| 2352 -tags [list $name]] | |
| 2353 | |
| 2354 set bbox [$win.tabs bbox $id] | |
| 2355 set wd [expr [lindex $bbox 2]-[lindex $bbox 0]] | |
| 2356 set ht [expr [lindex $bbox 3]-[lindex $bbox 1]] | |
| 2357 if {$ht > $maxh} { | |
| 2358 set maxh $ht | |
| 2359 } | |
| 2360 | |
| 2361 $win.tabs create polygon 0 0 $x 0 \ | |
| 2362 [expr $x+$margin] [expr -$ht-$margin] \ | |
| 2363 [expr $x+$margin+$wd] [expr -$ht-$margin] \ | |
| 2364 [expr $x+$wd+2*$margin] 0 \ | |
| 2365 2000 0 2000 10 0 10 \ | |
| 2366 -outline black -fill $color \ | |
| 2367 -tags [list $name tab tab-$name] | |
| 2368 | |
| 2369 $win.tabs raise $id | |
| 2370 | |
| 2371 $win.tabs bind $name <ButtonPress-1> \ | |
| 2372 [list pkgconf::efftcl::tabnotebook_display $win $name] | |
| 2373 | |
| 2374 # BLV - add support for balloon help | |
| 2375 if { $tnInfo($name-help) != "" } { | |
| 2376 balloonhelp_canvas_for $win.tabs $name $tnInfo($name-help) | |
| 2377 } | |
| 2378 set x [expr $x+$wd+2*$margin] | |
| 2379 } | |
| 2380 set height [expr $maxh+2*$margin] | |
| 2381 $win.tabs move all 0 $height | |
| 2382 | |
| 2383 $win.tabs configure -width $x -height [expr $height+4] | |
| 2384 | |
| 2385 if {$tnInfo($win-current) != ""} { | |
| 2386 tabnotebook_display $win $tnInfo($win-current) | |
| 2387 } else { | |
| 2388 tabnotebook_display $win [lindex $tnInfo($win-tabs) 0] | |
| 2389 } | |
| 2390 set tnInfo($win-pending) "" | |
| 2391 } | |
| 2392 | |
| 2393 proc tabnotebook_display {win name} { | |
| 2394 variable tnInfo | |
| 2395 variable nbInfo | |
| 2396 | |
| 2397 # BLV: invoke appropriate callbacks in the current and new | |
| 2398 # tabs. | |
| 2399 set old_tab $tnInfo($win-current) | |
| 2400 if { ($old_tab != "") && ($tnInfo($old_tab-leavefn) != "") } { | |
| 2401 $tnInfo($old_tab-leavefn) $nbInfo($win.notebook-page-$old_tab)) | |
| 2402 } | |
| 2403 if { $tnInfo($name-enterfn) != "" } { | |
| 2404 $tnInfo($name-enterfn) $nbInfo($win.notebook-page-$name) | |
| 2405 } | |
| 2406 | |
| 2407 notebook_display $win.notebook $name | |
| 2408 | |
| 2409 set normal [option get $win tabColor Color] | |
| 2410 $win.tabs itemconfigure tab -fill $normal | |
| 2411 | |
| 2412 set active [option get $win activeTabColor Color] | |
| 2413 $win.tabs itemconfigure tab-$name -fill $active | |
| 2414 $win.tabs raise $name | |
| 2415 | |
| 2416 set tnInfo($win-current) $name | |
| 2417 } | |
| 2418 | |
| 2419 # ---------------------------------------------------------------------- | |
| 2420 # EXAMPLE: simple notebook that can dial up pages | |
| 2421 # ---------------------------------------------------------------------- | |
| 2422 # Effective Tcl/Tk Programming | |
| 2423 # Mark Harrison, DSC Communications Corp. | |
| 2424 # Michael McLennan, Bell Labs Innovations for Lucent Technologies | |
| 2425 # Addison-Wesley Professional Computing Series | |
| 2426 # ====================================================================== | |
| 2427 # Copyright (c) 1996-1997 Lucent Technologies Inc. and Mark Harrison | |
| 2428 # ====================================================================== | |
| 2429 | |
| 2430 # BLV - again check for TK being present. | |
| 2431 if { [info command option] == "option" } { | |
| 2432 option add *Notebook.borderWidth 2 widgetDefault | |
| 2433 option add *Notebook.relief sunken widgetDefault | |
| 2434 } | |
| 2435 | |
| 2436 # BLV: replace nbInfo global with a per-namespace variable | |
| 2437 array set nbInfo {} | |
| 2438 | |
| 2439 proc notebook_create {win} { | |
| 2440 variable nbInfo | |
| 2441 | |
| 2442 frame $win -class Notebook | |
| 2443 pack propagate $win 0 | |
| 2444 | |
| 2445 set nbInfo($win-count) 0 | |
| 2446 set nbInfo($win-pages) "" | |
| 2447 set nbInfo($win-current) "" | |
| 2448 return $win | |
| 2449 } | |
| 2450 | |
| 2451 proc notebook_page {win name} { | |
| 2452 variable nbInfo | |
| 2453 | |
| 2454 set page "$win.page[incr nbInfo($win-count)]" | |
| 2455 lappend nbInfo($win-pages) $page | |
| 2456 set nbInfo($win-page-$name) $page | |
| 2457 | |
| 2458 frame $page | |
| 2459 | |
| 2460 if {$nbInfo($win-count) == 1} { | |
| 2461 after idle [list pkgconf::efftcl::notebook_display $win $name] | |
| 2462 } | |
| 2463 | |
| 2464 return $page | |
| 2465 } | |
| 2466 | |
| 2467 proc notebook_display {win name} { | |
| 2468 variable nbInfo | |
| 2469 | |
| 2470 set page "" | |
| 2471 if {[info exists nbInfo($win-page-$name)]} { | |
| 2472 set page $nbInfo($win-page-$name) | |
| 2473 } elseif {[winfo exists $win.page$name]} { | |
| 2474 set page $win.page$name | |
| 2475 } | |
| 2476 if {$page == ""} { | |
| 2477 error "bad notebook page \"$name\"" | |
| 2478 } | |
| 2479 | |
| 2480 notebook_fix_size $win | |
| 2481 | |
| 2482 if {$nbInfo($win-current) != ""} { | |
| 2483 pack forget $nbInfo($win-current) | |
| 2484 } | |
| 2485 pack $page -expand yes -fill both | |
| 2486 set nbInfo($win-current) $page | |
| 2487 } | |
| 2488 | |
| 2489 proc notebook_fix_size {win} { | |
| 2490 variable nbInfo | |
| 2491 | |
| 2492 update idletasks | |
| 2493 | |
| 2494 set maxw 0 | |
| 2495 set maxh 0 | |
| 2496 foreach page $nbInfo($win-pages) { | |
| 2497 set w [winfo reqwidth $page] | |
| 2498 if {$w > $maxw} { | |
| 2499 set maxw $w | |
| 2500 } | |
| 2501 set h [winfo reqheight $page] | |
| 2502 if {$h > $maxh} { | |
| 2503 set maxh $h | |
| 2504 } | |
| 2505 } | |
| 2506 set bd [$win cget -borderwidth] | |
| 2507 set maxw [expr $maxw+2*$bd] | |
| 2508 set maxh [expr $maxh+2*$bd] | |
| 2509 $win configure -width $maxw -height $maxh | |
| 2510 } | |
| 2511 | |
| 2512 # ---------------------------------------------------------------------- | |
| 2513 # EXAMPLE: use "wm" commands to manage a balloon help window | |
| 2514 # ---------------------------------------------------------------------- | |
| 2515 # Effective Tcl/Tk Programming | |
| 2516 # Mark Harrison, DSC Communications Corp. | |
| 2517 # Michael McLennan, Bell Labs Innovations for Lucent Technologies | |
| 2518 # Addison-Wesley Professional Computing Series | |
| 2519 # ====================================================================== | |
| 2520 # Copyright (c) 1996-1997 Lucent Technologies Inc. and Mark Harrison | |
| 2521 # ====================================================================== | |
| 2522 | |
| 2523 # BLV fix: again this script may execute in tclsh rather than in wish. | |
| 2524 if { [info command "option"] == "option" } { | |
| 2525 option add *Balloonhelp*background white widgetDefault | |
| 2526 option add *Balloonhelp*foreground black widgetDefault | |
| 2527 option add *Balloonhelp.info.wrapLength 3i widgetDefault | |
| 2528 option add *Balloonhelp.info.justify left widgetDefault | |
| 2529 option add *Balloonhelp.info.font \ | |
| 2530 -*-lucida-medium-r-normal-sans-*-120-* widgetDefault | |
| 2531 | |
| 2532 toplevel .balloonhelp -class Balloonhelp \ | |
| 2533 -background black -borderwidth 1 -relief flat | |
| 2534 | |
| 2535 # BLV fix: I want to create the arrow image inline rather than | |
| 2536 # read it in from a file. | |
| 2537 image create bitmap arrow -data "\ | |
| 2538 #define arrow_width 8 | |
| 2539 #define arrow_height 8 | |
| 2540 static unsigned char arrow_bits[] = { | |
| 2541 0x1f, 0x0f, 0x0f, 0x1f, 0x39, 0x70, 0x20, 0x00}; | |
| 2542 " | |
| 2543 label .balloonhelp.arrow -anchor nw -image arrow | |
| 2544 | |
| 2545 # label .balloonhelp.arrow -anchor nw \ | |
| 2546 # -bitmap @[file join $env(EFFTCL_LIBRARY) images arrow.xbm] | |
| 2547 pack .balloonhelp.arrow -side left -fill y | |
| 2548 | |
| 2549 label .balloonhelp.info | |
| 2550 pack .balloonhelp.info -side left -fill y | |
| 2551 | |
| 2552 wm overrideredirect .balloonhelp 1 | |
| 2553 wm withdraw .balloonhelp | |
| 2554 } | |
| 2555 | |
| 2556 # ---------------------------------------------------------------------- | |
| 2557 # USAGE: balloonhelp_for <win> <mesg> | |
| 2558 # | |
| 2559 # Adds balloon help to the widget named <win>. Whenever the mouse | |
| 2560 # pointer enters this widget and rests within it for a short delay, | |
| 2561 # a balloon help window will automatically appear showing the | |
| 2562 # help <mesg>. | |
| 2563 # ---------------------------------------------------------------------- | |
| 2564 | |
| 2565 proc balloonhelp_for {win mesg} { | |
| 2566 variable bhInfo | |
| 2567 set bhInfo($win) $mesg | |
| 2568 | |
| 2569 bind $win <Enter> {pkgconf::efftcl::balloonhelp_pending %W %W} | |
| 2570 bind $win <Leave> {pkgconf::efftcl::balloonhelp_cancel} | |
| 2571 } | |
| 2572 | |
| 2573 # BLV: a variant that can be used for canvas items. | |
| 2574 | |
| 2575 proc balloonhelp_canvas_for { canvas id mesg } { | |
| 2576 variable bhInfo | |
| 2577 set bhInfo($canvas-$id) $mesg | |
| 2578 | |
| 2579 $canvas bind $id <Enter> [list pkgconf::efftcl::balloonhelp_pending $canvas $canvas-$id] | |
| 2580 $canvas bind $id <Leave> {pkgconf::efftcl::balloonhelp_cancel} | |
| 2581 } | |
| 2582 | |
| 2583 # ---------------------------------------------------------------------- | |
| 2584 # USAGE: balloonhelp_control <state> | |
| 2585 # | |
| 2586 # Turns balloon help on/off for the entire application. | |
| 2587 # ---------------------------------------------------------------------- | |
| 2588 set bhInfo(active) 1 | |
| 2589 | |
| 2590 proc balloonhelp_control {state} { | |
| 2591 variable bhInfo | |
| 2592 | |
| 2593 if {$state} { | |
| 2594 set bhInfo(active) 1 | |
| 2595 } else { | |
| 2596 balloonhelp_cancel | |
| 2597 set bhInfo(active) 0 | |
| 2598 } | |
| 2599 } | |
| 2600 | |
| 2601 # ---------------------------------------------------------------------- | |
| 2602 # USAGE: balloonhelp_pending <win> | |
| 2603 # | |
| 2604 # Used internally to mark the point in time when a widget is first | |
| 2605 # touched. Sets up an "after" event so that balloon help will appear | |
| 2606 # if the mouse remains within the current window. | |
| 2607 # ---------------------------------------------------------------------- | |
| 2608 | |
| 2609 # BLV - the first argument identifies the window, the second the help | |
| 2610 # string. | |
| 2611 proc balloonhelp_pending {win id} { | |
| 2612 variable bhInfo | |
| 2613 | |
| 2614 balloonhelp_cancel | |
| 2615 set bhInfo(pending) [after 1500 [list pkgconf::efftcl::balloonhelp_show $win $id]] | |
| 2616 } | |
| 2617 | |
| 2618 # ---------------------------------------------------------------------- | |
| 2619 # USAGE: balloonhelp_cancel | |
| 2620 # | |
| 2621 # Used internally to mark the point in time when the mouse pointer | |
| 2622 # leaves a widget. Cancels any pending balloon help requested earlier | |
| 2623 # and hides the balloon help window, in case it is visible. | |
| 2624 # ---------------------------------------------------------------------- | |
| 2625 proc balloonhelp_cancel {} { | |
| 2626 variable bhInfo | |
| 2627 | |
| 2628 if {[info exists bhInfo(pending)]} { | |
| 2629 after cancel $bhInfo(pending) | |
| 2630 unset bhInfo(pending) | |
| 2631 } | |
| 2632 wm withdraw .balloonhelp | |
| 2633 } | |
| 2634 | |
| 2635 # ---------------------------------------------------------------------- | |
| 2636 # USAGE: balloonhelp_show <win> | |
| 2637 # | |
| 2638 # Used internally to display the balloon help window for the | |
| 2639 # specified <win>. | |
| 2640 # ---------------------------------------------------------------------- | |
| 2641 | |
| 2642 # BLV - the first argument identifies the window, the second the | |
| 2643 # help message. | |
| 2644 | |
| 2645 proc balloonhelp_show {win id} { | |
| 2646 variable bhInfo | |
| 2647 | |
| 2648 if {$bhInfo(active)} { | |
| 2649 .balloonhelp.info configure -text $bhInfo($id) | |
| 2650 | |
| 2651 # BLV: switched from using window-relative positions | |
| 2652 # to mouse relative position. | |
| 2653 if { 0 } { | |
| 2654 set x [expr [winfo rootx $win]+10] | |
| 2655 set y [expr [winfo rooty $win]+[winfo height $win]] | |
| 2656 } else { | |
| 2657 set coords [winfo pointerxy $win] | |
| 2658 set x [expr [lindex $coords 0] + 15] | |
| 2659 set y [expr [lindex $coords 1] + 15] | |
| 2660 } | |
| 2661 if { ($x >= 0) && ($y >= 0) } { | |
| 2662 wm geometry .balloonhelp +$x+$y | |
| 2663 wm deiconify .balloonhelp | |
| 2664 raise .balloonhelp | |
| 2665 } | |
| 2666 } | |
| 2667 unset bhInfo(pending) | |
| 2668 } | |
| 2669 | |
| 2670 } | |
| 2671 | |
| 2672 # }}} | |
| 2673 # {{{ standalone initialisation | |
| 2674 | |
| 2675 # ---------------------------------------------------------------------------- | |
| 2676 # GUI Start-up. It is necessary to work out a few things about the operating | |
| 2677 # environment. | |
| 2678 # | |
| 2679 # 1) is this script being run via tclsh or via wish ? If the former then only | |
| 2680 # command line operation is possible. If the latter then a GUI environment | |
| 2681 # can be provided as well. | |
| 2682 # | |
| 2683 # 2) if TK is present, has it been extended with Tix ? If so use the standard | |
| 2684 # TK color scheme etc., not the Tix variant. | |
| 2685 # | |
| 2686 # 3) if TK is present, get rid of the top-level window. | |
| 2687 # | |
| 2688 # If this command is not being run stand-alone then it is the responsibility | |
| 2689 # of the calling code to take appropriate action, e.g. to enable gui mode | |
| 2690 # and to set up the appropriate options. | |
| 2691 # | |
| 2692 | |
| 2693 proc pkgconf::gui_standalone_init { } { | |
| 2694 | |
| 2695 variable gui_possible | |
| 2696 | |
| 2697 if { [info command tk] == "tk" } { | |
| 2698 | |
| 2699 # TK is loaded. For now allow GUI mode, but the actual decision | |
| 2700 # depends on command line arguments. | |
| 2701 set gui_possible 1 | |
| 2702 | |
| 2703 # Get rid of the top-level window. Otherwise this might pop up if the | |
| 2704 # script performs a blocking operation too early. | |
| 2705 wm withdraw . | |
| 2706 | |
| 2707 # If TIX is also present, prevent the TIX color scheme etc. from taking | |
| 2708 # effect. | |
| 2709 if { [info command tix] == "tix" } { | |
| 2710 tix resetoptions TK TK | |
| 2711 } | |
| 2712 | |
| 2713 # It is probably not a good idea to accept "send" messages. However | |
| 2714 # setting the appname also affects option handling, which is more | |
| 2715 # useful. Note that the send command is not available in all versions | |
| 2716 # of Tcl. | |
| 2717 if { [info command send] == "send" } { | |
| 2718 rename send {} | |
| 2719 } | |
| 2720 tk appname pkgconf | |
| 2721 | |
| 2722 } else { | |
| 2723 | |
| 2724 # TK is not loaded, so gui mode is not possible. | |
| 2725 set gui_possible 0 | |
| 2726 } | |
| 2727 } | |
| 2728 | |
| 2729 # }}} | |
| 2730 # {{{ set toplevel window | |
| 2731 | |
| 2732 # ---------------------------------------------------------------------------- | |
| 2733 # Allow a containing program, if any, to specify the window in which | |
| 2734 # this script should do its funky stuff. It is not possible to change | |
| 2735 # this window while pkgconf is active, so if for any reason it is | |
| 2736 # necessary to change the toplevel window then the old one must be | |
| 2737 # destroyed first, the new name must be installed, and then there | |
| 2738 # must be a new call to pkgconf::gui to redraw the window. | |
| 2739 # | |
| 2740 | |
| 2741 proc pkgconf::set_toplevel_window { name } { | |
| 2742 variable toplevel | |
| 2743 set toplevel $name | |
| 2744 } | |
| 2745 | |
| 2746 # }}} | |
| 2747 # {{{ main GUI draw routine | |
| 2748 | |
| 2749 # ---------------------------------------------------------------------------- | |
| 2750 # The main GUI code. | |
| 2751 # | |
| 2752 # The routine pkgconf::gui is responsible for creating the various windows. | |
| 2753 # These are as follows: | |
| 2754 # | |
| 2755 # 1) a menu bar containing menus for File, Window and Help. Currently the only | |
| 2756 # entry in File is Exit, and the entries in Help are all disabled. The | |
| 2757 # Window menu allows the output window to be hidden or shown. | |
| 2758 # | |
| 2759 # 2) a notebook frame containing four pages: | |
| 2760 # | |
| 2761 # a) target hardware. This lists all known target architectures, | |
| 2762 # and allows the user to select the appropriate one using a | |
| 2763 # set of radio buttons. | |
| 2764 # | |
| 2765 # b) packages. This lists all known packages and the versions for | |
| 2766 # each package. Unfortunately neither radio buttons nor checkbuttons | |
| 2767 # provide entirely the right paradigm here, but checkbuttons are | |
| 2768 # good enough. | |
| 2769 # | |
| 2770 # c) an edit page. This allows the user to invoke a text editor for | |
| 2771 # any of the fine-grained configuration headers. | |
| 2772 # | |
| 2773 # d) a compiler flags page. This allows the user to manipulate the | |
| 2774 # compiler flags etc. | |
| 2775 # | |
| 2776 # e) a build page. This allows the user to create the build tree and to | |
| 2777 # invoke make, make tests, make clean, etc. There is also an entry | |
| 2778 # field to allow the install directory to be changed. | |
| 2779 # | |
| 2780 # 3) a label field along the bottom, which can be used by the various | |
| 2781 # frames to display warning messages. | |
| 2782 # | |
| 2783 # 4) a separate frame to hold the outputs of builds. This can be either | |
| 2784 # docked below the main frame, or it can be a separate toplevel window. | |
| 2785 # The build frame contains a number of buttons to allow the text | |
| 2786 # screen to be cleared, removed from the display, docked/undocked, | |
| 2787 # or saved to a file. | |
| 2788 # | |
| 2789 # 5) the options database is consulted to decide whether the output | |
| 2790 # window should be docked or not by default. | |
| 2791 # | |
| 2792 # 6) if there is a file ~/.pkgconfrc this file gets executed. It is | |
| 2793 # assumed to contain valid Tcl code. | |
| 2794 # | |
| 2795 # If this script is running inside a large application then there may be | |
| 2796 # a frame $toplevel_window already. If so this frame should be used. | |
| 2797 # Otherwise a separate toplevel window should be created, complete with | |
| 2798 # menu bar. | |
| 2799 # | |
| 2800 | |
| 2801 proc pkgconf::gui { } { | |
| 2802 | |
| 2803 variable toplevel | |
| 2804 if { [winfo exists $toplevel] == 0 } { | |
| 2805 create_toplevel_window | |
| 2806 } | |
| 2807 | |
| 2808 # Now create a notebook, and add four pages to it. The names of these | |
| 2809 # pages have to be stored in separate variables. | |
| 2810 variable target_frame | |
| 2811 variable packages_frame | |
| 2812 variable options_frame | |
| 2813 variable flags_frame | |
| 2814 variable build_frame | |
| 2815 | |
| 2816 efftcl::tabnotebook_create $toplevel.notebook | |
| 2817 set target_frame [efftcl::tabnotebook_page $toplevel.notebook "Target" \ | |
| 2818 pkgconf::nbpage_targets_enter pkgconf::nbpage_targets_leave \ | |
| 2819 "Select target hardware"] | |
| 2820 set packages_frame [efftcl::tabnotebook_page $toplevel.notebook "Packages" \ | |
| 2821 pkgconf::nbpage_packages_enter pkgconf::nbpage_packages_leave \ | |
| 2822 "Select desired packages"] | |
| 2823 set options_frame [efftcl::tabnotebook_page $toplevel.notebook "Options" \ | |
| 2824 pkgconf::nbpage_options_enter pkgconf::nbpage_options_leave \ | |
| 2825 "Edit configuration options"] | |
| 2826 set flags_frame [efftcl::tabnotebook_page $toplevel.notebook "Flags" \ | |
| 2827 pkgconf::nbpage_flags_enter pkgconf::nbpage_flags_leave \ | |
| 2828 "Edit compiler flags"] | |
| 2829 set build_frame [efftcl::tabnotebook_page $toplevel.notebook "Build" \ | |
| 2830 pkgconf::nbpage_build_enter pkgconf::nbpage_build_leave \ | |
| 2831 "Build this configuration"] | |
| 2832 | |
| 2833 # By default the notebook is the widget that expands. If a build output | |
| 2834 # window is present instead then it is the output window that expands. | |
| 2835 pack $toplevel.notebook -side top -fill both -expand 1 | |
| 2836 | |
| 2837 # Make sure that the message window exists, since some of the | |
| 2838 # notebook update routines refer to it. | |
| 2839 label $toplevel.message -text "" -anchor w -relief raised -borderwidth 2 | |
| 2840 pack $toplevel.message -side top -fill x | |
| 2841 | |
| 2842 # Now create the notebook pages. | |
| 2843 nbpage_targets_initialise $target_frame | |
| 2844 nbpage_packages_initialise $packages_frame | |
| 2845 nbpage_options_initialise $options_frame | |
| 2846 nbpage_flags_initialise $flags_frame | |
| 2847 nbpage_build_initialise $build_frame | |
| 2848 | |
| 2849 # Create the output window, but leave it hidden for now. | |
| 2850 frame $toplevel.output | |
| 2851 frame $toplevel.output.buttons | |
| 2852 button $toplevel.output.buttons.hide -text "Hide" -command pkgconf::output_hide_window | |
| 2853 button $toplevel.output.buttons.undock -text "Undock" -command pkgconf::output_undock_window | |
| 2854 button $toplevel.output.buttons.clear -text "Clear" -command pkgconf::output_clear_window | |
| 2855 button $toplevel.output.buttons.save -text "Save..." -command pkgconf::output_save | |
| 2856 pack $toplevel.output.buttons.hide \ | |
| 2857 $toplevel.output.buttons.undock \ | |
| 2858 $toplevel.output.buttons.clear \ | |
| 2859 $toplevel.output.buttons.save -side left -expand 1 | |
| 2860 pack $toplevel.output.buttons -side top -fill x | |
| 2861 text $toplevel.output.text -wrap word -state disabled -yscrollcommand [list $toplevel.output.scroll set] | |
| 2862 pack $toplevel.output.text -side left -fill both -expand 1 | |
| 2863 scrollbar $toplevel.output.scroll -orient vertical -command [list $toplevel.output.text yview] | |
| 2864 pack $toplevel.output.scroll -side right -fill y | |
| 2865 | |
| 2866 # Create a toplevel window matching the output frame, but leave it | |
| 2867 # hidden for now. Give it the same bindings as the toplevel window. | |
| 2868 toplevel .pkgconf_output -menu .menubar -class Pkgconf | |
| 2869 wm withdraw .pkgconf_output | |
| 2870 wm title .pkgconf_output "pkgconf build output" | |
| 2871 wm protocol .pkgconf_output WM_DELETE_WINDOW { pkgconf::handle_exit } | |
| 2872 | |
| 2873 bind .pkgconf_output <Alt-q> { pkgconf::handle_exit } | |
| 2874 bind .pkgconf_output <Alt-f><KeyPress-x> { pkgconf::handle_exit } | |
| 2875 | |
| 2876 frame .pkgconf_output.buttons | |
| 2877 button .pkgconf_output.buttons.hide -text "Hide" -command pkgconf::output_hide_window | |
| 2878 button .pkgconf_output.buttons.undock -text "Dock" -command pkgconf::output_undock_window | |
| 2879 button .pkgconf_output.buttons.clear -text "Clear" -command pkgconf::output_clear_window | |
| 2880 button .pkgconf_output.buttons.save -text "Save..." -command pkgconf::output_save | |
| 2881 pack .pkgconf_output.buttons.hide \ | |
| 2882 .pkgconf_output.buttons.undock \ | |
| 2883 .pkgconf_output.buttons.clear \ | |
| 2884 .pkgconf_output.buttons.save -side left -expand 1 | |
| 2885 pack .pkgconf_output.buttons -side top -fill x | |
| 2886 text .pkgconf_output.text -wrap word -state disabled -yscrollcommand { .pkgconf_output.scroll set } | |
| 2887 pack .pkgconf_output.text -side left -fill both -expand 1 | |
| 2888 scrollbar .pkgconf_output.scroll -orient vertical -command { .pkgconf_output.text yview } | |
| 2889 pack .pkgconf_output.scroll -side right -fill y | |
| 2890 | |
| 2891 efftcl::balloonhelp_for $toplevel.output.buttons.hide \ | |
| 2892 "Remove the build output window, until more output appears." | |
| 2893 efftcl::balloonhelp_for .pkgconf_output.buttons.hide \ | |
| 2894 "Remove the build output window, until more output appears." | |
| 2895 efftcl::balloonhelp_for $toplevel.output.buttons.undock \ | |
| 2896 "Make the build output appear in a separate window." | |
| 2897 efftcl::balloonhelp_for .pkgconf_output.buttons.undock \ | |
| 2898 "Attach the build output to the main pkgconf window." | |
| 2899 efftcl::balloonhelp_for $toplevel.output.buttons.clear \ | |
| 2900 "Remove all build output text." | |
| 2901 efftcl::balloonhelp_for .pkgconf_output.buttons.clear \ | |
| 2902 "Remove all build output text." | |
| 2903 efftcl::balloonhelp_for $toplevel.output.buttons.save \ | |
| 2904 "Save build output to a file." | |
| 2905 efftcl::balloonhelp_for .pkgconf_output.buttons.save \ | |
| 2906 "Save build output to a file." | |
| 2907 | |
| 2908 # Consult the options database. | |
| 2909 variable output_docked | |
| 2910 option add "*docked" 1 startupFile | |
| 2911 set output_docked [option get $toplevel docked Pkgconf] | |
| 2912 | |
| 2913 # Look for a file ~/.pkgconfrc and execute it. | |
| 2914 if { [file isfile [file join "~" ".pkgconfrc"]] } { | |
| 2915 if { [namespace eval :: { catch { source [file join "~" ".pkgconfrc"] } message } ] != 0 } { | |
| 2916 warning "The following error occurred while executing ~/.pkgconfrc: $message" | |
| 2917 } | |
| 2918 } | |
| 2919 } | |
| 2920 | |
| 2921 # ---------------------------------------------------------------------------- | |
| 2922 # This routine creates the toplevel window, if pkgconf is running | |
| 2923 # independently rather than inside a larger application. | |
| 2924 | |
| 2925 proc pkgconf::create_toplevel_window { } { | |
| 2926 | |
| 2927 variable toplevel | |
| 2928 | |
| 2929 # Start by creating the menubar. TK8's support for native menus is | |
| 2930 # used. | |
| 2931 menu .menubar -type menubar | |
| 2932 menu .menubar.config -tearoff 0 -type normal | |
| 2933 menu .menubar.edit -tearoff 0 -type normal | |
| 2934 menu .menubar.view -tearoff 0 -type normal | |
| 2935 menu .menubar.help -tearoff 0 -type normal | |
| 2936 | |
| 2937 .menubar.config add command -label "Exit" -command pkgconf::handle_exit -underline 1 \ | |
| 2938 -accelerator "Alt+Q" | |
| 2939 | |
| 2940 .menubar.edit add command -label "Undo" -state disabled | |
| 2941 .menubar.edit add command -label "Redo" -state disabled | |
| 2942 | |
| 2943 .menubar.view add checkbutton -label "Show output" \ | |
| 2944 -variable pkgconf::output_visible -onvalue 1 -offvalue 0 \ | |
| 2945 -command pkgconf::output_menu | |
| 2946 .menubar.view add checkbutton -label "Balloon help" \ | |
| 2947 -variable pkgconf::efftcl::bhInfo(active) -onvalue 1 -offvalue 0 | |
| 2948 | |
| 2949 .menubar.help add command -label "Help on pkgconf" -state disabled | |
| 2950 .menubar.help add command -label "Help on the system" -state disabled | |
| 2951 .menubar.help add command -label "Search" -state disabled | |
| 2952 .menubar.help add separator | |
| 2953 .menubar.help add command -label "About pkgconf" -state disabled | |
| 2954 | |
| 2955 .menubar add cascade -menu .menubar.config -label "Configuration" -underline 0 | |
| 2956 .menubar add cascade -menu .menubar.edit -label "Edit" -underline 0 | |
| 2957 .menubar add cascade -menu .menubar.view -label "View" -underline 0 | |
| 2958 .menubar add cascade -menu .menubar.help -label "Help" -underline 0 | |
| 2959 | |
| 2960 # Create the toplevel window, giving it a menubar and a name, | |
| 2961 # and establish the accelerator binding. | |
| 2962 toplevel $toplevel -menu .menubar -class Pkgconf | |
| 2963 wm title $toplevel pkgconf | |
| 2964 bind $toplevel <Alt-q> { pkgconf::handle_exit } | |
| 2965 wm protocol $toplevel WM_DELETE_WINDOW { pkgconf::handle_exit } | |
| 2966 | |
| 2967 # Although there is a Configuration menu instead of a file menu, it is | |
| 2968 # desirable to support alt-f-x as a reasonably standard way of exiting | |
| 2969 # the program. | |
| 2970 bind $toplevel <Alt-f><KeyPress-x> { pkgconf::handle_exit } | |
| 2971 } | |
| 2972 | |
| 2973 # ---------------------------------------------------------------------------- | |
| 2974 # This routine gets invoked for exit handling: when the user invokes the | |
| 2975 # exit entry on the file menu; or when the alt-q accelerator is used; or | |
| 2976 # when a window delete request is received. For now the code just exits, | |
| 2977 # but it might be an idea to offer to save configuration changes if any. | |
| 2978 # | |
| 2979 proc pkgconf::handle_exit { } { | |
| 2980 exit 0 | |
| 2981 } | |
| 2982 | |
| 2983 # }}} | |
| 2984 # {{{ Notebook pages | |
| 2985 | |
| 2986 # {{{ Targets page | |
| 2987 | |
| 2988 # ---------------------------------------------------------------------------- | |
| 2989 # The targets page. This allows the user to select the target architecture, | |
| 2990 # platform, and startup. The range of available target architectures cannot | |
| 2991 # change while the program is running, so this window is actually fixed. | |
| 2992 # | |
| 2993 | |
| 2994 proc pkgconf::nbpage_targets_initialise { win } { | |
| 2995 | |
| 2996 variable config_data | |
| 2997 variable known_targets | |
| 2998 variable target_data | |
| 2999 variable target_page_data | |
| 3000 | |
| 3001 # I need a variable that can be associated with the radiobuttons and | |
| 3002 # identifies the selected target uniquely. It is not really | |
| 3003 # possible to do this with the three variables in the config data | |
| 3004 # directly. | |
| 3005 set target_page_data(selection) [list $config_data(target) $config_data(platform) $config_data(startup)] | |
| 3006 | |
| 3007 # Conceivably the number of targets could be larger than can fit | |
| 3008 # conveniently on to one screen, so it is desirable use a scrollable | |
| 3009 # form. Start by creating a scrollbar, a canvas, and a frame within | |
| 3010 # that canvas, and set up a standard resize callback. The canvas | |
| 3011 # starts off small, but expands as necessary. The actual size will | |
| 3012 # therefore be determined by whichever page does not have a | |
| 3013 # vertical scrollbar, typically the build page. | |
| 3014 scrollbar $win.scrollbar -command "$win.viewport yview" -orient vertical | |
| 3015 pack $win.scrollbar -side right -fill y | |
| 3016 | |
| 3017 canvas $win.viewport -height 10m -yscrollcommand "$win.scrollbar set" | |
| 3018 pack $win.viewport -fill both -expand 1 -padx 20 -pady 20 | |
| 3019 | |
| 3020 frame $win.viewport.form | |
| 3021 $win.viewport create window 0 0 -anchor nw -window $win.viewport.form | |
| 3022 | |
| 3023 bind $win.viewport.form <Configure> "pkgconf::nbpage_form_resized $win" | |
| 3024 | |
| 3025 # Now fill in the form with details of all the targets. | |
| 3026 # These are arranged in a simple grid. | |
| 3027 set form $win.viewport.form | |
| 3028 set row 0 | |
| 3029 | |
| 3030 foreach target $known_targets { | |
| 3031 | |
| 3032 label $form.arch-$row -text "Target [get_target_alias $target]" -anchor w | |
| 3033 grid $form.arch-$row -row $row -column 0 -sticky w | |
| 3034 incr row | |
| 3035 | |
| 3036 foreach platform $target_data($target,known_platforms) { | |
| 3037 foreach startup $target_data($target,$platform,startup) { | |
| 3038 | |
| 3039 label $form.platform-$row -text " Platform [get_platform_alias $target $platform]," -anchor w | |
| 3040 grid $form.platform-$row -row $row -column 0 -sticky w | |
| 3041 label $form.startup-$row -text "$startup startup" -anchor w | |
| 3042 grid $form.startup-$row -row $row -column 1 -sticky w -ipadx 5 | |
| 3043 radiobutton $form.button-$row -variable pkgconf::target_page_data(selection) \ | |
| 3044 -value [list $target $platform $startup] \ | |
| 3045 -command pkgconf::clear_status_line | |
| 3046 grid $form.button-$row -row $row -column 2 -sticky w | |
| 3047 incr row | |
| 3048 } | |
| 3049 } | |
| 3050 } | |
| 3051 } | |
| 3052 | |
| 3053 # | |
| 3054 # The enter routine gets invoked when the user switches to the targets tab, | |
| 3055 # and also during start-up since the targets tab is the first one. It is | |
| 3056 # responsible for keeping track of the initial target selection, so that | |
| 3057 # when the user switches to a different tab it is possible to know whether | |
| 3058 # or not the target has actually changed. | |
| 3059 # | |
| 3060 # As a useful side effect, the routine updates the status line. | |
| 3061 # | |
| 3062 proc pkgconf::nbpage_targets_enter { win } { | |
| 3063 | |
| 3064 variable config_data | |
| 3065 variable target_page_data | |
| 3066 | |
| 3067 set target_page_data(initial_selection) $target_page_data(selection) | |
| 3068 | |
| 3069 if { ($config_data(target) == "") || ($config_data(platform) == "") || ($config_data(startup) == "") } { | |
| 3070 set_status_line "Please select a target system." | |
| 3071 } else { | |
| 3072 clear_status_line | |
| 3073 } | |
| 3074 } | |
| 3075 | |
| 3076 proc pkgconf::nbpage_targets_leave { win } { | |
| 3077 | |
| 3078 variable target_page_data | |
| 3079 | |
| 3080 if { $target_page_data(selection) != $target_page_data(initial_selection) } { | |
| 3081 variable config_data | |
| 3082 variable build_tree_needs_update | |
| 3083 | |
| 3084 set config_data(target) [lindex $target_page_data(selection) 0] | |
| 3085 set config_data(platform) [lindex $target_page_data(selection) 1] | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
3086 set config_data(base_platform) [get_base_platform $config_data(target) $config_data(platform)] |
| 0 | 3087 set config_data(startup) [lindex $target_page_data(selection) 2] |
| 3088 set build_tree_needs_update 1 | |
| 3089 | |
| 3090 # A change of target has implications for the compiler flags, which | |
| 3091 # must be handled immediately. The user may not go into the flags | |
| 3092 # tab so the changes cannot be done in the flags tab enter/leave | |
| 3093 # routines. | |
| 3094 update_compiler_flags | |
| 3095 } | |
| 3096 } | |
| 3097 | |
| 3098 # | |
| 3099 # This routine take care of resize operations. Whenever the size | |
| 3100 # of the form changes the canvas' scroll region needs to be adjusted. | |
| 3101 # | |
| 3102 # Note that this code is also used for the packages page. | |
| 3103 # | |
| 3104 proc pkgconf::nbpage_form_resized { win } { | |
| 3105 | |
| 3106 set bbox [$win.viewport bbox all] | |
| 3107 set old_bbox [$win.viewport cget -scrollregion] | |
| 3108 set width [winfo width $win.viewport.form] | |
| 3109 set old_width [$win.viewport cget -width] | |
| 3110 if { ("$bbox" != "$old_bbox") || ($width != $old_width) } { | |
| 3111 $win.viewport configure -width $width -scrollregion $bbox | |
| 3112 } | |
| 3113 } | |
| 3114 | |
| 3115 # }}} | |
| 3116 # {{{ Packages page | |
| 3117 | |
| 3118 # ---------------------------------------------------------------------------- | |
| 3119 # The packages page. This is mostly similar to the targets page. | |
| 3120 # It is necessary to provide a mechanism for disabling packages. | |
| 3121 # It is also necessary to worry about changes to the target architecture. | |
| 3122 # The initialise() routine takes care of most of these things. | |
| 3123 | |
| 3124 proc pkgconf::nbpage_packages_initialise { win } { | |
| 3125 | |
| 3126 variable config_data | |
| 3127 variable known_packages | |
| 3128 variable package_data | |
| 3129 variable target_data | |
| 3130 variable packages_page_data | |
| 3131 | |
| 3132 # Start by storing details of the target that is currently | |
| 3133 # being displayed. | |
| 3134 set packages_page_data(current_target) $config_data(target) | |
| 3135 set packages_page_data(current_platform) $config_data(platform) | |
| 3136 | |
| 3137 # Typically the number of packages will be larger than can fit | |
| 3138 # conveniently on to one screen, so it is desirable use a scrollable | |
| 3139 # form. Start by creating a scrollbar, a canvas, and a frame within | |
| 3140 # that canvas, and set up a standard resize callback. The canvas | |
| 3141 # starts of small, but expands as necessary. The actual size will | |
| 3142 # therefore be determined by whichever page does not have a | |
| 3143 # vertical scrollbar, typically the build page. | |
| 3144 scrollbar $win.scrollbar -command "$win.viewport yview" -orient vertical | |
| 3145 pack $win.scrollbar -side right -fill y | |
| 3146 | |
| 3147 canvas $win.viewport -height 10m -yscrollcommand "$win.scrollbar set" | |
| 3148 pack $win.viewport -fill both -expand 1 -padx 20 -pady 20 | |
| 3149 | |
| 3150 frame $win.viewport.form | |
| 3151 $win.viewport create window 0 0 -anchor nw -window $win.viewport.form | |
| 3152 | |
| 3153 bind $win.viewport.form <Configure> "pkgconf::nbpage_form_resized $win" | |
| 3154 | |
| 3155 # Now fill in the form with details of all the packages. | |
| 3156 # These are arranged in a simple grid. | |
| 3157 set form $win.viewport.form | |
| 3158 set row 0 | |
| 3159 | |
| 3160 # Now handle the packages themselves. Each package can be in one | |
| 3161 # of the following states: | |
| 3162 # | |
| 3163 # 1) a hardware package is enabled by default if it is specified | |
| 3164 # for the current target or platform, disabled otherwise. | |
| 3165 # However the user should be able to explicitly enable or | |
| 3166 # disable it. This is handled by config_data(enabled_packages) | |
| 3167 # and config_data(disabled_packages). | |
| 3168 # | |
| 3169 # 2) a non-hardware package may be enabled or disabled by default, | |
| 3170 # but the user can change this. Again this is handled by | |
| 3171 # enabled_packages and disabled_packages. | |
| 3172 # | |
| 3173 # It is convenient to cache the list of target and platform specific | |
| 3174 # packages. | |
| 3175 set target_packages "" | |
| 3176 set platform_packages "" | |
| 3177 if { $config_data(target) != "" } { | |
| 3178 set target_packages $target_data($config_data(target),packages) | |
| 3179 if { $config_data(platform) != "" } { | |
| 3180 set platform_packages $target_data($config_data(target),$config_data(platform),packages) | |
| 3181 } | |
| 3182 } | |
| 3183 foreach pkg $known_packages { | |
| 3184 | |
| 3185 # What is the current version of each package ? | |
| 3186 set current_version "" | |
| 3187 | |
| 3188 if { $package_data($pkg,hardware) != 0 } { | |
| 3189 if { ([lsearch -exact $target_packages $pkg] != -1) || ([lsearch -exact $platform_packages $pkg] != -1)} { | |
| 3190 set current_version $config_data($pkg,version) | |
| 3191 } | |
| 3192 } elseif { $package_data($pkg,default) != 0 } { | |
| 3193 set current_version $config_data($pkg,version) | |
| 3194 } | |
| 3195 | |
| 3196 if { [lsearch -exact $config_data(enabled_packages) $pkg] != -1 } { | |
| 3197 set current_version $config_data($pkg,version) | |
| 3198 } | |
| 3199 if { [lsearch -exact $config_data(disabled_packages) $pkg] != -1 } { | |
| 3200 set current_version "" | |
| 3201 } | |
| 3202 | |
| 3203 # Store the current version, so that it is easier to figure out what | |
| 3204 # has changed. | |
| 3205 set packages_page_data($pkg,version) $current_version | |
| 3206 | |
| 3207 label $form.label-$row -text "[get_package_alias $pkg]:" | |
| 3208 grid $form.label-$row -row $row -column 0 -sticky w | |
| 3209 foreach version $package_data($pkg,versions) { | |
| 3210 label $form.version-$row -text "Version $version" | |
| 3211 grid $form.version-$row -row $row -column 1 -sticky w -ipady 5 | |
| 3212 | |
| 3213 radiobutton $form.button-$row -variable pkgconf::packages_page_data($pkg,version) \ | |
| 3214 -value $version -command [list pkgconf::nbpage_packages_change $pkg] | |
| 3215 grid $form.button-$row -row $row -column 2 -sticky w | |
| 3216 incr row | |
| 3217 } | |
| 3218 label $form.version-$row -text "Disable" | |
| 3219 grid $form.version-$row -row $row -column 1 -sticky w | |
| 3220 radiobutton $form.button-$row -variable pkgconf::packages_page_data($pkg,version) \ | |
| 3221 -value "" -command [list pkgconf::nbpage_packages_change $pkg] | |
| 3222 grid $form.button-$row -row $row -column 2 -sticky w | |
| 3223 incr row | |
| 3224 } | |
| 3225 } | |
| 3226 | |
| 3227 # | |
| 3228 # This routine gets invoked whenever there is a change to one of the | |
| 3229 # packages. It sets a flag indicating that the build tree is out of data. | |
| 3230 # It will also update the appropriate config_data. | |
| 3231 # | |
| 3232 proc pkgconf::nbpage_packages_change { pkg } { | |
| 3233 | |
| 3234 variable build_tree_needs_update | |
| 3235 set build_tree_needs_update 1 | |
| 3236 | |
| 3237 variable packages_page_data | |
| 3238 variable config_data | |
| 3239 | |
| 3240 set version $packages_page_data($pkg,version) | |
| 3241 if { $version == "" } { | |
| 3242 | |
| 3243 # This package is being explicitly disabled. | |
| 3244 set index [lsearch -exact $config_data(enabled_packages) $pkg] | |
| 3245 if { $index != -1 } { | |
| 3246 set config_data(enabled_packages) [lreplace $config_data(enabled_packages) $index $index] | |
| 3247 } | |
| 3248 | |
| 3249 set index [lsearch -exact $config_data(disabled_packages) $pkg] | |
| 3250 if { $index == -1 } { | |
| 3251 lappend config_data(disabled_packages) $pkg | |
| 3252 } | |
| 3253 } else { | |
| 3254 | |
| 3255 # A package version is being changed, possibly causing it to | |
| 3256 # be enabled. | |
| 3257 set config_data($pkg,version) $version | |
| 3258 | |
| 3259 set index [lsearch -exact $config_data(disabled_packages) $pkg] | |
| 3260 if { $index != -1 } { | |
| 3261 set config_data(disabled_packages) [lreplace $config_data(disabled_packages) $index $index] | |
| 3262 } | |
| 3263 | |
| 3264 set index [lsearch -exact $config_data(enabled_packages) $pkg] | |
| 3265 if { $index == -1 } { | |
| 3266 lappend config_data(enabled_packages) $pkg | |
| 3267 } | |
| 3268 } | |
| 3269 } | |
| 3270 | |
| 3271 # | |
| 3272 # The packages page needs to be redrawn every time a different target is | |
| 3273 # selected, so that the user can select which version of the HAL packages | |
| 3274 # should be used. The redraw can be achieved by deleting the existing | |
| 3275 # contents of the window and re-invoking the initialise function. | |
| 3276 | |
| 3277 proc pkgconf::nbpage_packages_enter { win } { | |
| 3278 | |
| 3279 variable packages_page_data | |
| 3280 variable config_data | |
| 3281 | |
| 3282 if { ($packages_page_data(current_target) != $config_data(target)) || | |
| 3283 ($packages_page_data(current_platform) != $config_data(platform)) } { | |
| 3284 | |
| 3285 foreach subwin [winfo children $win] { | |
| 3286 destroy $subwin | |
| 3287 } | |
| 3288 nbpage_packages_initialise $win | |
| 3289 } | |
| 3290 | |
| 3291 # If the target architecture is not yet known, remind the user. | |
| 3292 if { ($config_data(target) == "") || ($config_data(platform) == "") || ($config_data(startup) == "") } { | |
| 3293 set_status_line "Please select a target system." | |
| 3294 } else { | |
| 3295 clear_status_line | |
| 3296 } | |
| 3297 } | |
| 3298 | |
| 3299 # | |
| 3300 # Currently this code does nothing, instead it is left to the | |
| 3301 # nbpage_packages_change routine above to update the appropriate | |
| 3302 # global information. This is unfortunate in that if the user | |
| 3303 # makes a mistake and undoes it pkgconf still thinks that the | |
| 3304 # build tree is out of date. | |
| 3305 | |
| 3306 proc pkgconf::nbpage_packages_leave { win } { | |
| 3307 } | |
| 3308 | |
| 3309 # }}} | |
| 3310 # {{{ Options page | |
| 3311 | |
| 3312 # ---------------------------------------------------------------------------- | |
| 3313 # The options page. This consists of two frame arranged vertically. | |
| 3314 # The top frame allows the user to select the editor to use, which is | |
| 3315 # initialised from the VISUAL environment variable. The bottom frame | |
| 3316 # is another scrollable canvas allowing the user to select a header | |
| 3317 # file to edit. | |
| 3318 # | |
| 3319 # A number of special cases have to be allowed for. If there is no | |
| 3320 # text editor then all the buttons to edit a text file have to | |
| 3321 # be disabled. If there is no pkgconf directory in the build tree | |
| 3322 # yet then there will be no files to edit. Even if there is an | |
| 3323 # an pkgconf directory it may not contain all the files it is | |
| 3324 # supposed to, especially if the build tree is not up to date. | |
| 3325 # | |
| 3326 | |
| 3327 proc pkgconf::nbpage_options_initialise { win } { | |
| 3328 | |
| 3329 # Start with the top frame. This contains a label, an entry field, | |
| 3330 # and a button that invokes a file selector. | |
| 3331 # NOTE: these borderwidths should not be hardwired. | |
| 3332 variable editor | |
| 3333 frame $win.top -relief raised -borderwidth 2 | |
| 3334 label $win.top.label -text "Editor:" | |
| 3335 entry $win.top.entry -relief sunken -borderwidth 2 -textvariable pkgconf::editor | |
| 3336 button $win.top.button -text "Browse..." -command pkgconf::nbpage_options_browse | |
| 3337 pack $win.top.button -side right | |
| 3338 pack $win.top.entry -side right -fill x -expand 1 | |
| 3339 pack $win.top.label -side left | |
| 3340 pack $win.top -side top -fill x | |
| 3341 | |
| 3342 efftcl::balloonhelp_for $win.top.entry "The text editor that should be used." | |
| 3343 efftcl::balloonhelp_for $win.top.button "Select the text editor that should be used." | |
| 3344 | |
| 3345 # The entry widget does not support a command callback when | |
| 3346 # a string has been typed in, so it is necessary to use the | |
| 3347 # trace facility instead to enable or disable the buttons. | |
| 3348 # Note that this routine may get invoked from the update routine, | |
| 3349 # so it is necessary to clean up the old trace. | |
| 3350 trace vdelete pkgconf::editor w pkgconf::nbpage_options_editor_changed | |
| 3351 trace variable pkgconf::editor w pkgconf::nbpage_options_editor_changed | |
| 3352 | |
| 3353 # At this point there are now button widgets in this page. The | |
| 3354 # nbpage_options_editor_changed routine used this list. | |
| 3355 variable options_page_data | |
| 3356 set options_page_data(buttons) "" | |
| 3357 | |
| 3358 # Now check for editable files in the pkgconf directory. | |
| 3359 # Three of the files, makefile, pkgconf.mak and system.h are generated | |
| 3360 # and should not be edited by users. There may also be various .stamp | |
| 3361 # files used by the build system. | |
| 3362 variable build_tree | |
| 3363 set files "" | |
| 3364 foreach filename [glob -nocomplain [file join $build_tree "pkgconf" "*"]] { | |
| 3365 set filename [file tail $filename] | |
| 3366 if { [string match {*.stamp} $filename] } continue | |
| 3367 if { ($filename == "makefile") || ($filename == "pkgconf.mak") || ($filename == "system.h") } continue | |
| 3368 lappend files $filename | |
| 3369 } | |
| 3370 | |
| 3371 if { $files == "" } { | |
| 3372 | |
| 3373 # OK, just display a message. There is likely to be an appropriate | |
| 3374 # warning in the message frame at the bottom of the window already. | |
| 3375 label $win.message -text "There are no configuration files to edit." | |
| 3376 pack $win.message -fill both -expand 1 | |
| 3377 | |
| 3378 # A valid configuration always has a makevars file to edit, so the | |
| 3379 # implication is that the build tree is out of date. It probably | |
| 3380 # makes sense to set the relevant flag here. | |
| 3381 variable build_tree_needs_update | |
| 3382 set build_tree_needs_update 1 | |
| 3383 return | |
| 3384 } | |
| 3385 | |
| 3386 # The editable files are displayed in a scrollable frame, just | |
| 3387 # like the targets and packages pages. | |
| 3388 scrollbar $win.scrollbar -command "$win.viewport yview" -orient vertical | |
| 3389 pack $win.scrollbar -side right -fill y | |
| 3390 | |
| 3391 canvas $win.viewport -height 10m -yscrollcommand "$win.scrollbar set" | |
| 3392 pack $win.viewport -fill both -expand 1 -padx 20 -pady 20 | |
| 3393 | |
| 3394 frame $win.viewport.form | |
| 3395 $win.viewport create window 0 0 -anchor nw -window $win.viewport.form | |
| 3396 | |
| 3397 bind $win.viewport.form <Configure> "pkgconf::nbpage_form_resized $win" | |
| 3398 | |
| 3399 # Now fill in the form with all the buttons. | |
| 3400 set form $win.viewport.form | |
| 3401 set row 0 | |
| 3402 | |
| 3403 foreach file $files { | |
| 3404 | |
| 3405 button $form.button-$row -text "<pkgconf/$file>" -anchor w \ | |
| 3406 -command [list pkgconf::nbpage_options_edit $file] | |
| 3407 grid $form.button-$row -row $row -column 0 -sticky we -padx 10 -pady 5 | |
| 3408 label $form.label-$row -anchor w -text "Edit [file join $build_tree pkgconf $file]" | |
| 3409 grid $form.label-$row -row $row -column 1 -sticky w | |
| 3410 | |
| 3411 efftcl::balloonhelp_for $form.button-$row "Edit this configuration file." | |
| 3412 lappend options_page_data(buttons) $form.button-$row | |
| 3413 if { $editor == "" } { | |
| 3414 $form.button-$row configure -state disabled | |
| 3415 } | |
| 3416 incr row | |
| 3417 } | |
| 3418 } | |
| 3419 | |
| 3420 # The options page needs to be redrawn every time the build tree is | |
| 3421 # regenerated, since this may result in a different set of editable | |
| 3422 # configuration header files. | |
| 3423 | |
| 3424 proc pkgconf::nbpage_options_enter { win } { | |
| 3425 | |
| 3426 variable options_page_needs_refresh | |
| 3427 | |
| 3428 if { $options_page_needs_refresh != 0 } { | |
| 3429 set options_page_needs_refresh 0 | |
| 3430 foreach subwin [winfo children $win] { destroy $subwin } | |
| 3431 nbpage_options_initialise $win | |
| 3432 } | |
| 3433 | |
| 3434 # It is also desirable to display some warnings. | |
| 3435 variable config_data | |
| 3436 variable build_tree_needs_update | |
| 3437 variable editor | |
| 3438 variable options_page_data | |
| 3439 | |
| 3440 set options_page_data(no_editor) 0 | |
| 3441 | |
| 3442 if { ($config_data(target) == "") || ($config_data(platform) == "") || ($config_data(startup) == "") } { | |
| 3443 set_status_line "The target hardware has not yet been selected." | |
| 3444 } elseif { $build_tree_needs_update } { | |
| 3445 set_status_line "The build tree needs updating." | |
| 3446 } elseif { $editor == "" } { | |
| 3447 set options_page_data(no_editor) 1 | |
| 3448 set_status_line "No text editor has been defined yet." | |
| 3449 } else { | |
| 3450 clear_status_line | |
| 3451 } | |
| 3452 } | |
| 3453 | |
| 3454 # | |
| 3455 # There are no obvious actions to be taken if the user switches to | |
| 3456 # a different tab. Even if the user has invoked the editor on a | |
| 3457 # configuration file there is no guarantee that anything has actually | |
| 3458 # changed. | |
| 3459 proc pkgconf::nbpage_options_leave { win } { | |
| 3460 } | |
| 3461 | |
| 3462 # | |
| 3463 # This procedure allows the user to select a text editor. It gets invoked | |
| 3464 # from the browse button. | |
| 3465 # | |
| 3466 # NOTE: on windows it might be desirable to specify a .exe extension as | |
| 3467 # the type, but even that is optional under NT. | |
| 3468 # | |
| 3469 proc pkgconf::nbpage_options_browse { } { | |
| 3470 | |
| 3471 variable editor | |
| 3472 variable build_tree | |
| 3473 variable toplevel | |
| 3474 | |
| 3475 set filename [tk_getOpenFile -initialdir $build_tree -parent $toplevel -title "Select text editor"] | |
| 3476 if { $filename == "" } { | |
| 3477 return | |
| 3478 } | |
| 3479 set editor $filename | |
| 3480 } | |
| 3481 | |
| 3482 # | |
| 3483 # This procedure is invoked whenever the editor variable is changed. | |
| 3484 # Its purpose is to enable or disable the buttons for the various | |
| 3485 # configuration headers. | |
| 3486 # | |
| 3487 # The code does not actually check whether the current editor value corresponds | |
| 3488 # to a valid executable. It is just about possible to check for an existing | |
| 3489 # file somewhere in the path, but that is expensive and there is still no | |
| 3490 # guarantee that the file is a valid executable. | |
| 3491 # | |
| 3492 | |
| 3493 proc pkgconf::nbpage_options_editor_changed { name1 name2 mode } { | |
| 3494 | |
| 3495 variable editor | |
| 3496 variable options_page_data | |
| 3497 variable toplevel | |
| 3498 | |
| 3499 if { $editor == "" } { | |
| 3500 | |
| 3501 foreach button $options_page_data(buttons) { | |
| 3502 $button configure -state disabled | |
| 3503 } | |
| 3504 } else { | |
| 3505 if { $options_page_data(no_editor) } { | |
| 3506 $toplevel.message configure -text "" | |
| 3507 set options_page_data(no_editor) 0 | |
| 3508 } | |
| 3509 foreach button $options_page_data(buttons) { | |
| 3510 $button configure -state normal | |
| 3511 } | |
| 3512 } | |
| 3513 } | |
| 3514 | |
| 3515 # This routine gets invoked to edit a header file. It simply | |
| 3516 # executes the current editor in the background. No attempt is | |
| 3517 # made to wait for command completion, to prevent a single file | |
| 3518 # from being edited multiple times, or anything like that. | |
| 3519 | |
| 3520 proc pkgconf::nbpage_options_edit { filename } { | |
| 3521 | |
| 3522 variable editor | |
| 3523 variable build_tree | |
| 3524 | |
| 3525 run_command pkgconf::nbpage_options_ignore $editor [file join $build_tree pkgconf $filename] | |
| 3526 } | |
| 3527 | |
| 3528 # This callback gets invoked from the run_command code whenever the | |
| 3529 # editor sends output. In the case of emacsclient such output | |
| 3530 # is the unfortunate string "Waiting for Emacs...Done". In the case | |
| 3531 # of xterm -e vi there is no output. | |
| 3532 # | |
| 3533 # On the whole it is better to ignore the output. This may mean | |
| 3534 # that warning or error messages get discared. | |
| 3535 | |
| 3536 proc pkgconf::nbpage_options_ignore { msg } { | |
| 3537 | |
| 3538 } | |
| 3539 | |
| 3540 # }}} | |
| 3541 # {{{ Flags page | |
| 3542 | |
| 3543 # ---------------------------------------------------------------------------- | |
| 3544 # The flags page. This consists of a big grid, arranged vertically into | |
| 3545 # five separate categories of flags. Within each category there is a | |
| 3546 # label identifying the category and four separate entry fields for the | |
| 3547 # various variables. | |
| 3548 # | |
| 3549 # The data for a given flag can come from two sources. The default value | |
| 3550 # comes from the targets file, and in most cases this will be an empty | |
| 3551 # string. Alternatively the user can overwrite it, e.g. as a command | |
| 3552 # line argument or in the GUI, in which case the changed information | |
| 3553 # gets saved in the pkgconf save file. | |
| 3554 # | |
| 3555 | |
| 3556 proc pkgconf::nbpage_flags_initialise { win } { | |
| 3557 | |
| 3558 variable flags_page_data | |
| 3559 variable known_compiler_flags | |
| 3560 variable config_data | |
| 3561 | |
| 3562 # Start by creating array entries for all the known compiler flags. | |
| 3563 if { ($config_data(target) != "") && ($config_data(platform) != "") } { | |
| 3564 foreach flag $known_compiler_flags { | |
| 3565 set flags_page_data($flag) [get_platform_cflags $config_data(target) $config_data(platform) $flag] | |
| 3566 } | |
| 3567 } else { | |
| 3568 foreach flag $known_compiler_flags { | |
| 3569 set flags_page_data($flag) "" | |
| 3570 } | |
| 3571 } | |
| 3572 | |
| 3573 # If the current configuration information contains any compiler flags, | |
| 3574 # update the appropriate variable. | |
| 3575 foreach flag $known_compiler_flags { | |
| 3576 if { [info exists config_data(cflags,$flag)] } { | |
| 3577 set flags_page_data($flag) $config_data(cflags,$flag) | |
| 3578 } | |
| 3579 } | |
| 3580 | |
| 3581 # Keep track of which target and platform the current settings correspond to. | |
| 3582 set flags_page_data(target) $config_data(target) | |
| 3583 set flags_page_data(platform) $config_data(platform) | |
| 3584 | |
| 3585 # Time to actually create the interface. | |
| 3586 # Again this tab uses a frame inside a scrolled canvas. | |
| 3587 scrollbar $win.scrollbar -command "$win.viewport yview" -orient vertical | |
| 3588 pack $win.scrollbar -side right -fill y | |
| 3589 | |
| 3590 canvas $win.viewport -height 10m -yscrollcommand "$win.scrollbar set" | |
| 3591 pack $win.viewport -fill both -expand 1 -padx 20 -pady 20 | |
| 3592 | |
| 3593 frame $win.viewport.form | |
| 3594 $win.viewport create window 0 0 -anchor nw -window $win.viewport.form | |
| 3595 | |
| 3596 bind $win.viewport.form <Configure> "pkgconf::nbpage_form_resized $win" | |
| 3597 | |
| 3598 # Now fill in the form with details of all the flags. | |
| 3599 # These are arranged in a simple grid. | |
| 3600 set form $win.viewport.form | |
| 3601 set row 0 | |
| 3602 | |
| 3603 grid columnconfigure $form 1 -weight 1 | |
| 3604 label $form.archflags -text "Architecture-related compiler flags" | |
| 3605 grid $form.archflags -row $row -column 0 -columnspan 2 -sticky w | |
| 3606 incr row | |
| 3607 foreach flag { ARCHFLAGS CARCHFLAGS CXXARCHFLAGS LDARCHFLAGS } { | |
| 3608 label $form.label-$flag -text $flag | |
| 3609 grid $form.label-$flag -row $row -column 0 -sticky w | |
| 3610 entry $form.entry-$flag -textvariable pkgconf::flags_page_data($flag) -width 60 | |
| 3611 grid $form.entry-$flag -row $row -column 1 -sticky we | |
| 3612 incr row | |
| 3613 } | |
| 3614 | |
| 3615 label $form.errflags -text "Warnings and errors" | |
| 3616 grid $form.errflags -row $row -column 0 -columnspan 2 -sticky w | |
| 3617 incr row | |
| 3618 foreach flag { ERRFLAGS CERRFLAGS CXXERRFLAGS LDERRFLAGS } { | |
| 3619 label $form.label-$flag -text $flag | |
| 3620 grid $form.label-$flag -row $row -column 0 -sticky w | |
| 3621 entry $form.entry-$flag -textvariable pkgconf::flags_page_data($flag) | |
| 3622 grid $form.entry-$flag -row $row -column 1 -sticky we | |
| 3623 incr row | |
| 3624 } | |
| 3625 | |
| 3626 label $form.dbgflags -text "Debugging and optimization levels" | |
| 3627 grid $form.dbgflags -row $row -column 0 -columnspan 2 -sticky w | |
| 3628 incr row | |
| 3629 foreach flag { DBGFLAGS CDBGFLAGS CXXDBGFLAGS LDDBGFLAGS } { | |
| 3630 label $form.label-$flag -text $flag | |
| 3631 grid $form.label-$flag -row $row -column 0 -sticky w | |
| 3632 entry $form.entry-$flag -textvariable pkgconf::flags_page_data($flag) | |
| 3633 grid $form.entry-$flag -row $row -column 1 -sticky we | |
| 3634 incr row | |
| 3635 } | |
| 3636 | |
| 3637 label $form.langflags -text "Language-related flags" | |
| 3638 grid $form.langflags -row $row -column 0 -columnspan 2 -sticky w | |
| 3639 incr row | |
| 3640 foreach flag { LANGFLAGS CLANGFLAGS CXXLANGFLAGS LDLANGFLAGS } { | |
| 3641 label $form.label-$flag -text $flag | |
| 3642 grid $form.label-$flag -row $row -column 0 -sticky w | |
| 3643 entry $form.entry-$flag -textvariable pkgconf::flags_page_data($flag) | |
| 3644 grid $form.entry-$flag -row $row -column 1 -sticky we | |
| 3645 incr row | |
| 3646 } | |
| 3647 | |
| 3648 label $form.extraflags -text "Miscellaneous" | |
| 3649 grid $form.extraflags -row $row -column 0 -columnspan 2 -sticky w | |
| 3650 incr row | |
| 3651 foreach flag { EXTRAFLAGS CEXTRAFLAGS CXXEXTRAFLAGS LDEXTRAFLAGS } { | |
| 3652 label $form.label-$flag -text $flag | |
| 3653 grid $form.label-$flag -row $row -column 0 -sticky w | |
| 3654 entry $form.entry-$flag -textvariable pkgconf::flags_page_data($flag) | |
| 3655 grid $form.entry-$flag -row $row -column 1 -sticky we | |
| 3656 incr row | |
| 3657 } | |
| 3658 } | |
| 3659 | |
| 3660 # | |
| 3661 # There is nothing to be done on entry to this tab. If the target architecture | |
| 3662 # has changed then there will have been a separate call to update_compiler_flags | |
| 3663 # below. This cannot be delayed until the enter call because there is no | |
| 3664 # guarantee that the user will switch to the flags tab after changing target | |
| 3665 # architecture. | |
| 3666 # | |
| 3667 proc pkgconf::nbpage_flags_enter { win } { | |
| 3668 } | |
| 3669 | |
| 3670 # | |
| 3671 # On leaving the page it is necessary to check for any flags that are | |
| 3672 # different from the default settings, and update the config_data | |
| 3673 # settings appropriately. | |
| 3674 # | |
| 3675 proc pkgconf::nbpage_flags_leave { win } { | |
| 3676 | |
| 3677 variable config_data | |
| 3678 variable flags_page_data | |
| 3679 variable known_compiler_flags | |
| 3680 | |
| 3681 if { ($config_data(target) == "") && ($config_data(platform) == "") } { | |
| 3682 | |
| 3683 # If no target has been defined then it is not possible to compare | |
| 3684 # with the default setting. All that can be done is set or clear | |
| 3685 # the current config setting. | |
| 3686 foreach flag $known_compiler_flags { | |
| 3687 if { $flags_page_data($flag) == "" } { | |
| 3688 if { [info exists config_data(cflags,$flag) ] } { | |
| 3689 unset config_data(cflags,$flag) | |
| 3690 } | |
| 3691 } else { | |
| 3692 set config_data(cflags,$flag) $flags_page_data($flag) | |
| 3693 } | |
| 3694 } | |
| 3695 } else { | |
| 3696 | |
| 3697 # For any flag which currently has default settings, | |
| 3698 # clear the appropriate config_data() entry. Otherwise store | |
| 3699 # the flag data. | |
| 3700 foreach flag $known_compiler_flags { | |
| 3701 | |
| 3702 if { $flags_page_data($flag) == [get_platform_cflags $config_data(target) $config_data(platform) $flag] } { | |
| 3703 if { [info exists config_data(cflags,$flag) ] } { | |
| 3704 unset config_data(cflags,$flag) | |
| 3705 } | |
| 3706 } else { | |
| 3707 set config_data(cflags,$flag) $flags_page_data($flag) | |
| 3708 } | |
| 3709 } | |
| 3710 } | |
| 3711 } | |
| 3712 | |
| 3713 # | |
| 3714 # When the target architecture changes it is necessary to update the compiler | |
| 3715 # flags appropriately. Basically any flag that was defined by the old target | |
| 3716 # has to be cleared, and then any flag defined for the new target has to be | |
| 3717 # installed. There is a risk that some user changes will be lost, but there | |
| 3718 # is no easy solution to this. | |
| 3719 # | |
| 3720 proc pkgconf::update_compiler_flags { } { | |
| 3721 | |
| 3722 variable config_data | |
| 3723 variable flags_page_data | |
| 3724 variable known_compiler_flags | |
| 3725 | |
| 3726 foreach flag $known_compiler_flags { | |
| 3727 | |
| 3728 if { ($flags_page_data(target) == "") || ($flags_page_data(platform) == "") } { | |
| 3729 set old_default_flag "" | |
| 3730 } else { | |
| 3731 set old_default_flag [get_platform_cflags $flags_page_data(target) $flags_page_data(platform) $flag] | |
| 3732 } | |
| 3733 set new_default_flag [get_platform_cflags $config_data(target) $config_data(platform) $flag] | |
| 3734 | |
| 3735 # If there is no change to the default flags leave things well alone. | |
| 3736 # That way user changes will not get overwritten. | |
| 3737 if { $old_default_flag == $new_default_flag } { | |
| 3738 continue | |
| 3739 } | |
| 3740 | |
| 3741 # Otherwise always install the new settings, which may mean eliminating | |
| 3742 # user changes. | |
| 3743 set flags_page_data($flag) $new_default_flag | |
| 3744 if { [info exists config_data(cflags,$flag)] } { | |
| 3745 unset config_data(cflags,$flag) | |
| 3746 } | |
| 3747 } | |
| 3748 | |
| 3749 set flags_page_data(target) $config_data(target) | |
| 3750 set flags_page_data(platform) $config_data(platform) | |
| 3751 } | |
| 3752 | |
| 3753 # }}} | |
| 3754 # {{{ Build page | |
| 3755 | |
| 3756 # ---------------------------------------------------------------------------- | |
| 3757 # The build page. This consists of the following buttons, gridded, | |
| 3758 # with explanatory text. | |
| 3759 # | |
| 3760 # 1) Update build tree | |
| 3761 # 2) Make | |
| 3762 # 3) Make tests | |
| 2 | 3763 # 4) Make misc |
| 3764 # 5) Make clean | |
| 0 | 3765 # |
| 3766 # The make buttons should be disabled if the build tree is out of date. | |
| 3767 # This is controlled by the variable build_tree_needs_update, which | |
| 3768 # may have got set during the options page creation. An additional | |
| 3769 # check that needs to be made here is whether or not the makefile | |
| 3770 # exists. If the current config data does not specify the target | |
| 3771 # then even the "Update tree" button must be disabled. | |
| 3772 # | |
| 3773 # Whenever a make is in progress all the buttons should be disabled. | |
| 3774 # | |
| 3775 | |
| 3776 proc pkgconf::nbpage_build_initialise { win } { | |
| 3777 | |
| 3778 # Update the variable build_tree_needs_update if there is no | |
| 3779 # makefile in the build tree. | |
| 3780 variable build_tree_needs_update | |
| 3781 variable component_repository | |
| 3782 variable build_tree | |
| 3783 variable config_data | |
| 3784 | |
| 3785 if { [file isfile [file join $build_tree makefile]] == 0 } { | |
| 3786 set build_tree_needs_update 1 | |
| 3787 } | |
| 3788 if { ($config_data(target) == "") || ($config_data(platform) == "") || ($config_data(startup) == "") } { | |
| 3789 set build_tree_needs_update 1 | |
| 3790 } | |
| 3791 | |
| 3792 # Create three labels identifying the various trees. | |
| 3793 frame $win.top | |
| 3794 label $win.top.source_label -anchor w -text "Component repository:" | |
| 3795 label $win.top.source_value -anchor w -text "$component_repository" | |
| 3796 label $win.top.build_label -anchor w -text "Current build tree:" | |
| 3797 label $win.top.build_value -anchor w -text "$build_tree" | |
| 3798 label $win.top.install_label -anchor w -text "Current install tree:" | |
| 3799 label $win.top.install_value -anchor w -text "$config_data(prefix)" | |
| 3800 grid $win.top.source_label -row 0 -column 0 -sticky w | |
| 3801 grid $win.top.source_value -row 0 -column 1 -sticky we | |
| 3802 grid $win.top.build_label -row 1 -column 0 -sticky w | |
| 3803 grid $win.top.build_value -row 1 -column 1 -sticky we | |
| 3804 grid $win.top.install_label -row 2 -column 0 -sticky w | |
| 3805 grid $win.top.install_value -row 2 -column 1 -sticky we | |
| 3806 grid columnconfigure $win.top 1 -weight 1 | |
| 3807 pack $win.top -side top -fill x -padx 5 -pady 5 | |
| 3808 | |
| 3809 # Create a grid with the four buttons and with explanatory | |
| 3810 # messages. | |
| 3811 frame $win.grid | |
| 3812 pack $win.grid -fill both -expand 1 | |
| 3813 set win $win.grid | |
| 3814 | |
| 3815 button $win.tree -text "Update tree" -command pkgconf::nbpage_build_update_tree | |
| 3816 button $win.make -text "Make" -command pkgconf::nbpage_build_make | |
| 3817 button $win.tests -text "Make tests" -command pkgconf::nbpage_build_tests | |
| 2 | 3818 button $win.misc -text "Make misc" -command pkgconf::nbpage_build_misc |
| 0 | 3819 button $win.clean -text "Make clean" -command pkgconf::nbpage_build_clean |
| 3820 | |
| 3821 if { ($config_data(target) == "" ) || ($config_data(platform) == "") || ($config_data(startup) == "") } { | |
| 3822 $win.tree configure -state disabled | |
| 3823 } | |
| 3824 if { $build_tree_needs_update } { | |
| 3825 $win.make configure -state disabled | |
| 3826 $win.tests configure -state disabled | |
| 2 | 3827 $win.misc configure -state disabled |
| 0 | 3828 $win.clean configure -state disabled |
| 3829 } | |
| 3830 grid $win.tree -row 0 -column 0 -sticky we -padx 5 -pady 5 | |
| 3831 grid $win.make -row 1 -column 0 -sticky we -padx 5 -pady 5 | |
| 3832 grid $win.tests -row 2 -column 0 -sticky we -padx 5 -pady 5 | |
| 2 | 3833 grid $win.misc -row 3 -column 0 -sticky we -padx 5 -pady 5 |
| 3834 grid $win.clean -row 4 -column 0 -sticky we -padx 5 -pady 5 | |
| 0 | 3835 |
| 3836 message $win.treemsg -anchor w -justify left -width 300 -text \ | |
| 3837 "Create or update the build and install trees." | |
| 3838 message $win.makemsg -anchor w -justify left -width 300 -text \ | |
| 3839 "Build the current configuration, leaving libraries and header files in the install tree." | |
| 3840 message $win.testsmsg -anchor w -justify left -width 300 -text \ | |
| 3841 "Build the test executables for the current configuration. These executables will be\ | |
| 3842 placed in the install tree." | |
| 2 | 3843 message $win.miscmsg -anchor w -justify left -width 300 -text \ |
| 3844 "Build the misc executables for the current configuration. These executables will be\ | |
| 3845 placed in the misc directory." | |
| 0 | 3846 message $win.cleanmsg -anchor w -justify left -width 300 -text \ |
| 3847 "Perform a clean-up operation in the build and install trees." | |
| 3848 grid $win.treemsg -row 0 -column 1 -sticky we | |
| 3849 grid $win.makemsg -row 1 -column 1 -sticky we | |
| 3850 grid $win.testsmsg -row 2 -column 1 -sticky we | |
| 2 | 3851 grid $win.miscmsg -row 3 -column 1 -sticky we |
| 3852 grid $win.cleanmsg -row 4 -column 1 -sticky we | |
| 0 | 3853 grid columnconfigure $win 1 -weight 1 |
| 3854 } | |
| 3855 | |
| 3856 # The build page needs refreshing every time that the user changes the | |
| 3857 # target or one of the packages. The important question is whether or | |
| 3858 # not the build tree needs to be updated before any builds can take place. | |
| 3859 # Of course the build tree can only be generated if the target architecture | |
| 3860 # is known. | |
| 3861 | |
| 3862 proc pkgconf::nbpage_build_enter { win } { | |
| 3863 | |
| 3864 variable build_tree_needs_update | |
| 3865 variable build_frame | |
| 3866 variable toplevel | |
| 3867 | |
| 3868 if { $build_tree_needs_update } { | |
| 3869 $build_frame.grid.make configure -state disabled | |
| 3870 $build_frame.grid.tests configure -state disabled | |
| 2 | 3871 $build_frame.grid.misc configure -state disabled |
| 0 | 3872 $build_frame.grid.clean configure -state disabled |
| 3873 | |
| 3874 set_status_line "The build tree must be updated before this configuration can be built." | |
| 3875 } else { | |
| 3876 clear_status_line | |
| 3877 } | |
| 3878 | |
| 3879 variable config_data | |
| 3880 if { ($config_data(target) == "") || ($config_data(platform) == "") || ($config_data(startup) == "") } { | |
| 3881 $build_frame.grid.tree configure -state disabled | |
| 3882 set_status_line "The target hardware has not yet been selected." | |
| 3883 } else { | |
| 3884 $build_frame.grid.tree configure -state normal | |
| 3885 } | |
| 3886 } | |
| 3887 | |
| 3888 # | |
| 3889 # There are no actual settings that can be changed in this tab, | |
| 3890 # so no updates are required. | |
| 3891 # | |
| 3892 proc pkgconf::nbpage_build_leave { win } { | |
| 3893 } | |
| 3894 | |
| 3895 # | |
| 3896 # This callback function is invoked during the various makes. | |
| 3897 # If it is passed an empty string then the command has finished and | |
| 3898 # all the buttons can be reenabled. Otherwise it is necessary to send | |
| 3899 # some text to the output window. | |
| 3900 | |
| 3901 proc pkgconf::nbpage_build_handle_output { mesg } { | |
| 3902 | |
| 3903 if { $mesg == "" } { | |
| 3904 output_add_text "Build has finished.\n" | |
| 3905 nbpage_build_control_buttons 1 | |
| 3906 } else { | |
| 3907 output_add_text "$mesg\n" | |
| 3908 } | |
| 3909 } | |
| 3910 | |
| 3911 | |
| 3912 # This utility is used to control all the buttons in the build frame. | |
| 3913 proc pkgconf::nbpage_build_control_buttons { on } { | |
| 3914 | |
| 3915 variable build_frame | |
| 3916 set buttons [grid slaves $build_frame.grid -column 0] | |
| 3917 foreach button $buttons { | |
| 3918 if { $on } { | |
| 3919 $button configure -state normal | |
| 3920 } else { | |
| 3921 $button configure -state disabled | |
| 3922 } | |
| 3923 } | |
| 3924 } | |
| 3925 | |
| 3926 # | |
| 3927 # These functions get invoked for the buttons in the build page. | |
| 3928 # | |
| 3929 proc pkgconf::nbpage_build_update_tree { } { | |
| 3930 | |
| 3931 variable toplevel | |
| 3932 variable options_page_needs_refresh | |
| 3933 variable build_tree_needs_update | |
| 3934 | |
| 3935 nbpage_build_control_buttons 0 | |
| 3936 produce_build_tree | |
| 3937 nbpage_build_control_buttons 1 | |
| 3938 $toplevel.message configure -text "" | |
| 3939 set options_page_needs_refresh 1 | |
| 3940 set build_tree_needs_update 0 | |
| 3941 } | |
| 3942 | |
| 3943 proc pkgconf::nbpage_build_make { } { | |
| 3944 | |
| 3945 variable build_tree | |
| 3946 variable config_data | |
| 3947 | |
| 3948 nbpage_build_control_buttons 0 | |
| 3949 output_add_text "Building current configuration.\nBuild tree is $build_tree.\nInstall tree is $config_data(prefix)\n" | |
| 3950 run_command pkgconf::nbpage_build_handle_output make -C $build_tree | |
| 3951 } | |
| 3952 | |
| 3953 proc pkgconf::nbpage_build_tests { } { | |
| 3954 | |
| 3955 variable build_tree | |
| 3956 variable config_data | |
| 3957 nbpage_build_control_buttons 0 | |
| 3958 output_add_text \ | |
| 3959 "Building test executables.\nBuild tree is $build_tree\nInstall tree is $config_data(prefix)\n" | |
| 3960 run_command pkgconf::nbpage_build_handle_output make -C $build_tree tests | |
| 3961 } | |
| 3962 | |
| 2 | 3963 proc pkgconf::nbpage_build_misc { } { |
| 3964 | |
| 3965 variable build_tree | |
| 3966 variable config_data | |
| 3967 nbpage_build_control_buttons 0 | |
| 3968 output_add_text \ | |
| 3969 "Building misc executables.\nBuild tree is $build_tree\nInstall tree is $config_data(prefix)\n" | |
| 3970 run_command pkgconf::nbpage_build_handle_output make -C $build_tree misc | |
| 3971 } | |
| 3972 | |
| 0 | 3973 proc pkgconf::nbpage_build_clean { } { |
| 3974 | |
| 3975 variable build_tree | |
| 3976 nbpage_build_control_buttons 0 | |
| 3977 output_add_text "Cleaning build tree $build_tree.\n" | |
| 3978 run_command pkgconf::nbpage_build_handle_output make -C $build_tree clean | |
| 3979 } | |
| 3980 | |
| 3981 # }}} | |
| 3982 | |
| 3983 # }}} | |
| 3984 # {{{ Output window | |
| 3985 | |
| 3986 # ---------------------------------------------------------------------------- | |
| 3987 # These routines take care of the output window. There are two variables | |
| 3988 # describing the current state of the window: output_docked and | |
| 3989 # output_visible. There are four commands which can be invoked from | |
| 3990 # buttons, and a further command which can be invoked from the windows | |
| 3991 # menu. There is also a routine which can be used to add text to | |
| 3992 # the current output window, making it visible if necessary. | |
| 3993 # | |
| 3994 # The packing of the main .pkgconf window has to be redone every time | |
| 3995 # the output window is displayed or hidden, if the output window is | |
| 3996 # currently docked. To avoid duplicating code there are auxiliary | |
| 3997 # routine output_make_visible and output_make_invisible. | |
| 3998 # | |
| 3999 | |
| 4000 # This routine is invoked from the View menu. Its purpose is to | |
| 4001 # hide or display the output window, depending on the value of | |
| 4002 # output_visible. Note that output_visible indicates the desired | |
| 4003 # state of affairs, not the actual state of affairs. | |
| 4004 # | |
| 4005 proc pkgconf::output_menu { } { | |
| 4006 | |
| 4007 variable output_visible | |
| 4008 | |
| 4009 if { $output_visible == 0 } { | |
| 4010 output_make_invisible | |
| 4011 } else { | |
| 4012 output_make_visible | |
| 4013 } | |
| 4014 } | |
| 4015 | |
| 4016 proc pkgconf::output_make_visible { } { | |
| 4017 | |
| 4018 variable output_docked | |
| 4019 variable toplevel | |
| 4020 | |
| 4021 if { $output_docked == 0 } { | |
| 4022 # The output is in a separate window. Deiconifying it should make | |
| 4023 # it visible. | |
| 4024 wm deiconify .pkgconf_output | |
| 4025 } else { | |
| 4026 # It is necessary to repack the main window. This time it is the | |
| 4027 # output frame that should expand. | |
| 4028 pack forget $toplevel.notebook $toplevel.message | |
| 4029 pack $toplevel.notebook -side top -fill x | |
| 4030 pack $toplevel.message -side top -fill x | |
| 4031 pack $toplevel.output -side top -fill both -expand 1 | |
| 4032 } | |
| 4033 } | |
| 4034 | |
| 4035 proc pkgconf::output_make_invisible { } { | |
| 4036 | |
| 4037 variable output_docked | |
| 4038 variable toplevel | |
| 4039 | |
| 4040 if { $output_docked == 0 } { | |
| 4041 # The output is in a separate window, just withdraw it. | |
| 4042 wm withdraw .pkgconf_output | |
| 4043 } else { | |
| 4044 # It is necessary to repack the .pkgconf window without | |
| 4045 # the output window. This time it is the notebook which | |
| 4046 # should expand to fit all available space. | |
| 4047 pack forget $toplevel.notebook $toplevel.message $toplevel.output | |
| 4048 pack $toplevel.notebook -side top -fill both -expand 1 | |
| 4049 pack $toplevel.message -side top -fill x | |
| 4050 } | |
| 4051 } | |
| 4052 | |
| 4053 # | |
| 4054 # This routine is invoked when the output window is already visible | |
| 4055 # and the user has pressed the button in that window to make it | |
| 4056 # invisible. | |
| 4057 # | |
| 4058 proc pkgconf::output_hide_window { } { | |
| 4059 | |
| 4060 variable output_visible | |
| 4061 variable toplevel | |
| 4062 ASSERT { $output_visible != 0 } | |
| 4063 | |
| 4064 output_make_invisible | |
| 4065 set output_visible 0 | |
| 4066 } | |
| 4067 | |
| 4068 # | |
| 4069 # Switch between a docked and an undocked window. The window must | |
| 4070 # currently be visible. Any text must be copied across from | |
| 4071 # one widget to the other. | |
| 4072 # | |
| 4073 proc pkgconf::output_undock_window { } { | |
| 4074 | |
| 4075 variable output_visible | |
| 4076 variable output_docked | |
| 4077 variable toplevel | |
| 4078 | |
| 4079 ASSERT { $output_visible != 0 } | |
| 4080 | |
| 4081 output_make_invisible | |
| 4082 | |
| 4083 $toplevel.output.text configure -state normal | |
| 4084 .pkgconf_output.text configure -state normal | |
| 4085 | |
| 4086 if { $output_docked == 0 } { | |
| 4087 $toplevel.output.text insert end [.pkgconf_output.text get 1.0 "end - 1 chars"] | |
| 4088 .pkgconf_output.text delete 1.0 end | |
| 4089 set output_docked 1 | |
| 4090 } else { | |
| 4091 .pkgconf_output.text insert end [$toplevel.output.text get 1.0 "end - 1 chars"] | |
| 4092 $toplevel.output.text delete 1.0 end | |
| 4093 set output_docked 0 | |
| 4094 } | |
| 4095 | |
| 4096 $toplevel.output.text configure -state disabled | |
| 4097 .pkgconf_output.text configure -state disabled | |
| 4098 | |
| 4099 output_make_visible | |
| 4100 } | |
| 4101 | |
| 4102 # | |
| 4103 # Clear the text window, which should currently be visible. | |
| 4104 # | |
| 4105 proc pkgconf::output_clear_window { } { | |
| 4106 | |
| 4107 variable output_visible | |
| 4108 variable output_docked | |
| 4109 variable toplevel | |
| 4110 | |
| 4111 ASSERT { $output_visible != 0 } | |
| 4112 if { $output_docked == 0 } { | |
| 4113 .pkgconf_output.text configure -state normal | |
| 4114 .pkgconf_output.text delete 1.0 end | |
| 4115 .pkgconf_output.text configure -state disabled | |
| 4116 } else { | |
| 4117 $toplevel.output.text configure -state normal | |
| 4118 $toplevel.output.text delete 1.0 end | |
| 4119 $toplevel.output.text configure -state disabled | |
| 4120 } | |
| 4121 } | |
| 4122 | |
| 4123 # | |
| 4124 # Save the current contents of the text window to a file. | |
| 4125 # | |
| 4126 proc pkgconf::output_save { } { | |
| 4127 | |
| 4128 variable build_tree | |
| 4129 variable output_docked | |
| 4130 variable toplevel | |
| 4131 | |
| 4132 set filename [tk_getSaveFile -initialdir $build_tree -initialfile pkgconf.log \ | |
| 4133 -parent [expr { $output_docked ? "$toplevel" : ".pkgconf_output" } ] ] | |
| 4134 | |
| 4135 if { $filename == "" } { | |
| 4136 return | |
| 4137 } | |
| 4138 | |
| 4139 if { [catch { | |
| 4140 set file [open $filename w] | |
| 4141 if { $output_docked == 0 } { | |
| 4142 puts $file [.pkgconf_output.text get 1.0 "end - 1 chars"] | |
| 4143 } else { | |
| 4144 puts $file [$toplevel.output.text get 1.0 "end - 1 chars"] | |
| 4145 } | |
| 4146 close $file | |
| 4147 } message] != 0 } { | |
| 4148 warning "Failed to save build output to $filename: $message" | |
| 4149 } | |
| 4150 } | |
| 4151 | |
| 4152 # | |
| 4153 # Output some text. This gets invoked mainly during builds, but also | |
| 4154 # by the report() function when generating a build tree. It is | |
| 4155 # necessary to make sure that the text widget is visible. | |
| 4156 # | |
| 4157 proc pkgconf::output_add_text { msg } { | |
| 4158 | |
| 4159 variable output_visible | |
| 4160 variable output_docked | |
| 4161 variable toplevel | |
| 4162 | |
| 4163 if { $output_visible == 0 } { | |
| 4164 output_make_visible | |
| 4165 set output_visible 1 | |
| 4166 } | |
| 4167 | |
| 4168 if { $output_docked == 0 } { | |
| 4169 .pkgconf_output.text configure -state normal | |
| 4170 .pkgconf_output.text insert end $msg | |
| 4171 .pkgconf_output.text configure -state disabled | |
| 4172 .pkgconf_output.text see end | |
| 4173 } else { | |
| 4174 $toplevel.output.text configure -state normal | |
| 4175 $toplevel.output.text insert end $msg | |
| 4176 $toplevel.output.text configure -state disabled | |
| 4177 $toplevel.output.text see end | |
| 4178 } | |
| 4179 } | |
| 4180 | |
| 4181 # }}} | |
| 4182 # {{{ Status line | |
| 4183 | |
| 4184 # ---------------------------------------------------------------------------- | |
| 4185 # Some utility routines to update the status line. | |
| 4186 | |
| 4187 proc pkgconf::set_status_line { text } { | |
| 4188 variable toplevel | |
| 4189 $toplevel.message configure -text $text | |
| 4190 } | |
| 4191 | |
| 4192 proc pkgconf::clear_status_line { } { | |
| 4193 variable toplevel | |
| 4194 $toplevel.message configure -text "" | |
| 4195 } | |
| 4196 | |
| 4197 # }}} | |
| 4198 # {{{ Diagnostics | |
| 4199 | |
| 4200 # ---------------------------------------------------------------------------- | |
| 4201 # GUI versions of the same routines. For now tk_messageBox will have | |
| 4202 # to suffice for fatal error | |
| 4203 # | |
| 4204 proc pkgconf::gui_fatal_error_handler { msg } { | |
| 4205 | |
| 4206 variable toplevel | |
| 4207 | |
| 4208 if { [winfo exists $toplevel] } { | |
| 4209 tk_messageBox -parent $toplevel -icon error -title "pkgconf: fatal error" -type ok -message $msg | |
| 4210 } else { | |
| 4211 tk_messageBox -icon error -title "pkgconf: fatal error" -type ok -message $msg | |
| 4212 } | |
| 4213 exit 1 | |
| 4214 } | |
| 4215 | |
| 4216 proc pkgconf::gui_warning_handler { msg } { | |
| 4217 | |
| 4218 variable toplevel | |
| 4219 | |
| 4220 if { [winfo exists $toplevel] } { | |
| 4221 tk_messageBox -parent $toplevel -icon error -title "pkgconf: fatal error" -type ok -message $msg | |
| 4222 } else { | |
| 4223 tk_messageBox -icon error -title "pkgconf: fatal error" -type ok -message $msg | |
| 4224 } | |
| 4225 } | |
| 4226 | |
| 4227 proc pkgconf::gui_report_handler { msg } { | |
| 4228 | |
| 4229 output_add_text "$msg\n" | |
| 4230 update | |
| 4231 } | |
| 4232 | |
| 4233 # }}} | |
| 4234 # {{{ Executing external commands | |
| 4235 | |
| 4236 # ---------------------------------------------------------------------------- | |
| 4237 # This code is responsible for executing external commands. The broken nature | |
| 4238 # of pipes under Windows makes this somewhat more difficult than it should be. | |
| 4239 | |
| 4240 proc pkgconf::run_command { callback command args } { | |
| 4241 | |
| 4242 # Start up the specified command. Actually the main command is run such that | |
| 4243 # both stdout and stderr are piped into cat, thus making sure that the | |
| 4244 # stderr output is not discarded. | |
| 4245 set result [catch { set pipe [open "|[concat $command $args] 2>@ stdout" "r"] } message] | |
| 4246 if { $result != 0 } { | |
| 4247 warning "Failed to execute $command: $message" | |
| 4248 return | |
| 4249 } | |
| 4250 | |
| 4251 # Now set the pipe to non-blocking, to prevent the whole GUI from | |
| 4252 # locking up by accident. | |
| 4253 fconfigure $pipe -blocking 0 | |
| 4254 | |
| 4255 # Set up an event handler to read back any output. | |
| 4256 fileevent $pipe readable [list pkgconf::handle_command_output $pipe $callback] | |
| 4257 } | |
| 4258 | |
| 4259 # | |
| 4260 # This routine gets invoked whenever there may be data waiting on the | |
| 4261 # pipe. | |
| 4262 # | |
| 4263 proc pkgconf::handle_command_output { pipe callback } { | |
| 4264 | |
| 4265 set data "" | |
| 4266 set count [gets $pipe data] | |
| 4267 if { $count > 0 } { | |
| 4268 $callback $data | |
| 4269 } elseif { [eof $pipe] } { | |
| 4270 catch { close $pipe } | |
| 4271 $callback "" | |
| 4272 } | |
| 4273 } | |
| 4274 | |
| 4275 # }}} | |
| 4276 | |
| 4277 # }}} | |
| 4278 # {{{ Produce build tree | |
| 4279 | |
| 4280 # {{{ Description | |
| 4281 | |
| 4282 # ---------------------------------------------------------------------------- | |
| 4283 # Producing the build tree. This requires the following information: | |
| 4284 # | |
| 4285 # 1) the location of the component repository. This should be known. | |
| 4286 # | |
| 4287 # 2) the location of the build tree. This should also be known. | |
| 4288 # | |
| 4289 # 3) full details of the target architecture. These may not have been supplied | |
| 4290 # yet, which would result in a fatal error. | |
| 4291 # | |
| 4292 # 4) details of which packages are explicitly enabled or disabled. | |
| 4293 # | |
| 4294 # 5) details of which version of each package should be used. | |
| 4295 # | |
| 4296 # 6) prefix information, i.e. where the system will be installed. | |
| 4297 # The default value "" indicates an install directory relative to the | |
| 4298 # build tree. | |
| 4299 # | |
| 4300 # This routine may be called for an empty build tree, or it | |
| 4301 # may be used to update an existing build tree. | |
| 4302 # | |
| 4303 # The steps that have to be taken are as follows: | |
| 4304 # | |
| 4305 # 1) create a pkgconf directory, which is where all the editable | |
| 4306 # header files will end up. A few other files will end up there | |
| 4307 # as well. | |
| 4308 # | |
| 4309 # 2) examine all packages, including the hal packages. For each package: | |
| 4310 # | |
| 4311 # a) if there is a src directory in the component repository, reproduce | |
| 4312 # this in the build tree. If this src directory has any | |
| 4313 # sub-directories, these have to be created as well. | |
| 4314 # | |
| 4315 # The src directory should contain a file PKGconf.mak. This has to be | |
| 4316 # copied across as makefile. There may also be PKGconf.mak files in | |
| 4317 # subdirectories which should also get copied across. Typically the | |
| 4318 # latter will be for internal development purposes. | |
| 4319 # | |
| 4320 # b) if there is an include directory in the component repository, | |
| 4321 # make a matching directory in the build tree. Ditto for any | |
| 4322 # subdirectories other than pkgconf. | |
| 4323 # | |
| 4324 # The purpose of this include directory is to allow users to make | |
| 4325 # editable copies of the header files in the build tree. A makefile | |
| 4326 # is generated in this directory which will take care of updating the | |
| 4327 # header files that actually get used for building, i.e. those in the | |
| 4328 # include directory. The header files are not actually copied across | |
| 4329 # at this point, that will happen during the first make. | |
| 4330 # | |
| 4331 # The pkgconf directory is handled differently. Every file in | |
| 4332 # pkgconf is copied across to the build tree's pkgconf directory, | |
| 4333 # unless there is already a matching file in the build tree. | |
| 4334 # This avoids overwriting edits made by the user in the build | |
| 4335 # tree. The disadvantage is that if the version in the component | |
| 4336 # repository is edited it will have to be copied by hand, or the | |
| 4337 # -force command line argument will have to be used. | |
| 4338 # | |
| 4339 # c) if there is a tests directory in the component repository, make | |
| 4340 # a matching directory in the build tree and copy | |
| 4341 # across PKGconf.mak. If this tests directory has any subdirectories | |
| 4342 # then these must be created as well. | |
| 4343 # | |
| 2 | 4344 # d) similarly for any 'misc' directories |
| 4345 # | |
| 0 | 4346 # 3) create the install directory tree, complete with lib, include, and tests |
| 4347 # directories, and the include/pkgconf sub-directory. Additional | |
| 4348 # sub-directories within include need not be generated at this point, | |
| 4349 # that happens as such sub-directories are encountered within the | |
| 4350 # component repository. | |
| 4351 # | |
| 4352 # 4) copy across the makevars file. | |
| 4353 # | |
| 4354 # 5) generate the files specific to this configuration. | |
| 4355 # | |
| 4356 # Note that subdirectories corresponding to old packages are not | |
| 4357 # deleted, they simply get ignored. Arguably this should change, | |
| 4358 # but then you run the risk of deleting user changes in a package | |
| 4359 # that has been disabled only temporarily. | |
| 4360 # | |
| 4361 | |
| 4362 # }}} | |
| 4363 # {{{ Check requirements | |
| 4364 | |
| 4365 # ---------------------------------------------------------------------------- | |
| 4366 # It is not possible to generate a build tree unless certain requirements | |
| 4367 # are satisfied. Most of these will have been checked elsewhere. | |
| 4368 # | |
| 4369 proc pkgconf::check_requirements { } { | |
| 4370 | |
| 4371 ASSERT { $pkgconf::build_tree != "" } | |
| 4372 ASSERT { $pkgconf::component_repository != "" } | |
| 4373 | |
| 4374 if { $pkgconf::component_repository == $pkgconf::build_tree } { | |
| 4375 report "Builds of eCos cannot happen in the same directory as the sources." | |
| 4376 report "Currently your build tree is $pkgconf::build_tree." | |
| 4377 report "This is the same directory as your component repository." | |
| 4378 fatal_error "Unable to proceed with builds in this directory." | |
| 4379 } | |
| 4380 | |
| 4381 if { $pkgconf::config_data(target) == "" } { | |
| 4382 fatal_error "No target architecture has been specified." | |
| 4383 } | |
| 4384 if { $pkgconf::config_data(platform) == "" } { | |
| 4385 fatal_error "No target platform has been specified." | |
| 4386 } | |
| 4387 if { $pkgconf::config_data(startup) == "" } { | |
| 4388 fatal_error "No target startup mechanism has been specified." | |
| 4389 } | |
| 4390 } | |
| 4391 | |
| 4392 # }}} | |
| 4393 # {{{ Directory and file utilities | |
| 4394 | |
| 4395 # ---------------------------------------------------------------------------- | |
| 4396 # Start with a number of utility routines to access all files in | |
| 4397 # a directory, stripping out well-known files such as makefile.am. | |
| 4398 # The routines take an optional pattern argument if only certain | |
| 4399 # files are of interest. | |
| 4400 # | |
| 4401 # Note that symbolic links are returned as well as files. | |
| 4402 # | |
| 4403 proc pkgconf::locate_files { dir { pattern "*"} } { | |
| 4404 | |
| 4405 ASSERT { $dir != "" } | |
| 4406 | |
| 4407 # Start by getting a list of all the files. | |
| 4408 set filelist [glob -nocomplain -- [file join $dir $pattern]] | |
| 4409 | |
| 4410 # Eliminate the pathnames from all of these files | |
| 4411 set filenames "" | |
| 4412 foreach file $filelist { | |
| 2 | 4413 if { [string range $file end end] != "~" } { |
| 4414 lappend filenames [file tail $file] | |
| 4415 } | |
| 0 | 4416 } |
| 4417 | |
| 4418 # Eliminate any obviously spurious entries. | |
| 4419 foreach file { CVS Makefile.am Makefile.in makefile acinclude.m4 aclocal.m4 configure.in configure } { | |
| 4420 set index [lsearch -exact $filenames $file] | |
| 4421 if { $index != -1 } { | |
| 4422 set filenames [lreplace $filenames $index $index] | |
| 4423 } | |
| 4424 } | |
| 4425 | |
| 4426 # Eliminate any subdirectories. | |
| 4427 set subdirs "" | |
| 4428 foreach name $filenames { | |
| 4429 if { [file isdir [file join $dir $name]] } { | |
| 4430 lappend subdirs $name | |
| 4431 } | |
| 4432 } | |
| 4433 foreach subdir $subdirs { | |
| 4434 set index [lsearch -exact $filenames $subdir] | |
| 4435 set filenames [lreplace $filenames $index $index] | |
| 4436 } | |
| 4437 | |
| 4438 return $filenames | |
| 4439 } | |
| 4440 | |
| 4441 # | |
| 4442 # This utility returns all sub-directories, as opposed to all files. | |
| 4443 # A variant glob pattern is used here. This version is not recursive. | |
| 4444 proc pkgconf::locate_subdirs { dir { pattern "*" }} { | |
| 4445 | |
| 4446 ASSERT { $dir != "" } | |
| 4447 | |
| 4448 set dirlist [glob -nocomplain -- [file join $dir $pattern "."]] | |
| 4449 | |
| 4450 # Eliminate the pathnames and the spurious /. at the end of each entry | |
| 4451 set dirnames "" | |
| 4452 foreach dir $dirlist { | |
| 4453 lappend dirnames [file tail [file dirname $dir]] | |
| 4454 } | |
| 4455 | |
| 4456 # Get rid of the CVS directory, if any | |
| 4457 set index [lsearch -exact $dirnames "CVS"] | |
| 4458 if { $index != -1 } { | |
| 4459 set dirnames [lreplace $dirnames $index $index] | |
| 4460 } | |
| 4461 | |
| 4462 # That should be it. | |
| 4463 return $dirnames | |
| 4464 } | |
| 4465 | |
| 4466 # | |
| 4467 # A variant which is recursive. This one does not support a pattern. | |
| 4468 # | |
| 4469 proc pkgconf::locate_all_subdirs { dir } { | |
| 4470 | |
| 4471 ASSERT { $dir != "" } | |
| 4472 | |
| 4473 set result "" | |
| 4474 foreach subdir [locate_subdirs $dir] { | |
| 4475 lappend result $subdir | |
| 4476 foreach x [locate_all_subdirs [file join $dir $subdir]] { | |
| 4477 lappend result [file join $subdir $x] | |
| 4478 } | |
| 4479 } | |
| 4480 return $result | |
| 4481 } | |
| 4482 | |
| 4483 # | |
| 4484 # This routine returns a list of all the files in a given directory and in | |
| 4485 # all subdirectories, preserving the subdirectory name. | |
| 4486 # | |
| 4487 proc pkgconf::locate_all_files { dir { pattern "*" } } { | |
| 4488 | |
| 4489 ASSERT { $dir != "" } | |
| 4490 | |
| 4491 set files [locate_files $dir $pattern] | |
| 4492 set subdirs [locate_subdirs $dir] | |
| 4493 | |
| 4494 foreach subdir $subdirs { | |
| 4495 set subfiles [locate_all_files [file join $dir $subdir] $pattern] | |
| 4496 foreach file $subfiles { | |
| 4497 lappend files [file join $subdir $file] | |
| 4498 } | |
| 4499 } | |
| 4500 | |
| 4501 return $files | |
| 4502 } | |
| 4503 | |
| 4504 # | |
| 4505 # Sometimes a directory may be empty, or contain just a CVS subdirectory, | |
| 4506 # in which case there is no point in copying it across. | |
| 4507 # | |
| 4508 proc pkgconf::is_empty_directory { dir } { | |
| 4509 | |
| 4510 ASSERT { $dir != "" } | |
| 4511 | |
| 4512 set contents [glob -nocomplain -- [file join $dir "*"]] | |
| 4513 if { [llength $contents] == 0 } { | |
| 4514 return 1 | |
| 4515 } | |
| 4516 if { ([llength $contents] == 1) && [string match {*CVS} $contents] } { | |
| 4517 return 1 | |
| 4518 } | |
| 4519 return 0 | |
| 4520 } | |
| 4521 | |
| 4522 # ---------------------------------------------------------------------------- | |
| 4523 # Given a pathname such as kernel/current/include, this routine returns | |
| 4524 # a string which points at the build tree's pkgconf directory | |
| 4525 # complete with the appropriate number of ..'s in the pathname | |
| 4526 # | |
| 4527 proc pkgconf::get_dotdots_pkgconf { dir } { | |
| 4528 | |
| 4529 set result ".." | |
| 4530 | |
| 4531 while { 1} { | |
| 4532 set dir [file dirname $dir] | |
| 4533 if { ($dir == ".") || ($dir == ":") } { | |
| 4534 break | |
| 4535 } | |
| 4536 set result [file join $result ".."] | |
| 4537 } | |
| 4538 | |
| 4539 set result [file join $result "pkgconf"] | |
| 4540 return $result | |
| 4541 } | |
| 4542 | |
| 4543 # ---------------------------------------------------------------------------- | |
| 4544 # Internally this script works using native path names. When outputting the | |
| 4545 # makefile information it is necessary to output the paths in a format that | |
| 4546 # is understood by GnuMake. | |
| 4547 # | |
| 4548 proc pkgconf::get_pathname_for_make { dir } { | |
| 4549 | |
| 4550 # First of all, handle directory separators. Under Unix this is a no-op. | |
| 4551 # Under Windows the current directory separator may be \ instead of /. | |
| 4552 # It is not entirely clear under what circumstances Tcl's "file nativename" | |
| 4553 # facility uses / vs. \, but converting all existing backslashes to | |
| 4554 # forward slashes should be harmless. | |
| 4555 if { $pkgconf::windows_host != 0 } { | |
| 4556 regsub -all -- {\\} $dir "/" dir | |
| 4557 } | |
| 4558 | |
| 4559 # Next cope with spaces in pathnames. GnuMake does not always cope | |
| 4560 # sensibly with these, even if backslash quoting is used - there | |
| 4561 # are known problems with VPATH and with the wildcard function. Under | |
| 4562 # Unix there is no simple solution, but it is unlikely that the problem | |
| 4563 # will arise in the first place. Under Windows it is quite likely that | |
| 4564 # the problem will arise, but it is possible to work around it | |
| 4565 # by using a short file name. | |
| 4566 | |
| 4567 set index [string first " " $dir] | |
| 4568 if { $index != -1 } { | |
| 4569 if { $pkgconf::windows_host != 0 } { | |
| 4570 | |
| 4571 # This call will only work if the specified object already exists. | |
| 4572 # This should not be a problem, as the pathnames are likely to | |
| 4573 # be relative to the component repository, the build tree, or the | |
| 4574 # install tree. The component repository must already exist. The | |
| 4575 # build tree must already exist, since this call will only be | |
| 4576 # invoked when generating makefiles inside the build tree. The | |
| 4577 # install tree will have been created before pkgconf/pkgconf.mak | |
| 4578 # is written out, and that is the only place that needs to refer | |
| 4579 # to it. | |
| 4580 | |
| 4581 set dir [file attribute $dir -shortname] | |
| 4582 } else { | |
| 4583 fatal_error "Cannot cope with pathname \"$pathname\".\nPathnames with spaces are not supported on this platform." | |
| 4584 } | |
| 4585 } | |
| 4586 | |
| 4587 # Other characters that have special meaning include: []*?()$^|&#<>"'`; | |
| 4588 # At least, that is the list used within vmake. $ has to be quoted as $$, | |
| 4589 # the others should be quoted with a single backslash. | |
| 4590 regsub -all -- {\$} $dir {$$} dir | |
| 4591 foreach char { {\[} {\]} {\*} {\?} {\(} {\)} {\^} {\|} {\&} {\#} {\<} {\>} {\"} {\'} {\`} {\;} } { | |
| 4592 regsub -all -- $char $dir "\\$char" dir | |
| 4593 } | |
| 4594 | |
| 4595 # Now cope with Windows drive names. | |
| 4596 # | |
| 4597 # First, volume-relative filenames. If the directory string begins with | |
| 4598 # c:xxx, as opposed to c:/xxx, it is necessary to figure out what the | |
| 4599 # current directory is on drive c: and use this as prefix for the rest | |
| 4600 # of the string. | |
| 4601 # | |
| 4602 # Once volume-relative filenames have been handled the directory may be | |
| 4603 # along the lines of c:/Cygnus/eCos/whatever. This is problematical for | |
| 4604 # GnuMake since the colon character has special meaning in various places, | |
| 4605 # e.g. to identify static pattern rules. cygwin32 uses //c/ as an alias | |
| 4606 # for c:/ wherever appropriate. | |
| 4607 if { $pkgconf::windows_host != 0 } { | |
| 4608 | |
| 4609 set dummy "" | |
| 4610 set match1 "" | |
| 4611 set match2 "" | |
| 4612 set match3 "" | |
| 4613 | |
| 4614 if { [regexp -- {^([a-zA-Z]:)(/)?(.*)} $dir dummy match1 match2 match3] == 1 } { | |
| 4615 if { $match2 == "" } { | |
| 4616 set result [catch { | |
| 4617 set current_dir [pwd] | |
| 4618 cd $match1 | |
| 4619 set dir [pwd] | |
| 4620 regsub -all -- {\\} $dir "/" dir | |
| 4621 set dir [file join $dir $match3] | |
| 4622 cd $current_dir | |
| 4623 } message] | |
| 4624 if { $result != 0 } { | |
| 4625 fatal_error "Failed to determine current directory on drive $match1" | |
| 4626 } | |
| 4627 } | |
| 4628 } | |
| 4629 | |
| 4630 if { [regexp -- {^([a-zA-Z]):} $dir dummy match1] == 1 } { | |
| 4631 set dir "//$match1[string range $dir 2 end]" | |
| 4632 } | |
| 4633 } | |
| 4634 | |
| 4635 return $dir | |
| 4636 } | |
| 4637 | |
| 4638 # ---------------------------------------------------------------------------- | |
| 4639 # Take a cygwin32 filename such as //d/tmp/pkgobj and turn it into something | |
| 4640 # acceptable to Tcl, i.e. d:/tmp/pkgobj. There are a few other complications... | |
| 4641 | |
| 4642 proc pkgconf::get_pathname_for_tcl { name } { | |
| 4643 | |
| 4644 if { $pkgconf::windows_host } { | |
| 4645 set dummy "" | |
| 4646 set match1 "" | |
| 4647 set match2 "" | |
| 4648 | |
| 4649 # If the pathname is relative to ~, expand it now. | |
| 4650 if { [regexp -- {^~(.*)$} $name dummy match1] } { | |
| 4651 set name [file nativename $name] | |
| 4652 } | |
| 4653 | |
| 4654 # For consistency, get rid of any backslashes in the pathname. | |
| 4655 # Especially since the file nativename command above may have | |
| 4656 # introduced some. | |
| 4657 regsub -all -- {\\} $name "/" name | |
| 4658 | |
| 4659 # And now replace //d/tmp/pkgobj with d:/tmp/pkgobj | |
| 4660 if { [regexp -- {^//([a-zA-Z])(/.*)$} $name dummy match1 match2] == 1 } { | |
| 4661 set name "$match1:$match2" | |
| 4662 } | |
| 4663 | |
| 4664 # If the pathname is relative to the cygwin root, get hold of the | |
| 4665 # drive name. | |
| 4666 if { ([regexp -- {^/(.*)$} $name dummy match1] == 1) && ([regexp -- {^//.*$} $name dummy] == 0) } { | |
| 4667 set saved_dir [pwd] | |
| 4668 cd / | |
| 4669 set name [file join [pwd] $match1] | |
| 4670 cd $saved_dir | |
| 4671 } | |
| 4672 } | |
| 4673 return $name | |
| 4674 } | |
| 4675 | |
| 4676 # ---------------------------------------------------------------------------- | |
| 4677 # Output a standard banner to a generated file. | |
| 4678 # | |
| 4679 | |
| 4680 proc pkgconf::output_banner { file name } { | |
| 4681 | |
| 4682 puts $file \ | |
| 4683 "# | |
| 4684 # File $name | |
| 4685 # | |
| 4686 # This file is generated automatically by the pkgconf program. | |
| 4687 # It should not be edited. Any changes made to this file may | |
| 4688 # be overwritten by pkgconf. | |
| 4689 #" | |
| 4690 } | |
| 4691 | |
| 4692 # ---------------------------------------------------------------------------- | |
| 4693 # Make sure that a newly created or copied file is writable. This operation | |
| 4694 # is platform-specific. Under Unix at most the current user is given | |
| 4695 # permission, since there does not seem to be any easy way to get hold | |
| 4696 # of the real umask. | |
| 4697 | |
| 4698 proc pkgconf::make_writable { name } { | |
| 4699 | |
| 4700 ASSERT { $name != "" } | |
| 4701 ASSERT { [file isfile $name] } | |
| 4702 | |
| 4703 if { [file writable $name] == 0 } { | |
| 4704 if { $pkgconf::windows_host != 0 } { | |
| 4705 file attributes $name -readonly 0 | |
| 4706 } else { | |
| 4707 set mask [file attributes $name -permissions] | |
| 4708 set mask [expr $mask | 0200] | |
| 4709 file attributes $name -permissions $mask | |
| 4710 } | |
| 4711 } | |
| 4712 } | |
| 4713 | |
| 4714 # }}} | |
| 4715 # {{{ Other utilities | |
| 4716 | |
| 4717 # ---------------------------------------------------------------------------- | |
| 4718 # This code works out what packages should go into the current configuration. | |
| 4719 # The rules are as follows: | |
| 4720 # | |
| 4721 # 1) all hardware-specific packages should be disabled, unless they are | |
| 4722 # mentioned explicitly in the targets file for the current target or | |
| 4723 # platform, or unless they are enabled explicitly by the user. | |
| 4724 # | |
| 4725 # 2) all other packages which are enabled by default should be included, | |
| 4726 # unless they are disabled explicitly by the user. | |
| 4727 # | |
| 4728 # 3) all non-hardware packages which are disabled by default should be | |
| 4729 # left out, unless they are enabled explicitly by the user. | |
| 4730 | |
| 4731 proc pkgconf::get_current_packages { } { | |
| 4732 | |
| 4733 ASSERT { $pkgconf::config_data(target) != "" } | |
| 4734 ASSERT { $pkgconf::config_data(platform) != "" } | |
| 4735 ASSERT { [info exists pkgconf::target_data($pkgconf::config_data(target),packages)] } | |
| 4736 ASSERT { [info exists pkgconf::target_data($pkgconf::config_data(target),$pkgconf::config_data(platform),packages)] } | |
| 4737 ASSERT { [info exists pkgconf::config_data(enabled_packages)] } | |
| 4738 ASSERT { [info exists pkgconf::config_data(disabled_packages)] } | |
| 4739 | |
| 4740 set result "" | |
| 4741 set target_packages $pkgconf::target_data($pkgconf::config_data(target),packages) | |
| 4742 set platform_packages $pkgconf::target_data($pkgconf::config_data(target),$pkgconf::config_data(platform),packages) | |
| 4743 set enabled_packages $pkgconf::config_data(enabled_packages) | |
| 4744 set disabled_packages $pkgconf::config_data(disabled_packages) | |
| 4745 | |
| 4746 foreach pkg $pkgconf::known_packages { | |
| 4747 | |
| 4748 ASSERT { [info exists pkgconf::package_data($pkg,hardware)] } | |
| 4749 | |
| 4750 if { $pkgconf::package_data($pkg,hardware) } { | |
| 4751 | |
| 4752 if { [lsearch -exact $disabled_packages $pkg] != -1 } { | |
| 4753 continue | |
| 4754 } elseif { [lsearch -exact $target_packages $pkg] != -1 } { | |
| 4755 lappend result $pkg | |
| 4756 } elseif { [lsearch -exact $platform_packages $pkg] != -1 } { | |
| 4757 lappend result $pkg | |
| 4758 } elseif { [lsearch -exact $enabled_packages $pkg] != -1 } { | |
| 4759 lappend result $pkg | |
| 4760 } | |
| 4761 | |
| 4762 } elseif { $pkgconf::package_data($pkg,default) != 0 } { | |
| 4763 if { [lsearch -exact $disabled_packages $pkg] == -1 } { | |
| 4764 lappend result $pkg | |
| 4765 } | |
| 4766 } else { | |
| 4767 if { [lsearch -exact $enabled_packages $pkg] != -1 } { | |
| 4768 lappend result $pkg | |
| 4769 } | |
| 4770 } | |
| 4771 } | |
| 4772 | |
| 4773 return $result | |
| 4774 } | |
| 4775 | |
| 4776 # ---------------------------------------------------------------------------- | |
| 4777 # A utility to determine whether or not a particular setting has changed relative to | |
| 4778 # what is currently in the build tree. Information about the latter comes from | |
| 4779 # the save file, but may not exist the first time that the build tree is generated. | |
| 4780 # The config_data array itself may be sparsely populated, especially when it comes | |
| 4781 # to compiler flags. | |
| 4782 | |
| 4783 proc pkgconf::value_has_changed { name } { | |
| 4784 | |
| 4785 ASSERT {$name != ""} | |
| 4786 | |
| 4787 if { [info exists pkgconf::config_data($name)] == 0 } { | |
| 4788 | |
| 4789 if { [info exists pkgconf::saved_data($name)] == 0 } { | |
| 4790 return 0 | |
| 4791 } else { | |
| 4792 return 1 | |
| 4793 } | |
| 4794 | |
| 4795 } else { | |
| 4796 | |
| 4797 if { [info exists pkgconf::saved_data($name)] == 0 } { | |
| 4798 return 1 | |
| 4799 } | |
| 4800 if { $pkgconf::saved_data($name) != $pkgconf::config_data($name) } { | |
| 4801 return 1 | |
| 4802 } | |
| 4803 return 0 | |
| 4804 } | |
| 4805 } | |
| 4806 | |
| 4807 # ---------------------------------------------------------------------------- | |
| 4808 # Has there been a change in the packages in the system, either which packages | |
| 4809 # are present or any of their versions ? If there has been a change in the | |
| 4810 # packages then the amount of work that has to be done inside pkgconf is | |
| 4811 # increased significantly. | |
| 4812 | |
| 4813 proc pkgconf::packages_have_changed { } { | |
| 4814 | |
| 4815 if { [value_has_changed "target"] || [value_has_changed "platform"] } { | |
| 4816 return 1 | |
| 4817 } | |
| 4818 if { [value_has_changed "enabled_packages"] || [value_has_changed "disabled_packages"] } { | |
| 4819 return 1 | |
| 4820 } | |
| 4821 foreach pkg $pkgconf::known_packages { | |
| 4822 if { [value_has_changed "$pkg,version"] } { | |
| 4823 return 1 | |
| 4824 } | |
| 4825 } | |
| 4826 | |
| 4827 return 0 | |
| 4828 } | |
| 4829 | |
| 4830 | |
| 4831 # ---------------------------------------------------------------------------- | |
| 4832 # Given the name of a package, e.g. CYGPKG_KERNEL, return something which is | |
| 4833 # more acceptable in the build tree. Creating directories and files with | |
| 4834 # names containing lots of upper case characters is unacceptable. | |
| 4835 | |
| 4836 proc pkgconf::get_build_alias { name } { | |
| 4837 | |
| 4838 ASSERT { $name != ""} | |
| 4839 | |
| 4840 set index [string first "_" $name] | |
| 4841 if { $index != -1 } { | |
| 4842 set new_name [string range $name [incr index] end] | |
| 4843 if { $new_name != "" } { | |
| 4844 set name $new_name | |
| 4845 } | |
| 4846 } | |
| 4847 set name [string tolower $name] | |
| 4848 return $name | |
| 4849 } | |
| 4850 | |
| 4851 # }}} | |
| 4852 # {{{ Process a package | |
| 4853 | |
| 4854 # ---------------------------------------------------------------------------- | |
| 4855 # Process an entire package. The header files, the src directory, and the | |
| 4856 # tests directory are all handled separately. | |
| 4857 | |
| 4858 proc pkgconf::process_package { name dir } { | |
| 4859 | |
| 4860 report "Processing package $dir" | |
| 4861 | |
| 4862 set incdir [file join $dir "include"] | |
| 4863 if { [file isdir [file join $pkgconf::component_repository $incdir]] } { | |
| 4864 lappend pkgconf::inc_dirs $incdir | |
| 4865 process_package_includes $name $incdir | |
| 4866 } | |
| 4867 | |
| 4868 set srcdir [file join $dir "src"] | |
| 4869 if { [file isdir [file join $pkgconf::component_repository $srcdir]] } { | |
| 4870 if { [file isfile [file join $pkgconf::component_repository $srcdir PKGconf.mak]] } { | |
| 4871 lappend pkgconf::src_dirs $srcdir | |
| 4872 process_package_src $srcdir | |
| 4873 } | |
| 4874 } | |
| 4875 | |
| 4876 set testsdir [file join $dir "tests"] | |
| 4877 if { [file isdir [file join $pkgconf::component_repository $testsdir]] } { | |
| 4878 if { [file isfile [file join $pkgconf::component_repository $testsdir PKGconf.mak]] } { | |
| 4879 lappend pkgconf::tests_dirs $testsdir | |
| 4880 process_package_tests $name $testsdir | |
| 4881 } | |
| 4882 } | |
| 2 | 4883 |
| 4884 set miscdir [file join $dir "misc"] | |
| 4885 if { [file isdir [file join $pkgconf::component_repository $miscdir]] } { | |
| 4886 if { [file isfile [file join $pkgconf::component_repository $miscdir PKGconf.mak]] } { | |
| 4887 lappend pkgconf::misc_dirs $miscdir | |
| 4888 process_package_misc $miscdir | |
| 4889 } | |
| 4890 } | |
| 0 | 4891 } |
| 4892 | |
| 4893 # ---------------------------------------------------------------------------- | |
| 4894 # Processing the header files is somewhat complicated. The include directories | |
| 4895 # and any subdirectories except pkgconf have to be created in the build tree. | |
| 4896 # Details of these subdirectories get stored in the variable header_subdirs. | |
| 4897 # A pro-forma makefile has to be generated in the build tree, using details | |
| 4898 # of all the header files. These header files must also be appended to the | |
| 4899 # variable header_files. Any files in pkgconf have to be copied across | |
| 4900 # to the pkgconf directory, but must not overwrite the files that are | |
| 4901 # already there. | |
| 4902 # | |
| 4903 # As an additional complication, each package may define its own header | |
| 4904 # file directory. For example a package xyz may specify that all of its | |
| 4905 # exported header files should go into the xyz subdirectory of the install | |
| 4906 # include tree, not at the top level. There are special cases for the HAL. | |
| 4907 # | |
| 4908 # Note that if there are any spurious directories already present, these | |
| 4909 # do not get deleted. However the generated makefile will not reference | |
| 4910 # them so it should be harmless. | |
| 4911 # | |
| 4912 | |
| 4913 proc pkgconf::process_package_includes { name dir } { | |
| 4914 | |
| 4915 # What subdirectory in the install tree should be used ? | |
| 4916 ASSERT { [info exists pkgconf::package_data($name,incdir)] } | |
| 4917 set pkg_incdir $pkgconf::package_data($name,incdir) | |
| 4918 | |
| 4919 # Get information about the package's include directory. | |
| 4920 set pkg_inc_dirs [locate_all_subdirs [file join $pkgconf::component_repository $dir]] | |
| 4921 set pkg_pkgconf_files [locate_files [file join $pkgconf::component_repository $dir "pkgconf"]] | |
| 4922 set pkg_inc_files [locate_all_files [file join $pkgconf::component_repository $dir]] | |
| 4923 | |
| 4924 # Remove all pkgconf headers from the all_headers list. pkgconf headers | |
| 4925 # are handled by a separate makefile in the pkgconf directory. | |
| 4926 foreach hdr $pkg_pkgconf_files { | |
| 4927 set index [lsearch -exact $pkg_inc_files [file join pkgconf $hdr]] | |
| 4928 ASSERT { $index != -1 } | |
| 4929 set pkg_inc_files [lreplace $pkg_inc_files $index $index] | |
| 4930 } | |
| 4931 | |
| 4932 # Remove all unwanted subdirectories. These include pkgconf (which is handled | |
| 4933 # specially) and any empty subdirectories. | |
| 4934 set tmp "" | |
| 4935 foreach subdir $pkg_inc_dirs { | |
| 4936 if { ($subdir == "pkgconf") } { | |
| 4937 continue | |
| 4938 } | |
| 4939 if { [is_empty_directory [file join $pkgconf::component_repository $dir $subdir] ] } { | |
| 4940 continue | |
| 4941 } | |
| 4942 lappend tmp $subdir | |
| 4943 } | |
| 4944 set pkg_inc_dirs $tmp | |
| 4945 | |
| 4946 # Create the include directory in the build tree, plus any subdirectories. | |
| 4947 # This directory tree must map the structure of the source tree, so there is | |
| 4948 # no need to worry about thispkg_incdir. | |
| 4949 file mkdir [file join $pkgconf::build_tree $dir] | |
| 4950 foreach subdir $pkg_inc_dirs { | |
| 4951 file mkdir [file join $pkgconf::build_tree $dir $subdir] | |
| 4952 } | |
| 4953 | |
| 4954 # Copy across the pkgconf files that are not already present. | |
| 4955 # Also keep track of this information globally. | |
| 4956 foreach hdr $pkg_pkgconf_files { | |
| 4957 if { [lsearch -exact $pkgconf::pkgconf_files $hdr] != -1 } { | |
| 4958 return -code error "Duplicate configuration header file $hdr" | |
| 4959 } | |
| 4960 lappend pkgconf::pkgconf_files $hdr | |
| 4961 | |
| 4962 set src [file join $pkgconf::component_repository $dir "pkgconf" $hdr] | |
| 4963 set dest [file join $pkgconf::build_tree "pkgconf" $hdr] | |
| 4964 if { (! [file isfile $dest]) || ($pkgconf::force_arg != 0) } { | |
| 4965 file copy -force -- $src $dest | |
| 4966 make_writable $dest | |
| 4967 } | |
| 4968 } | |
| 4969 | |
| 4970 # Keep track of all the subdirectories that should be generated | |
| 4971 # in the install tree. Note that packages may share these | |
| 4972 # subdirectories, e.g. the sys subdirectory will be used by | |
| 4973 # both the C library and by a POSIX compatibily layer. | |
| 4974 # | |
| 4975 # It is necessary to list pkg_incdir separately, and all | |
| 4976 # of its parent directories. Otherwise it is not possible to | |
| 4977 # clean up the install tree correctly when packages get removed. | |
| 4978 if { $pkg_incdir != "" } { | |
| 4979 set current_path "" | |
| 4980 foreach field [file split $pkg_incdir] { | |
| 4981 set current_path [file join $current_path $field] | |
| 4982 if { [lsearch -exact $pkgconf::install_inc_dirs $current_path] == -1 } { | |
| 4983 lappend pkgconf::install_inc_dirs $current_path | |
| 4984 } | |
| 4985 } | |
| 4986 } | |
| 4987 foreach subdir $pkg_inc_dirs { | |
| 4988 set dest [file join $pkg_incdir $subdir] | |
| 4989 if { [lsearch -exact $pkgconf::install_inc_dirs $dest] == -1 } { | |
| 4990 lappend pkgconf::install_inc_dirs $dest | |
| 4991 } | |
| 4992 } | |
| 4993 | |
| 4994 # Keep track of all header files, checking for duplicates. | |
| 4995 foreach hdr $pkg_inc_files { | |
| 4996 set dest [file join $pkg_incdir $hdr] | |
| 4997 if { [lsearch -exact $pkgconf::install_inc_files $dest] != -1 } { | |
| 4998 return -code error "Duplicate header file $dest" | |
| 4999 } | |
| 5000 lappend pkgconf::install_inc_files $dest | |
| 5001 } | |
| 5002 | |
| 5003 # Generate the makefile in the target directory. First set up | |
| 5004 # some variables to contain the right sort of data for a makefile. | |
| 5005 if { $pkg_incdir == "" } { | |
| 5006 set pkg_incdir "." | |
| 5007 } else { | |
| 5008 set pkg_incdir [get_pathname_for_make $pkg_incdir] | |
| 5009 } | |
| 5010 set tmp "" | |
| 5011 foreach file $pkg_inc_files { | |
| 5012 lappend tmp [get_pathname_for_make $file] | |
| 5013 } | |
| 5014 set pkg_inc_files $tmp | |
| 5015 | |
| 5016 set filename [file join $dir "makefile"] | |
| 5017 set makefile [open [file join $pkgconf::build_tree $filename] "w"] | |
| 5018 output_banner $makefile $filename | |
| 5019 puts $makefile \ | |
| 5020 " | |
| 5021 include [get_pathname_for_make [file join [get_dotdots_pkgconf $dir] "pkgconf.mak"]] | |
| 5022 | |
| 2 | 5023 include [get_pathname_for_make [file join [get_dotdots_pkgconf $dir] "system.mak"]] |
| 5024 | |
| 0 | 5025 HEADERS := $pkg_inc_files |
| 5026 TARGETS := \$(foreach hdr,\$(HEADERS),\$(PREFIX)/include/$pkg_incdir/\$(hdr)) | |
| 5027 .PHONY : build clean | |
| 5028 VPATH := . [file join \$(COMPONENT_REPOSITORY) $dir] | |
| 5029 | |
| 5030 build: \$(TARGETS) | |
| 5031 | |
| 5032 " | |
| 5033 foreach hdr $pkg_inc_files { | |
| 5034 puts $makefile "\$(PREFIX)/include/$pkg_incdir/$hdr : $hdr" | |
| 5035 if { $pkgconf::config_data(use_links) == 0 } { | |
| 5036 puts $makefile "\t@\$(CP) \$< \$@" | |
| 5037 } else { | |
| 5038 puts $makefile "\t@\$(RM) \$@; ln -s \$< \$@" | |
| 5039 } | |
| 5040 puts $makefile "" | |
| 5041 } | |
| 5042 | |
| 5043 puts $makefile "clean:" | |
| 5044 foreach hdr $pkg_inc_files { | |
| 5045 puts $makefile "\t@\$(RM) \$(PREFIX)/include/$pkg_incdir/$hdr" | |
| 5046 } | |
| 5047 puts $makefile "\n# End of $filename" | |
| 5048 close $makefile | |
| 5049 } | |
| 5050 | |
| 5051 # ---------------------------------------------------------------------------- | |
| 5052 # Processing the src directory is relatively straightforward. It is | |
| 5053 # necessary to create the src directory in the build tree, plus any | |
| 5054 # subdirectories. It is also necessary to copy across the PKGconf.mak | |
| 5055 # file from the component repository to the build tree, assuming the | |
| 5056 # destination file does not already exist, and do the same in any | |
| 5057 # subdirectories. | |
| 5058 # | |
| 5059 proc pkgconf::process_package_src { dir } { | |
| 5060 | |
| 5061 set srcdir [file join $pkgconf::component_repository $dir] | |
| 5062 set destdir [file join $pkgconf::build_tree $dir] | |
| 5063 | |
| 5064 file mkdir $destdir | |
| 5065 set subdirs [locate_all_subdirs $srcdir] | |
| 5066 foreach subdir $subdirs { | |
| 5067 if { [is_empty_directory [file join $srcdir $subdir] ] } { | |
| 5068 continue | |
| 5069 } | |
| 5070 file mkdir [file join $destdir $subdir] | |
| 5071 } | |
| 5072 | |
| 5073 set makefiles [locate_all_files $srcdir "PKGconf.mak"] | |
| 5074 foreach makefile $makefiles { | |
| 5075 set destname [file join $destdir [file dirname $makefile] "makefile"] | |
| 5076 | |
| 5077 if { ([file isfile $destname] == 0) || $pkgconf::force_arg } { | |
| 5078 file copy -force -- [file join $srcdir $makefile] $destname | |
| 5079 make_writable $destname | |
| 5080 } | |
| 5081 } | |
| 5082 } | |
| 5083 | |
| 5084 # ---------------------------------------------------------------------------- | |
| 5085 # Processing the tests directories is just the same as the source | |
| 5086 # directories, for now. There is one additional complication in that | |
| 5087 # the test executables have to get installed, so it is necessary to | |
| 5088 # keep track of which directories are needed in the install tree. | |
| 5089 | |
| 5090 proc pkgconf::process_package_tests { name dir } { | |
| 5091 | |
| 5092 set srcdir [file join $pkgconf::component_repository $dir] | |
| 5093 set destdir [file join $pkgconf::build_tree $dir] | |
| 5094 | |
| 5095 lappend pkgconf::install_test_dirs [get_build_alias $name] | |
| 5096 | |
| 5097 file mkdir $destdir | |
| 5098 set subdirs [locate_all_subdirs $srcdir] | |
| 5099 | |
| 5100 foreach subdir $subdirs { | |
| 5101 lappend pkgconf::install_test_dirs [file join [get_build_alias $name] $subdir] | |
| 5102 file mkdir [file join $destdir $subdir] | |
| 5103 } | |
| 5104 | |
| 5105 set makefiles [locate_all_files $srcdir "PKGconf.mak"] | |
| 5106 foreach makefile $makefiles { | |
| 5107 set destname [file join $destdir [file dirname $makefile] "makefile"] | |
| 5108 if { ([file isfile $destname] == 0) || $pkgconf::force_arg } { | |
| 5109 file copy -force -- [file join $srcdir $makefile] $destname | |
| 5110 make_writable $destname | |
| 5111 } | |
| 5112 } | |
| 5113 } | |
| 5114 | |
| 2 | 5115 # ---------------------------------------------------------------------------- |
| 5116 # Processing the misc directory is just like the src directory. | |
| 5117 # | |
| 5118 proc pkgconf::process_package_misc { dir } { | |
| 5119 | |
| 5120 set miscdir [file join $pkgconf::component_repository $dir] | |
| 5121 set destdir [file join $pkgconf::build_tree $dir] | |
| 5122 | |
| 5123 file mkdir $destdir | |
| 5124 set subdirs [locate_all_subdirs $miscdir] | |
| 5125 foreach subdir $subdirs { | |
| 5126 if { [is_empty_directory [file join $miscdir $subdir] ] } { | |
| 5127 continue | |
| 5128 } | |
| 5129 file mkdir [file join $destdir $subdir] | |
| 5130 } | |
| 5131 | |
| 5132 set makefiles [locate_all_files $miscdir "PKGconf.mak"] | |
| 5133 foreach makefile $makefiles { | |
| 5134 set destname [file join $destdir [file dirname $makefile] "makefile"] | |
| 5135 | |
| 5136 if { ([file isfile $destname] == 0) || $pkgconf::force_arg } { | |
| 5137 file copy -force -- [file join $miscdir $makefile] $destname | |
| 5138 make_writable $destname | |
| 5139 } | |
| 5140 } | |
| 5141 } | |
| 5142 | |
| 5143 # }}} | |
| 5144 # {{{ Package debug options | |
| 5145 | |
| 5146 # ---------------------------------------------------------------------- | |
| 5147 # Enable appropriate debug options in various packages. Currently the | |
| 5148 # only option that is affected is CYGPKG_INFRA_DEBUG in pkgconf/infra.h | |
| 5149 | |
| 5150 proc pkgconf::enable_package_debug_options { } { | |
| 5151 | |
| 5152 report "Enabling debug-related options" | |
| 5153 | |
| 5154 set fd [open [file join $pkgconf::build_tree "pkgconf" "infra.h"] "r"] | |
| 5155 set data [read $fd] | |
| 5156 close $fd | |
| 5157 | |
| 5158 if { [regexp -- {undef[ ]+CYGPKG_INFRA_DEBUG} $data] } { | |
| 5159 regsub -- {undef[ ]+CYGPKG_INFRA_DEBUG} $data {define CYGPKG_INFRA_DEBUG} data | |
| 5160 set fd [open [file join $pkgconf::build_tree "pkgconf" "infra.h"] "w"] | |
| 5161 puts $fd $data | |
| 5162 close $fd | |
| 5163 } | |
| 5164 } | |
| 5165 | |
| 5166 # Or the inverse. | |
| 5167 proc pkgconf::disable_package_debug_options { } { | |
| 5168 | |
| 5169 report "Disabling debug-related options" | |
| 5170 | |
| 5171 set fd [open [file join $pkgconf::build_tree "pkgconf" "infra.h"] "r"] | |
| 5172 set data [read $fd] | |
| 5173 close $fd | |
| 5174 | |
| 5175 if { [regexp -- {define[ ]+CYGPKG_INFRA_DEBUG} $data] } { | |
| 5176 regsub -- {define[ ]+CYGPKG_INFRA_DEBUG} $data {undef CYGPKG_INFRA_DEBUG} data | |
| 5177 set fd [open [file join $pkgconf::build_tree "pkgconf" "infra.h"] "w"] | |
| 5178 puts $fd $data | |
| 5179 close $fd | |
| 5180 } | |
| 5181 } | |
| 5182 | |
| 0 | 5183 # }}} |
| 5184 # {{{ Install tree | |
| 5185 | |
| 5186 # ---------------------------------------------------------------------------- | |
| 5187 # These routines take care of the install tree. The routine | |
| 5188 # produce_install_tree gets invoked after details of all the packages | |
| 5189 # are known, and hence after details of all the subdirectories | |
| 5190 # are known. | |
| 5191 # | |
| 5192 # Currently this routine will empty out the lib and tests directory | |
| 5193 # completely. It will also get rid of any files and subdirectories in | |
| 5194 # include which are no longer of interest. | |
| 5195 # | |
| 5196 # Clearing out libtarget.a and any similar libraries avoids problems | |
| 5197 # if the target architecture has changed. Such a change should cause | |
| 5198 # all source files to be rebuilt via a dependency on the makefile | |
| 5199 # auxiliary files. However it would result in an attempt to create | |
| 5200 # a library archive containing a mixture of architectures, which could | |
| 5201 # cause all sorts of problems. To make sure that the library gets | |
| 5202 # regenerated during the next build all the stamp files have to be | |
| 5203 # deleted. | |
| 5204 # | |
| 5205 # It is not a good idea to manipulate header files unnecessarily, | |
| 5206 # since changing these would result in application code being | |
| 5207 # recompiled as well as system code. However if the old and new | |
| 5208 # configurations involve a header file with the same name but coming | |
| 5209 # from different packages, (e.g. a standard HAL header if you switch | |
| 5210 # targets or platforms, or a package header if you change the version | |
| 5211 # of that package) then there are complications. | |
| 5212 # | |
| 5213 # For now the code is draconian and just deletes everything. This | |
| 5214 # needs to be optimised. | |
| 5215 # | |
| 5216 | |
| 5217 proc pkgconf::produce_install_tree { } { | |
| 5218 | |
| 5219 ASSERT { $pkgconf::build_tree != "" } | |
| 5220 | |
| 5221 if { $pkgconf::config_data(prefix) != "" } { | |
| 5222 set prefix $pkgconf::config_data(prefix) | |
| 5223 } else { | |
| 5224 set prefix [file join $pkgconf::build_tree "install"] | |
| 5225 } | |
| 5226 ASSERT { $prefix != "" } | |
| 5227 | |
| 5228 # There should be at least an include/pkgconf subdirectory | |
| 5229 ASSERT { $pkgconf::install_inc_dirs != "" } | |
| 5230 | |
| 5231 # In Tcl the mkdir call is a no-op if the directory already exists. | |
| 5232 report "Generating install directory $prefix" | |
| 5233 file mkdir $prefix | |
| 5234 file mkdir [file join $prefix "include"] | |
| 5235 file mkdir [file join $prefix "lib"] | |
| 5236 file mkdir [file join $prefix "tests"] | |
| 5237 | |
| 5238 foreach subdir $pkgconf::install_inc_dirs { | |
| 5239 file mkdir [file join $prefix "include" $subdir] | |
| 5240 } | |
| 5241 foreach subdir $pkgconf::install_test_dirs { | |
| 5242 file mkdir [file join $prefix "tests" $subdir] | |
| 5243 } | |
| 5244 | |
| 5245 if { 0 } { | |
| 5246 | |
| 5247 # BLV - this code does not work with the makefiles that are now | |
| 5248 # generated for the various include directories. If the old | |
| 5249 # configuration involved a header file xyz.h from package A and | |
| 5250 # the new configuration involves a header file xyz.h from a | |
| 5251 # different package (or a different version of the same package) | |
| 5252 # then the old header file would hang around. A temporary | |
| 5253 # work-around is to delete all header files. A proper fix is | |
| 5254 # rather more complicated. | |
| 5255 | |
| 5256 # Examine all the files currently in the include directory. If | |
| 5257 # any of them are not recognised then they should be deleted. | |
| 5258 # Typically this happens if a package is removed. | |
| 5259 # | |
| 5260 # There may be problems if users put the install tree under | |
| 5261 # source code control, in that files just disappear. However even if | |
| 5262 # the source code control system restores an old file this should be | |
| 5263 # harmless. The directory routines ignore CVS subdirectories and all | |
| 5264 # hidden files. | |
| 5265 # | |
| 5266 # Files in pkgconf have to be treated specially. These are listed | |
| 5267 # in pkgconf_files, not header_files. | |
| 5268 | |
| 5269 set existing_headers [locate_all_files [file join $prefix "include"]] | |
| 5270 set pkgconf_headers [locate_all_files [file join $prefix "include" pkgconf]] | |
| 5271 | |
| 5272 foreach file $pkgconf_headers { | |
| 5273 if { [lsearch -exact $pkgconf::pkgconf_files $file] == -1 } { | |
| 5274 set filename [file join $prefix "include" $file] | |
| 5275 report "Deleting unnecessary file $filename" | |
| 5276 file delete -- $filename | |
| 5277 } | |
| 5278 | |
| 5279 # Make sure that this file does not get processed again in the | |
| 5280 # next loop. | |
| 5281 set file [file join "pkgconf" $file] | |
| 5282 set index [lsearch -exact $existing_headers $file] | |
| 5283 ASSERT { $index != -1 } | |
| 5284 set existing_headers [lreplace $existing_headers $index $index] | |
| 5285 } | |
| 5286 | |
| 5287 foreach file $existing_headers { | |
| 5288 if { [lsearch -exact $pkgconf::install_inc_files $file] == -1 } { | |
| 5289 set filename [file join $prefix "include" $file] | |
| 5290 report "Deleting unnecessary file $filename" | |
| 5291 file delete -- $filename | |
| 5292 } | |
| 5293 } | |
| 5294 | |
| 5295 # If the user has switched from symbolic links to file copies then | |
| 5296 # it is also necessary to delete the old symbolic links. The reverse | |
| 5297 # also applies. | |
| 5298 set existing_headers [locate_all_files [file join $prefix "include"]] | |
| 5299 set files_removed 0 | |
| 5300 foreach file $existing_headers { | |
| 5301 | |
| 5302 set filename [file join $prefix "include" $file] | |
| 5303 set type [file type $filename] | |
| 5304 | |
| 5305 if { ($pkgconf::config_data(use_links) == 0 ) && ($type == "link") } { | |
| 5306 file delete -- $filename | |
| 5307 set files_removed 1 | |
| 5308 } elseif { ($pkgconf::config_data(use_links) == 1 ) && ($type == "file") } { | |
| 5309 file delete -- $filename | |
| 5310 set files_removed 1 | |
| 5311 } | |
| 5312 } | |
| 5313 if { $files_removed != 0 } { | |
| 5314 if { $pkgconf::config_data(use_links) == 0 } { | |
| 5315 report "Symbolic links in [file join $prefix include] deleted." | |
| 5316 } else { | |
| 5317 report "Header file copies in [file join $prefix include] deleted." | |
| 5318 } | |
| 5319 } | |
| 5320 | |
| 5321 # Now get rid of any unwanted subdirectories. | |
| 5322 set existing_subdirs [locate_all_subdirs [file join $prefix "include"]] | |
| 5323 foreach subdir $existing_subdirs { | |
| 5324 if { [lsearch -exact $pkgconf::install_inc_dirs $subdir] == -1 } { | |
| 5325 set dirname [file join $prefix "include" $subdir] | |
| 5326 report "Deleting unnecessary directory $dirname" | |
| 5327 file delete -force -- $dirname | |
| 5328 } | |
| 5329 } | |
| 5330 | |
| 5331 } else { | |
| 5332 | |
| 5333 # BLV - delete all header files for now. This is inefficient but safe. | |
| 5334 | |
| 5335 set existing_headers [locate_all_files [file join $prefix "include"]] | |
| 5336 foreach file $existing_headers { | |
| 5337 set filename [file join $prefix "include" $file] | |
| 5338 file delete -- $filename | |
| 5339 } | |
| 5340 | |
| 5341 # Now get rid of any unwanted subdirectories. | |
| 5342 set existing_subdirs [locate_all_subdirs [file join $prefix "include"]] | |
| 5343 foreach subdir $existing_subdirs { | |
| 5344 if { [lsearch -exact $pkgconf::install_inc_dirs $subdir] == -1 } { | |
| 5345 set dirname [file join $prefix "include" $subdir] | |
| 5346 report "Deleting unnecessary directory $dirname" | |
| 5347 file delete -force -- $dirname | |
| 5348 } | |
| 5349 } | |
| 5350 } | |
| 5351 | |
| 5352 # Get rid of all the files in lib. | |
| 5353 set lib_files [locate_files [file join $prefix "lib"]] | |
| 5354 if { $lib_files != "" } { | |
| 5355 report "Deleting old library files $lib_files" | |
| 5356 foreach file $lib_files { | |
| 5357 file delete -- [file join $prefix "lib" $file] | |
| 5358 } | |
| 5359 } | |
| 5360 | |
| 5361 # And get rid of any stamp files spread around the object tree | |
| 5362 foreach src_dir $pkgconf::src_dirs { | |
| 5363 set dirname [file join $pkgconf::build_tree $src_dir] | |
| 5364 set stamp_files [locate_files $dirname "*.stamp"] | |
| 5365 foreach file $stamp_files { | |
| 5366 file delete -- [file join $dirname $file] | |
| 5367 } | |
| 5368 } | |
| 5369 | |
| 5370 # Ditto for tests | |
| 5371 set test_files [locate_all_files [file join $prefix "tests"]] | |
| 5372 if { $test_files != "" } { | |
| 5373 report "Deleting old test executables." | |
| 5374 foreach file $test_files { | |
| 5375 file delete -- [file join $prefix "tests" $file] | |
| 5376 } | |
| 5377 } | |
| 5378 foreach test_dir $pkgconf::tests_dirs { | |
| 5379 set dirname [file join $pkgconf::build_tree $test_dir] | |
| 5380 set stamp_files [locate_files $dirname "*.stamp"] | |
| 5381 foreach file $stamp_files { | |
| 5382 file delete -- [file join $dirname $file] | |
| 5383 } | |
| 5384 } | |
| 5385 | |
| 5386 # If there has been a change in the packages in the system | |
| 5387 # then the various makefile.deps files currently in the | |
| 5388 # build tree may contain references to header files that | |
| 5389 # are no longer present. Therefore it is necessary to | |
| 5390 # get rid of the makefile.deps files. Any changes to the | |
| 5391 # packages will result in a new pkgconf/pkgconf.mak file | |
| 5392 # and all object files depend on this, so everything that | |
| 5393 # needs to be rebuilt will still be rebuilt and new | |
| 5394 # dependency files will be generated. | |
| 5395 # | |
| 5396 # If there has not been a change to the packages then the | |
| 5397 # makefile.deps files must not be deleted, or there would | |
| 5398 # be problems when just a header file is changed. | |
| 5399 if { [packages_have_changed] } { | |
| 5400 | |
| 5401 foreach src_dir $pkgconf::src_dirs { | |
| 5402 set dirname [file join $pkgconf::build_tree $src_dir] | |
| 5403 set dep_files [locate_files $dirname "makefile.deps"] | |
| 5404 foreach file $dep_files { | |
| 5405 file delete -- [file join $dirname $file] | |
| 5406 } | |
| 5407 } | |
| 5408 | |
| 5409 foreach test_dir $pkgconf::tests_dirs { | |
| 5410 set dirname [file join $pkgconf::build_tree $test_dir] | |
| 5411 set dep_files [locate_files $dirname "makefile.deps"] | |
| 5412 foreach file $dep_files { | |
| 5413 file delete -- [file join $dirname $file] | |
| 5414 } | |
| 5415 } | |
| 5416 } | |
| 5417 } | |
| 5418 | |
| 5419 # }}} | |
| 5420 # {{{ Produce misc. files | |
| 5421 | |
| 5422 # ---------------------------------------------------------------------------- | |
| 5423 # Three files have to be generated, and one additional file can be copied. | |
| 5424 # | |
| 5425 # 1) pkgconf/makevars has to be copied from the component repository. | |
| 5426 # 2) pkgconf/makevars relies on pkgconf/pkgconf.mak, which is generated | |
| 5427 # 3) pkgconf/system.h has to be generated. | |
| 5428 # 5) pkgconf/makefile has to be generated. | |
| 5429 # | |
| 5430 | |
| 5431 proc pkgconf::produce_misc_files { } { | |
| 5432 | |
| 5433 report "Generating miscellaneous files." | |
| 5434 | |
| 5435 # Start by copying across pkgconf/makevars unless these files | |
| 5436 # already exist in the build tree. Note that these files are | |
| 5437 # user-editable so they cannot be overwritten automatically. | |
| 5438 set destname [file join $pkgconf::build_tree "pkgconf" "makevars"] | |
| 5439 set sourcename [file join $pkgconf::component_repository "pkgconf" "makevars"] | |
| 5440 if { (![file isfile $destname]) || ($pkgconf::force_arg != 0) } { | |
| 5441 file copy -force -- $sourcename $destname | |
| 5442 make_writable $destname | |
| 5443 } | |
| 5444 | |
| 5445 # Next generate the file pkgconf.mak. This should only happen if any | |
| 5446 # of the data in the file is changed, because there are file-level | |
| 5447 # dependencies in the various makefiles. Additions to the packages | |
| 5448 # file will normally be caught by a missing version number. Other | |
| 5449 # changes to the packages or targets file may not be caught. | |
| 5450 | |
| 5451 set config_changed 0 | |
| 5452 if { [packages_have_changed] } { | |
| 5453 set config_changed 1 | |
| 5454 } | |
| 5455 if { [value_has_changed "prefix"] } { | |
| 5456 set config_changed 1 | |
| 5457 } | |
| 5458 foreach flag $pkgconf::known_compiler_flags { | |
| 5459 if { [value_has_changed "cflags,$flag"] } { | |
| 5460 set config_changed 1 | |
| 5461 break | |
| 5462 } | |
| 5463 } | |
| 5464 if { ![file isfile [file join $pkgconf::build_tree "pkgconf" "pkgconf.mak"]] } { | |
| 5465 set config_changed 1 | |
| 5466 } | |
| 5467 if { $pkgconf::force_arg != 0 } { | |
| 5468 set config_changed 1 | |
| 5469 } | |
| 5470 | |
| 5471 if { $config_changed != 0 } { | |
| 5472 | |
| 5473 set filename [file join "pkgconf" "pkgconf.mak"] | |
| 5474 set file [open [file join $pkgconf::build_tree $filename] "w"] | |
| 5475 output_banner $file $filename | |
| 5476 | |
| 5477 # All PKGconf.mak files should include the master pkgconf.mak | |
| 5478 # file ASAP. It is desirable to have a goal at the top of that | |
| 5479 # file. This is likely to be the first goal detected by make, | |
| 5480 # and hence the default. | |
| 5481 puts $file "\ndefault: build\n" | |
| 5482 | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5483 set platform $pkgconf::config_data(platform) |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5484 if [info exists pkgconf::target_data($pkgconf::config_data(target),$platform,prefix)] { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5485 set command_prefix $pkgconf::target_data($pkgconf::config_data(target),$platform,prefix) |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5486 } else { |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5487 set command_prefix $pkgconf::target_data($pkgconf::config_data(target),prefix) |
|
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5488 } |
|
44
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5489 if {"" != $command_prefix} { |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5490 set command_prefix "${command_prefix}-" |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5491 } |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5492 |
| 0 | 5493 puts $file "" |
| 5494 puts $file "COMPONENT_REPOSITORY\t\t:= [get_pathname_for_make $pkgconf::component_repository]" | |
| 5495 puts $file "BUILD_TREE\t\t\t:= [get_pathname_for_make $pkgconf::build_tree]" | |
| 5496 | |
| 2 | 5497 # Provide details of target etc. so that packages can specify |
| 5498 # per-target files. | |
| 5499 puts $file "TARGET\t\t\t\t:= $pkgconf::config_data(target)" | |
| 5500 puts $file "PLATFORM\t\t\t:= $pkgconf::config_data(platform)" | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5501 puts $file "BASE_PLATFORM\t\t\t:= $pkgconf::config_data(base_platform)" |
| 2 | 5502 puts $file "STARTUP\t\t\t\t:= $pkgconf::config_data(startup)" |
| 5503 | |
| 0 | 5504 # The prefix (i.e. install directory) should default to somewhere |
| 5505 # relative to the build tree. | |
| 5506 set prefix $pkgconf::config_data(prefix) | |
| 5507 if { $prefix == "" } { | |
| 5508 set prefix [file join $pkgconf::build_tree "install"] | |
| 5509 } | |
| 5510 puts $file "PREFIX\t\t\t\t:= [get_pathname_for_make $prefix]" | |
| 5511 if { $pkgconf::windows_host != 0 } { | |
| 5512 puts $file "EXEEXT\t\t\t\t:= .exe" | |
| 5513 } | |
| 5514 puts $file "" | |
|
44
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5515 puts $file "PKGCONF_CC\t\t\t:= ${command_prefix}gcc" |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5516 puts $file "PKGCONF_CXX\t\t\t:= ${command_prefix}gcc" |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5517 puts $file "PKGCONF_AR\t\t\t:= ${command_prefix}ar" |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5518 puts $file "PKGCONF_LD\t\t\t:= ${command_prefix}ld" |
|
41bd4f3a90de
Merge from eCos master repository on 1999-10-08-07:47:04-BST
jlarmour
parents:
14
diff
changeset
|
5519 puts $file "PKGCONF_OBJCOPY\t\t\t:= ${command_prefix}objcopy" |
| 0 | 5520 puts $file "" |
| 5521 | |
| 5522 foreach flag $pkgconf::known_compiler_flags { | |
| 5523 set value "" | |
| 5524 if { [info exists pkgconf::config_data(cflags,$flag)] != 0 } { | |
| 5525 set value $pkgconf::config_data(cflags,$flag) | |
| 5526 } else { | |
| 5527 set value [get_platform_cflags $pkgconf::config_data(target) $pkgconf::config_data(platform) $flag] | |
| 5528 } | |
| 5529 if { $value != "" } { | |
| 5530 puts $file "PKGCONF_[set flag]\t\t:= $value" | |
| 5531 } | |
| 5532 } | |
| 5533 puts $file "" | |
| 5534 | |
| 5535 foreach pkg [get_current_packages] { | |
| 5536 set varname "[get_build_alias $pkg]_DIR" | |
| 5537 set dirname [file join $pkgconf::package_data($pkg,dir) $pkgconf::config_data($pkg,version)] | |
| 5538 puts $file "$varname\t\t:= $dirname" | |
| 5539 } | |
| 5540 | |
| 5541 # There are several files containing information about make variables | |
| 5542 # rules. The current file, pkgconf.mak, contains information that | |
| 5543 # is known to the pkgconf script and should not be edited by users. | |
| 5544 # There may be a per-package file in the build tree's pkgconf | |
| 5545 # directory, containing per-package settings. And there is the | |
| 5546 # makevars file which users can edit to override anything else. | |
| 5547 # | |
| 5548 # The makefiles for the various packages should only | |
| 5549 # need to include one of these files, the rest can be handled | |
| 5550 # automatically. Since pkgconf.mak is generated it knows the | |
| 5551 # location of the build tree, making it a lot easier to find | |
| 5552 # the others. Therefore pkgconf.mak is included first, then | |
| 5553 # the per-package file, and finally the makevars file. | |
| 5554 | |
| 5555 puts $file " | |
| 5556 PACKAGE_RULES_FILE := \$(wildcard \$(BUILD_TREE)/pkgconf/\$(PACKAGE).mak) | |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
44
diff
changeset
|
5557 ifneq (\$(PACKAGE_RULES_FILE),) |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
44
diff
changeset
|
5558 include \$(PACKAGE_RULES_FILE) |
| 0 | 5559 endif" |
| 5560 | |
| 5561 puts $file "\ninclude \$(BUILD_TREE)/pkgconf/makevars" | |
| 5562 | |
| 5563 puts $file "\n# End of $filename" | |
| 5564 close $file | |
| 5565 } | |
| 5566 | |
| 5567 # And the file system.h | |
| 5568 # | |
| 5569 # Again, because of file-level dependencies this file should only | |
| 5570 # be written out if anything has actually changed. | |
| 5571 set config_changed 0 | |
| 5572 if { [packages_have_changed] || [value_has_changed "startup"] } { | |
| 5573 set config_changed 1 | |
| 5574 } | |
| 5575 if { ![file isfile [file join $pkgconf::build_tree "pkgconf" "system.h"]] } { | |
| 5576 set config_changed 1 | |
| 5577 } | |
| 5578 if { $pkgconf::force_arg != 0 } { | |
| 5579 set config_changed 1 | |
| 5580 } | |
| 5581 | |
| 5582 if { $config_changed != 0 } { | |
| 5583 | |
| 5584 set filename [file join "pkgconf" "system.h"] | |
| 5585 set file [open [file join $pkgconf::build_tree $filename] "w"] | |
| 5586 puts $file \ | |
| 5587 "#ifndef CYGONCE_PKGCONF_SYSTEM_H | |
| 5588 #define CYGONCE_PKGCONF_SYSTEM_H | |
| 5589 /* | |
| 5590 * File $filename | |
| 5591 * | |
| 5592 * This file is generated automatically by the pkgconf program. | |
| 5593 * It should not be edited. Any changes to this file may be | |
| 5594 * overwritten by pkgconf. | |
| 5595 */ | |
| 5596 " | |
| 5597 puts $file "#define CYG_HAL_[string toupper $pkgconf::config_data(target)]" | |
| 5598 puts $file \ | |
| 5599 "#define CYG_HAL_[string toupper $pkgconf::config_data(target)]_[string toupper $pkgconf::config_data(platform)]" | |
| 5600 puts $file "#define CYG_HAL_STARTUP_[string toupper $pkgconf::config_data(startup)]" | |
| 5601 puts $file "" | |
| 5602 set current_packages [get_current_packages] | |
| 5603 foreach pkg $pkgconf::known_packages { | |
| 5604 if { [lsearch -exact $current_packages $pkg] == -1 } { | |
| 5605 puts $file "#undef $pkg" | |
| 5606 } else { | |
| 5607 puts $file "#define $pkg" | |
| 5608 } | |
| 5609 } | |
| 5610 | |
| 2 | 5611 # Additions for the MLT |
| 5612 puts $file "\n" | |
|
14
01ce82f3e11a
Merge from eCos master repository on 1999-06-11-17:05:41-BST
jlarmour
parents:
12
diff
changeset
|
5613 puts $file "#define CYGHWR_MEMORY_LAYOUT_LDI <pkgconf/mlt_[set pkgconf::config_data(target)]_[set pkgconf::config_data(platform)]_[set pkgconf::config_data(startup)].ldi>" |
|
01ce82f3e11a
Merge from eCos master repository on 1999-06-11-17:05:41-BST
jlarmour
parents:
12
diff
changeset
|
5614 puts $file "#define CYGHWR_MEMORY_LAYOUT_H <pkgconf/mlt_[set pkgconf::config_data(target)]_[set pkgconf::config_data(platform)]_[set pkgconf::config_data(startup)].h>" |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
5615 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
5616 # Also output details of the HAL header files that should be included |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
5617 puts $file "\n" |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
5618 puts $file "#define CYGBLD_HAL_TARGET_H <pkgconf/hal_[set pkgconf::config_data(target)].h>" |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5619 puts $file "#define CYGBLD_HAL_PLATFORM_H <pkgconf/hal_[set pkgconf::config_data(target)]_[set pkgconf::config_data(base_platform)].h>" |
| 2 | 5620 |
| 0 | 5621 puts $file "\ |
| 5622 \n#endif /* CYGONCE_PKGCONF_SYSTEM_H */ | |
| 5623 /* EOF $filename */" | |
| 5624 close $file | |
| 5625 } | |
| 5626 | |
| 2 | 5627 # 'system.mak' has the same basic information, but in a form |
| 5628 # that can be used by makefile fragments. | |
| 5629 | |
| 5630 if { $config_changed != 0 } { | |
| 5631 | |
| 5632 set filename [file join "pkgconf" "system.mak"] | |
| 5633 set file [open [file join $pkgconf::build_tree $filename] "w"] | |
| 5634 puts $file \ | |
| 5635 "# | |
| 5636 # File $filename | |
| 5637 # | |
| 5638 # This file is generated automatically by the pkgconf program. | |
| 5639 # It should not be edited. Any changes to this file may be | |
| 5640 # overwritten by pkgconf. | |
| 5641 # | |
| 5642 " | |
| 5643 puts $file "CYG_HAL_[string toupper $pkgconf::config_data(target)]=1" | |
| 5644 puts $file \ | |
| 5645 "CYG_HAL_[string toupper $pkgconf::config_data(target)]_[string toupper $pkgconf::config_data(platform)]=1" | |
| 5646 puts $file "CYG_HAL_STARTUP_[string toupper $pkgconf::config_data(startup)]=1" | |
| 5647 puts $file "" | |
| 5648 set current_packages [get_current_packages] | |
| 5649 foreach pkg $pkgconf::known_packages { | |
| 5650 if { [lsearch -exact $current_packages $pkg] != -1 } { | |
| 5651 puts $file "$pkg=1" | |
| 5652 } | |
| 5653 } | |
| 5654 puts $file "\n# /* EOF $filename */" | |
| 5655 close $file | |
| 5656 } | |
| 5657 | |
| 0 | 5658 # Always output a makefile in the pkgconf directory. This is harmless |
| 5659 # because there should be no file-level dependencies on this file (just | |
| 5660 # like the toplevel makefile). | |
| 5661 set filename [file join "pkgconf" "makefile"] | |
| 5662 set makefile [open [file join $pkgconf::build_tree $filename] "w"] | |
| 5663 output_banner $makefile $filename | |
| 5664 | |
| 5665 puts $makefile \ | |
| 5666 "include pkgconf.mak | |
| 5667 | |
| 5668 .PHONY : build clean | |
| 5669 HEADERS := $pkgconf::pkgconf_files | |
| 5670 TARGETS := \$(foreach hdr,\$(HEADERS),\$(PREFIX)/include/pkgconf/\$(hdr)) | |
| 5671 | |
| 5672 build: \$(TARGETS) | |
| 5673 " | |
| 5674 | |
| 5675 foreach hdr $pkgconf::pkgconf_files { | |
| 5676 puts $makefile "\$(PREFIX)/include/pkgconf/$hdr : $hdr" | |
| 5677 if { $pkgconf::config_data(use_links) == 0 } { | |
| 5678 puts $makefile "\t@\$(CP) \$< \$@" | |
| 5679 } else { | |
| 5680 puts $makefile "\t@\$(RM) \$@; ln -s \$< \$@" | |
| 5681 } | |
| 5682 puts $makefile "" | |
| 5683 } | |
| 5684 | |
| 5685 puts $makefile "clean:" | |
| 5686 foreach hdr $pkgconf::pkgconf_files { | |
| 5687 puts $makefile "\t@\$(RM) \$(PREFIX)/include/pkgconf/$hdr" | |
| 5688 } | |
| 5689 puts $makefile "\n# End of $filename" | |
| 5690 close $makefile | |
| 5691 | |
| 5692 } | |
| 5693 | |
| 5694 # }}} | |
| 5695 # {{{ Produce the master makefile | |
| 5696 | |
| 5697 # ---------------------------------------------------------------------------- | |
| 5698 # This routine is responsible for generating the master makefile that | |
| 5699 # exists at the top of a build tree. This makefile supports three main | |
| 5700 # targets: default, tests and clean. There is a subsidiary target | |
| 5701 # "headers" which takes care of the header files. | |
| 5702 # | |
| 5703 | |
| 5704 proc pkgconf::produce_makefile { } { | |
| 5705 | |
| 5706 report "Generating toplevel makefile." | |
| 5707 | |
| 5708 ASSERT { $pkgconf::build_tree != "" } | |
| 5709 set filename [file join $pkgconf::build_tree "makefile"] | |
| 5710 set makefile [open $filename "w"] | |
| 5711 output_banner $makefile "makefile" | |
| 5712 | |
| 5713 puts $makefile \ | |
| 5714 " | |
| 5715 include pkgconf/pkgconf.mak | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
5716 .PHONY: default build clean tests headers" |
| 2 | 5717 |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
44
diff
changeset
|
5718 puts $makefile "\nbuild: \$(PREFIX)/lib/extras.o" |
| 2 | 5719 puts $makefile "\t@echo Build finished." |
| 5720 | |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
44
diff
changeset
|
5721 puts $makefile "\n\$(PREFIX)/lib/extras.o: \$(PREFIX)/lib/libextras.a" |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
44
diff
changeset
|
5722 puts $makefile "\t\$(CC) \$(ARCHFLAGS) \$(LDARCHFLAGS) -nostdlib -Wl,-r -Wl,--whole-archive \$(PREFIX)/lib/libextras.a -o \$(PREFIX)/lib/extras.o" |
| 2 | 5723 |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
44
diff
changeset
|
5724 puts $makefile "\n\$(PREFIX)/lib/libextras.a: headers" |
| 0 | 5725 foreach src_dir $pkgconf::src_dirs { |
| 5726 puts $makefile "\t\$(MAKE) -C $src_dir" | |
| 5727 } | |
| 5728 | |
| 5729 puts $makefile "\ntests: build" | |
| 5730 foreach tests_dir $pkgconf::tests_dirs { | |
| 5731 puts $makefile "\t\$(MAKE) -C $tests_dir" | |
| 5732 } | |
| 5733 puts $makefile "\t@echo Tests build finished." | |
| 5734 | |
| 2 | 5735 puts $makefile "\nmisc: build" |
| 5736 foreach misc_dir $pkgconf::misc_dirs { | |
| 5737 puts $makefile "\t\$(MAKE) -C $misc_dir" | |
| 5738 } | |
| 5739 puts $makefile "\t@echo Misc build finished." | |
| 5740 | |
| 0 | 5741 puts $makefile \ |
| 5742 "\nlibobjs := \$(wildcard \$(PREFIX)/lib/*) | |
| 5743 clean: | |
| 5744 ifneq (\$(libobjs),) | |
| 5745 \t\$(RM) \$(libobjs) | |
| 5746 endif | |
| 5747 \tmake -C pkgconf clean" | |
| 5748 foreach src_dir $pkgconf::src_dirs { | |
| 5749 puts $makefile "\t\$(MAKE) -C $src_dir clean" | |
| 5750 } | |
| 2 | 5751 foreach misc_dir $pkgconf::misc_dirs { |
| 5752 puts $makefile "\t\$(MAKE) -C $misc_dir clean" | |
| 5753 } | |
| 0 | 5754 foreach tests_dir $pkgconf::tests_dirs { |
| 5755 puts $makefile "\t\$(MAKE) -C $tests_dir clean" | |
| 5756 } | |
| 5757 foreach inc_dir $pkgconf::inc_dirs { | |
| 5758 puts $makefile "\t@\$(MAKE) -silent -C $inc_dir clean" | |
| 5759 } | |
| 5760 puts $makefile "\t@echo Clean finished." | |
| 5761 | |
| 5762 puts $makefile "\nheaders:" | |
| 5763 puts $makefile "\t@echo Checking header files." | |
| 5764 puts $makefile "\t@\$(MAKE) -silent -C pkgconf" | |
| 5765 foreach inc_dir $pkgconf::inc_dirs { | |
| 5766 puts $makefile "\t@\$(MAKE) -silent -C $inc_dir" | |
| 5767 } | |
| 5768 | |
| 5769 puts $makefile "" | |
| 5770 puts $makefile "# End of makefile" | |
| 5771 close $makefile | |
| 5772 } | |
| 5773 | |
| 5774 # }}} | |
| 5775 | |
| 5776 # {{{ Produce_build_tree | |
| 5777 | |
| 5778 proc pkgconf::produce_build_tree { } { | |
| 5779 | |
| 5780 # First, check that all the requirements have been satisfied. Normally | |
| 5781 # this will have been taken care of earlier. | |
| 5782 check_requirements | |
| 5783 | |
| 5784 # What is the install tree ? | |
| 5785 set prefix $pkgconf::config_data(prefix) | |
| 5786 if { $prefix == "" } { | |
| 5787 set prefix [file join $pkgconf::build_tree "install"] | |
| 5788 } | |
| 5789 set target $pkgconf::config_data(target) | |
| 5790 set platform $pkgconf::config_data(platform) | |
| 5791 set startup $pkgconf::config_data(startup) | |
| 5792 | |
| 5793 # Report the configuration that is being built. | |
| 5794 report "Generating build tree." | |
| 5795 report "Component repository is $pkgconf::component_repository" | |
| 5796 report "Build tree is $pkgconf::build_tree" | |
| 5797 report "Install directory is $prefix" | |
| 5798 report "Architecture $target, platform $platform, startup $startup." | |
| 5799 if { $pkgconf::config_data(use_links) != 0 } { | |
| 5800 report "Using symbolic links for the header files." | |
| 5801 } | |
| 5802 | |
| 5803 # Reset the list of all the header files that should be in the install | |
| 5804 # tree, and related variables. | |
| 5805 set pkgconf::inc_dirs "" | |
| 5806 set pkgconf::src_dirs "" | |
| 2 | 5807 set pkgconf::misc_dirs "" |
| 0 | 5808 set pkgconf::tests_dirs "" |
| 5809 set pkgconf::install_inc_dirs "pkgconf" | |
| 5810 set pkgconf::install_inc_files "" | |
| 5811 set pkgconf::pkgconf_files "makevars pkgconf.mak system.h" | |
| 5812 set pkgconf::install_test_dirs "" | |
| 5813 | |
| 5814 set status [catch { | |
| 5815 | |
| 5816 # Create the toplevel build tree directory, if necessary. | |
| 5817 if { ! [file exists $pkgconf::build_tree] } { | |
| 5818 report "Creating build tree $pkgconf::build_tree" | |
| 5819 file mkdir $pkgconf::build_tree | |
| 5820 } | |
| 5821 # Create the pkgconf subdirectory. A failure here indicates that | |
| 5822 # the build tree is not writable, and it is useful to detect this | |
| 5823 # before too much processing takes place. | |
| 5824 set dirname [file join $pkgconf::build_tree pkgconf] | |
| 5825 if { ! [file exists $dirname] } { | |
| 5826 report "Creating directory $dirname" | |
| 5827 file mkdir $dirname | |
| 5828 } | |
| 5829 | |
| 5830 # Process each package that is part of the current configuration | |
| 5831 foreach pkg [get_current_packages] { | |
| 5832 set dirname $pkgconf::package_data($pkg,dir) | |
| 5833 set dirname [file join $dirname $pkgconf::config_data($pkg,version)] | |
| 5834 process_package $pkg $dirname | |
| 5835 } | |
| 5836 | |
| 2 | 5837 # If this is a debug build (according to the --debug command line |
| 5838 # option), update the appropriate packages. | |
| 5839 if {$pkgconf::debug_arg != 0} { | |
| 5840 enable_package_debug_options | |
| 5841 } elseif {$pkgconf::nodebug_arg != 0} { | |
| 5842 disable_package_debug_options | |
| 5843 } | |
| 5844 | |
| 0 | 5845 # The install tree must exist before the misc files are generated. |
| 5846 # See get_pathname_for_make for details. | |
| 5847 produce_install_tree | |
| 5848 produce_misc_files | |
| 5849 produce_makefile | |
| 5850 | |
| 5851 report "Generating save file." | |
| 5852 write_save_file | |
| 5853 report "The Build tree is ready." | |
| 5854 | |
| 5855 } message] | |
| 5856 | |
| 5857 if { $status != 0 } { | |
| 5858 fatal_error "An unexpected error occurred while generating the build tree: $message" | |
| 5859 } | |
| 5860 } | |
| 5861 | |
| 5862 # }}} | |
| 5863 | |
| 5864 # }}} | |
| 5865 # {{{ main() | |
| 5866 | |
| 5867 # ---------------------------------------------------------------------------- | |
| 5868 # Initialise data. This routine is responsible for reading in the | |
| 5869 # packages file and the targets file, setting up the default data, | |
| 5870 # reading in the save file if any, and processing the command line | |
| 5871 # arguments if any. | |
| 5872 # | |
| 5873 | |
| 5874 proc pkgconf::initialise_data { } { | |
| 5875 | |
| 5876 # First, read the packages and targets files. These routines will | |
| 5877 # also deal with the --packages and --targets arguments, and | |
| 5878 # they will check for any invalid packages or targets that may | |
| 5879 # have been passed. The order of these two calls should not be | |
| 5880 # changed since read_targets needs to know about the available | |
| 5881 # packages for some of its validations. | |
| 5882 pkgconf::read_packages | |
| 5883 pkgconf::read_targets | |
| 5884 | |
| 5885 # If either or both of the --packages or --targets arguments | |
| 5886 # were used, do not go any further. The user was just asking | |
| 5887 # for information. Ditto for --pkgdata, which can be used by | |
| 5888 # other programs to get information about the various | |
| 5889 # packages in a format more appropriate for them. | |
| 5890 # | |
| 5891 # NOTE: the parsing code does not actually check that no | |
| 5892 # further arguments were passed, but it is unlikely that the | |
| 5893 # user would both ask for a list of packages and expect | |
| 5894 # something to happen. | |
| 5895 if { ( $pkgconf::list_packages_arg != 0 ) || | |
| 5896 ( $pkgconf::list_targets_arg != 0 ) || | |
| 5897 ( $pkgconf::list_pkgdata_arg != 0 ) } { | |
| 5898 exit 0 | |
| 5899 } | |
| 5900 | |
| 5901 # Set up default values for all options which are managed directly | |
| 5902 # by this program. | |
| 5903 pkgconf::setup_defaults | |
| 5904 | |
| 5905 # Check for a save file in the existing build tree. | |
| 5906 # If so read it in, updating the default values. | |
| 5907 pkgconf::read_save_file | |
| 5908 | |
| 5909 # Now process the command line arguments, which will again result | |
| 5910 # in updates to the default values. | |
| 5911 pkgconf::process_arguments | |
| 5912 | |
| 5913 # If the -flags argument was used, list the compiler flags currently | |
| 5914 # in use. This could not be done earlier since the compiler flags | |
| 5915 # may depend on the save file and on other command line arguments. | |
| 5916 if { $pkgconf::list_flags_arg != 0 } { | |
| 5917 foreach flag $pkgconf::known_compiler_flags { | |
| 5918 set value "" | |
| 5919 if { [info exists pkgconf::config_data(cflags,$flag)] != 0 } { | |
| 5920 set value $pkgconf::config_data(cflags,$flag) | |
| 5921 } else { | |
| 5922 set value [get_platform_cflags $pkgconf::config_data(target) $pkgconf::config_data(platform) $flag] | |
| 5923 } | |
| 5924 if { $value != "" } { | |
| 5925 puts "$flag\t\"$value\"" | |
| 5926 } | |
| 5927 } | |
| 5928 exit 0 | |
| 5929 } | |
| 5930 | |
| 5931 if { 0 } { | |
| 5932 puts "target: $pkgconf::config_data(target)" | |
| 5933 puts "platform: $pkgconf::config_data(platform)" | |
|
12
4cc3eff958ab
Merge from eCos master repository on 1999-06-04-22:24:56-BST
jlarmour
parents:
4
diff
changeset
|
5934 puts "base_platform: $pkgconf::config_data(base_platform)" |
| 0 | 5935 puts "startup: $pkgconf::config_data(startup)" |
| 5936 puts "prefix: $pkgconf::config_data(prefix)" | |
| 5937 puts "packages: $pkgconf::config_data(packages)" | |
| 5938 foreach pkg $pkgconf::config_data(packages) { | |
| 5939 puts "$pkg version $pkgconf::config_data($pkg,version)" | |
| 5940 } | |
| 5941 exit 0 | |
| 5942 } | |
| 5943 } | |
| 5944 | |
| 5945 # ---------------------------------------------------------------------------- | |
| 5946 # Main(). This code only runs if the script is being run stand-alone rather | |
| 5947 # than as part of a larger application. The controlling predicate is the | |
| 5948 # existence of the variable pkgconf_not_standalone which can be set by | |
| 5949 # the containing program if any. | |
| 5950 # | |
| 5951 | |
| 5952 if { ! [info exists pkgconf_not_standalone] } { | |
| 5953 | |
| 5954 # Do some necessary GUI initialisation such as hiding the main window | |
| 5955 # during startup. | |
| 5956 pkgconf::gui_standalone_init | |
| 5957 | |
| 5958 # Decide where warnings and fatal errors should go. | |
| 5959 pkgconf::initialise_error_handling | |
| 5960 | |
| 5961 # Parse the arguments and set the global variables appropriately. | |
| 5962 pkgconf::parse_arguments $argv0 $argv | |
| 5963 | |
| 5964 # Initialise all the data, e.g. by reading in the packages and | |
| 5965 # targets files. | |
| 5966 pkgconf::initialise_data | |
| 5967 | |
| 5968 # At this stage the code can do one of two things: run the GUI, | |
| 5969 # or build/update the build tree. | |
| 5970 # The GUI can be run if the necessary commands are available and | |
| 5971 # if the user did not pass -nw. | |
| 5972 if { $pkgconf::gui_possible && ! $pkgconf::no_windows_arg } { | |
| 5973 } else { | |
| 5974 set pkgconf::gui_mode 0 | |
| 5975 } | |
| 5976 | |
| 5977 # Reset error handling to the correct mode | |
| 5978 pkgconf::initialise_error_handling | |
| 5979 | |
| 5980 # Either enter GUI mode, or produce the build tree | |
| 5981 if { $pkgconf::gui_mode } { | |
| 5982 pkgconf::gui | |
| 5983 } else { | |
| 5984 pkgconf::produce_build_tree | |
| 5985 exit 0 | |
| 5986 } | |
| 5987 } | |
| 5988 | |
| 5989 # }}} | |
| 5990 | |
| 5991 |
