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