Lines Matching +full:ats +full:- +full:supported
13 # ----- @module proj.tcl -----
14 # @section Project-agnostic Helper APIs
32 # despite this code having a handful of near-twins running around a
33 # handful of third-party source trees.
37 # - Symbols with _ separators are intended for internal use within
39 # rely on. Symbols with - separators are public APIs.
41 # - By and large, autosetup prefers to update global state with the
43 # --X. In this developer's opinion that (A) causes more confusion
47 # well-defined variables and leaves the integration of those values
50 # [1]: As an example: testing for the -rpath flag, using
51 # cc-check-flags, can break later checks which use
52 # [cc-check-function-in-lib ...] because the resulting -rpath flag
60 # $proj__Config is an internal-use-only array for storing whatever generic
64 self-tests 1
69 # List of dot-in files to filter in the final stages of
73 # (which differ from the source dir in out-of-tree builds).
75 # See: proj-dot-ins-append and proj-dot-ins-process
77 set ::proj__Config(dot-in-files) [list]
81 # @proj-warn msg
86 proc proj-warn {args} {
87 show-notices
88 puts stderr [join [list "WARNING: \[[proj-scope 1]\]: " {*}$args] " "]
92 # Internal impl of [proj-fatal] and [proj-error]. It must be called
95 show-notices
97 while {"-up" eq [lindex $argv 0]} {
98 set argv [lassign $argv -]
102 puts stderr [join [list "FATAL: \[[proj-scope $lvl]]: " {*}$argv]]
105 error [join [list "\[[proj-scope $lvl]]:" {*}$argv]]
111 # @proj-fatal ?-up...? msg...
113 # Emits an error message to stderr and exits with non-0. All args are
117 # use the name of a call higher up in the stack, use -up once for each
120 proc proj-fatal {args} {
125 # @proj-error ?-up...? msg...
127 # Works like proj-fatal but uses [error] intead of [exit].
129 proc proj-error {args} {
133 set ::proj__Config(verbose-assert) [get-env proj-assert-verbose 0]
135 # @proj-assert script ?message?
142 proc proj-assert {script {msg ""}} {
143 if {1 eq $::proj__Config(verbose-assert)} {
144 msg-result [proj-bold "asserting: $script"]
150 proj-fatal "Assertion failed in \[[proj-scope 1]\]: $msg"
155 # @proj-bold str
159 # to bold that text, else it returns $str as-is.
161 proc proj-bold {args} {
169 # @proj-indented-notice ?-error? ?-notice? msg
171 # Takes a multi-line message and emits it with consistent indentation.
172 # It does not perform any line-wrapping of its own. Which output
173 # routine it uses depends on its flags, defaulting to msg-result.
174 # For -error and -notice it uses user-notice.
176 # If the -notice flag it used then it emits using [user-notice], which
180 # If the -error flag is provided then it renders the message
183 # If neither -notice nor -error are used, the message will be sent to
186 proc proj-indented-notice {args} {
188 set outFunc "msg-result"
190 switch -exact -- [lindex $args 0] {
191 -error {
193 set outFunc "user-notice"
195 -notice {
196 set args [lassign $args -]
197 set outFunc "user-notice"
214 show-notices
220 # @proj-is-cross-compiling
222 # Returns 1 if cross-compiling, else 0.
224 proc proj-is-cross-compiling {} {
225 expr {[get-define host] ne [get-define build]}
229 # @proj-strip-hash-comments value
235 # comments which appear after the first non-whitespace character.
237 proc proj-strip-hash-comments {val} {
248 # @proj-cflags-without-werror
250 # Fetches [define $var], strips out any -Werror entries, and returns
251 # the new value. This is intended for temporarily stripping -Werror
252 # from CFLAGS or CPPFLAGS within the scope of a [define-push] block.
254 proc proj-cflags-without-werror {{var CFLAGS}} {
256 foreach f [get-define $var ""] {
257 switch -exact -- $f {
258 -Werror {}
266 # @proj-check-function-in-lib
268 # A proxy for cc-check-function-in-lib with the following differences:
270 # - Does not make any global changes to the LIBS define.
272 # - Strips out the -Werror flag from CFLAGS before running the test,
273 # as these feature tests will often fail if -Werror is used.
275 # Returns the result of cc-check-function-in-lib (i.e. true or false).
279 proc proj-check-function-in-lib {function libs {otherlibs {}}} {
281 define-push {LIBS CFLAGS} {
282 #puts "CFLAGS before=[get-define CFLAGS]"
283 define CFLAGS [proj-cflags-without-werror]
284 #puts "CFLAGS after =[get-define CFLAGS]"
285 set found [cc-check-function-in-lib $function $libs $otherlibs]
291 # @proj-search-for-header-dir ?-dirs LIST? ?-subdirs LIST? header
294 # by the -dirs {LIST} and -subdirs {LIST} flags (each of which have
298 proc proj-search-for-header-dir {header args} {
302 # if {![proj-is-cross-compiling]} {
303 # lappend dirs [get-define prefix]
306 switch -exact -- [lindex $args 0] {
307 -dirs { set args [lassign $args - dirs] }
308 -subdirs { set args [lassign $args - subdirs] }
310 proj-error "Unhandled argument: $args"
325 # @proj-find-executable-path ?-v? binaryName
327 # Works similarly to autosetup's [find-executable-path $binName] but:
329 # - If the first arg is -v, it's verbose about searching, else it's quiet.
333 proc proj-find-executable-path {args} {
336 if {[lindex $args 0] eq "-v"} {
338 set args [lassign $args - binName]
339 msg-checking "Looking for $binName ... "
341 set check [find-executable-path $binName]
344 msg-result "not found"
346 msg-result $check
353 # @proj-bin-define binName ?defName?
355 # Uses [proj-find-executable-path $binName] to (verbosely) search for
359 # The define'd name is: If $defName is not empty, it is used as-is. If
360 # $defName is empty then "BIN_X" is used, where X is the upper-case
361 # form of $binName with any '-' characters replaced with '_'.
363 proc proj-bin-define {binName {defName {}}} {
364 set check [proj-find-executable-path -v $binName]
366 set defName "BIN_[string toupper [string map {- _} $binName]]"
373 # @proj-first-bin-of bin...
379 # Despite using cc-path-progs to do the search, this function clears
384 proc proj-first-bin-of {args} {
388 # Note that cc-path-progs defines $u to "false" if it finds no
390 if {[cc-path-progs $b]} {
391 set rc [get-define $u]
400 # @proj-opt-was-provided key
403 # or if it was specifically set using proj-opt-set, else 0. This can
410 # { foo-bar:=baz => {its help text} }
412 # This function will, when passed foo-bar, return 1 only if the user
413 # passes --foo-bar to configure, even if that invocation would resolve
415 # --foo-bar (with or without a value) then this returns 0.
417 # Calling [proj-opt-set] is, for purposes of the above, equivalent to
420 # Note: unlike most functions which deal with configure --flags, this
421 # one does not validate that $key refers to a pre-defined flag. i.e.
423 # call. [proj-opt-set] manipulates the internal list of flags, such
425 # return true. (That's an unintended and unavoidable side-effect, not
428 proc proj-opt-was-provided {key} {
433 # @proj-opt-set flag ?val?
435 # Force-set autosetup option $flag to $val. The value can be fetched
436 # later with [opt-val], [opt-bool], and friends.
440 proc proj-opt-set {flag {val 1}} {
443 # to [opt-bool $flag] will fail validation of $flag.
451 # @proj-opt-exists flag
456 proc proj-opt-exists {flag} {
461 # @proj-val-truthy val
466 proc proj-val-truthy {val} {
471 # @proj-opt-truthy flag
473 # Returns 1 if [opt-val $flag] appears to be a truthy value or
474 # [opt-bool $flag] is true. See proj-val-truthy.
476 proc proj-opt-truthy {flag} {
477 if {[proj-val-truthy [opt-val $flag]]} { return 1 }
480 # opt-bool will throw if $flag is not a known boolean flag
481 set rc [opt-bool $flag]
487 # @proj-if-opt-truthy boolFlag thenScript ?elseScript?
489 # If [proj-opt-truthy $flag] is true, eval $then, else eval $else.
491 proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} {
492 if {[proj-opt-truthy $boolFlag]} {
500 # @proj-define-for-opt flag def ?msg? ?iftrue? ?iffalse?
502 # If [proj-opt-truthy $flag] then [define $def $iftrue] else [define
503 # $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and
504 # a [msg-results ...] which corresponds to the result. Returns 1 if
505 # the opt-truthy check passes, else 0.
507 proc proj-define-for-opt {flag def {msg ""} {iftrue 1} {iffalse 0}} {
509 msg-checking "$msg "
513 if {[proj-opt-truthy $flag]} {
519 switch -- [proj-val-truthy [get-define $def]] {
524 msg-result $rcMsg
530 # @proj-opt-define-bool ?-v? optName defName ?descr?
532 # Checks [proj-opt-truthy $optName] and calls [define $defName X]
534 # [msg-checking] argument which defaults to $defName. Returns X.
536 # If args[0] is -v then the boolean semantics are inverted: if
540 proc proj-opt-define-bool {args} {
542 if {[lindex $args 0] eq "-v"} {
544 lassign $args - optName defName descr
553 msg-checking "[join $descr] ... "
554 set rc [proj-opt-truthy $optName]
558 msg-result $rc
564 # @proj-check-module-loader
566 # Check for module-loading APIs (libdl/libltdl)...
568 # Looks for libltdl or dlopen(), the latter either in -ldl or built in
572 # - HAVE_LIBLTDL to 1 or 0 if libltdl is found/not found
573 # - HAVE_LIBDL to 1 or 0 if dlopen() is found/not found
574 # - LDFLAGS_MODULE_LOADER one of ("-lltdl", "-ldl", or ""), noting
575 # that -ldl may legally be empty on some platforms even if
577 # extra link flags). LDFLAGS_MODULE_LOADER also gets "-rdynamic" appended
584 proc proj-check-module-loader {} {
585 msg-checking "Looking for module-loader APIs... "
586 if {99 ne [get-define LDFLAGS_MODULE_LOADER 99]} {
587 if {1 eq [get-define HAVE_LIBLTDL 0]} {
588 msg-result "(cached) libltdl"
590 } elseif {1 eq [get-define HAVE_LIBDL 0]} {
591 msg-result "(cached) libdl"
600 puts "" ;# cosmetic kludge for cc-check-XXX
601 if {[cc-check-includes ltdl.h] && [cc-check-function-in-lib lt_dlopen ltdl]} {
603 set LDFLAGS_MODULE_LOADER "-lltdl -rdynamic"
604 msg-result " - Got libltdl."
606 } elseif {[cc-with {-includes dlfcn.h} {
607 cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} {
608 msg-result " - This system can use dlopen() without -ldl."
612 } elseif {[cc-check-includes dlfcn.h]} {
615 if {[cc-check-function-in-lib dlopen dl]} {
616 msg-result " - dlopen() needs libdl."
617 set LDFLAGS_MODULE_LOADER "-ldl -rdynamic"
619 msg-result " - dlopen() not found in libdl. Assuming dlopen() is built-in."
620 set LDFLAGS_MODULE_LOADER "-rdynamic"
630 # @proj-no-check-module-loader
632 # Sets all flags which would be set by proj-check-module-loader to
637 proc proj-no-check-module-loader {} {
644 # @proj-file-content ?-trim? filename
647 # the first arg is -trim, the contents of the file named by the second
650 proc proj-file-content {args} {
653 if {"-trim" eq [lindex $args 0]} {
655 lassign $args - fname
665 # @proj-file-conent filename
670 proc proj-file-content-list {fname} {
681 # @proj-file-write ?-ro? fname content
685 # overwritten, even if it's flagged as read-only.
687 proc proj-file-write {args} {
688 if {"-ro" eq [lindex $args 0]} {
694 file delete -force -- $fname; # in case it's read-only
696 puts -nonewline $f $content
700 exec chmod -w $fname
701 #file attributes -w $fname; #jimtcl has no 'attributes'
707 # @proj-check-compile-commands ?configFlag?
713 # Returns 1 if supported, else 0, and defines HAVE_COMPILE_COMMANDS to
714 # that value. Defines MAKE_COMPILATION_DB to "yes" if supported, "no"
719 # because of compilers reacting differently to the -MJ flag.
721 proc proj-check-compile-commands {{configFlag {}}} {
722 msg-checking "compile_commands.json support... "
723 if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} {
724 msg-result "explicitly disabled"
729 if {[cctest -lang c -cflags {/dev/null -MJ} -source {}]} {
733 msg-result "compiler supports compile_commands.json"
738 msg-result "compiler does not support compile_commands.json"
747 # @proj-touch filename
752 proc proj-touch {filename} {
757 # @proj-make-from-dot-in ?-touch? infile ?outfile?
759 # Uses [make-template] to create makefile(-like) file(s) $outfile from
760 # $infile but explicitly makes the output read-only, to avoid
765 # - If $infile is a 2-element list, it is assumed to be an in/out pair,
768 # - $outfile is set to $infile stripped of its extension.
770 # If the first argument is -touch then the generated file is touched
778 proc proj-make-from-dot-in {args} {
782 if {[lindex $args 0] eq "-touch"} {
784 lassign $args - fIn fOut
800 #define-push {top_srcdir} {
801 #puts "--- $fIn $fOut top_srcdir=[get-define top_srcdir]"
802 make-template $fIn $fOut
803 #puts "--- $fIn $fOut top_srcdir=[get-define top_srcdir]"
804 # make-template modifies top_srcdir
807 proj-touch $fOut
810 exec chmod -w $fOut
811 #file attributes -w $f; #jimtcl has no 'attributes'
816 # @proj-check-profile-flag ?flagname?
820 # then it defines CC_PROFILE_FLAG to "-pg" and returns 1, else it
825 # order to avoid potential problems with escaping, space-containing
829 proc proj-check-profile-flag {{flagname profile}} {
830 #puts "flagname=$flagname ?[proj-opt-truthy $flagname]?"
831 if {[proj-opt-truthy $flagname]} {
832 set CC [get-define CC]
837 if { ![catch { exec $CC --version } msg]} {
838 if {[string first gcc $CC] != -1} {
839 define CC_PROFILE_FLAG "-pg"
849 # @proj-looks-like-windows ?key?
860 proc proj-looks-like-windows {{key host}} {
862 switch -glob -- [get-define $key] {
863 *-*-ming* - *-*-cygwin - *-*-msys - *windows* {
868 # These apply only to the local OS, not a cross-compilation target,
871 if {[find-an-executable cygpath] ne "" || $::tcl_platform(os) eq "Windows NT"} {
879 # @proj-looks-like-mac ?key?
882 # 'build' (==the being-built-on platform) define value and returns if
886 proc proj-looks-like-mac {{key host}} {
887 switch -glob -- [get-define $key] {
898 # @proj-exe-extension
901 # host and target are Windows-esque (Cygwin, MinGW, MSys). If the
906 proc proj-exe-extension {} {
909 if {[proj-looks-like-windows host]} {
912 if {[proj-looks-like-windows build]} {
920 # @proj-dll-extension
922 # Works like proj-exe-extension except that it defines BUILD_DLLEXT
925 # Trivia: for .dylib files, the linker needs the -dynamiclib flag
926 # instead of -shared.
928 proc proj-dll-extension {} {
930 switch -glob -- [get-define $key] {
934 *-*-ming* - *-*-cygwin - *-*-msys {
947 # @proj-lib-extension
949 # Static-library counterpart of proj-dll-extension. Defines
951 # extension for the being-built-on resp. the target platform.
953 proc proj-lib-extension {} {
955 switch -glob -- [get-define $key] {
956 *-*-ming* - *-*-cygwin - *-*-msys {
958 # ^^^ this was ".lib" until 2025-02-07. See
971 # @proj-file-extensions
973 # Calls all of the proj-*-extension functions.
975 proc proj-file-extensions {} {
976 proj-exe-extension
977 proj-dll-extension
978 proj-lib-extension
982 # @proj-affirm-files-exist ?-v? filename...
986 # Returns the last file name it checks. If the first argument is -v
987 # then it emits msg-checking/msg-result messages for each file.
989 proc proj-affirm-files-exist {args} {
992 if {[lindex $args 0] eq "-v"} {
997 if {$verbose} { msg-checking "Looking for $f ... " }
999 user-error "not found: $f"
1001 if {$verbose} { msg-result "" }
1008 # @proj-check-emsdk
1010 # Emscripten is used for doing in-tree builds of web-based WASM stuff,
1011 # as opposed to WASI-based WASM or WASM binaries we import from other
1012 # places. This is only set up for Unix-style OSes and is untested
1013 # anywhere but Linux. Requires that the --with-emsdk flag be
1016 # It looks for the SDK in the location specified by --with-emsdk.
1024 # If the --with-emsdk[=DIR] flag is explicitly provided and the SDK is
1030 # - HAVE_EMSDK = 0 or 1 (this function's return value)
1031 # - EMSDK_HOME = "" or top dir of the emsdk
1032 # - EMSDK_ENV_SH = "" or $EMSDK_HOME/emsdk_env.sh
1033 # - BIN_EMCC = "" or $EMSDK_HOME/upstream/emscripten/emcc
1040 proc proj-check-emsdk {} {
1041 set emsdkHome [opt-val with-emsdk]
1046 msg-checking "Emscripten SDK? "
1049 set emsdkHome [get-env EMSDK ""]
1056 msg-result "$emsdkHome"
1064 msg-result "emsdk_env.sh not found in $emsdkHome"
1067 msg-result "not found"
1071 proj-fatal "Cannot find the Emscripten SDK"
1078 # @proj-cc-check-Wl-flag ?flag ?args??
1083 # - -Wl,flag[,arg1[,...argN]]
1084 # - -Wl,flag -Wl,arg1 ...-Wl,argN
1089 proc proj-cc-check-Wl-flag {args} {
1090 cc-with {-link 1} {
1091 # Try -Wl,flag,...args
1092 set fli "-Wl"
1094 if {[cc-check-flags $fli]} {
1097 # Try -Wl,flag -Wl,arg1 ...-Wl,argN
1099 foreach f $args { append fli "-Wl,$f " }
1100 if {[cc-check-flags $fli]} {
1108 # @proj-check-rpath
1110 # Tries various approaches to handling the -rpath link-time
1115 # --exec-prefix=... or --libdir=... are explicitly passed to
1116 # configure then [get-define libdir] is used (noting that it derives
1117 # from exec-prefix by default).
1119 proc proj-check-rpath {} {
1120 if {[proj-opt-was-provided libdir]
1121 || [proj-opt-was-provided exec-prefix]} {
1122 set lp "[get-define libdir]"
1124 set lp "[get-define prefix]/lib"
1126 # If we _don't_ use cc-with {} here (to avoid updating the global
1127 # CFLAGS or LIBS or whatever it is that cc-check-flags updates) then
1130 cc-with {-link 1} {
1131 if {[cc-check-flags "-rpath $lp"]} {
1132 define LDFLAGS_RPATH "-rpath $lp"
1134 set wl [proj-cc-check-Wl-flag -rpath $lp]
1136 set wl [proj-cc-check-Wl-flag -R$lp]
1141 expr {"" ne [get-define LDFLAGS_RPATH]}
1145 # @proj-check-soname ?libname?
1147 # Checks whether CC supports the -Wl,soname,lib... flag. If so, it
1155 # potentially avoid some end-user confusion by using their own lib's
1158 proc proj-check-soname {{libname "libfoo.so.0"}} {
1159 cc-with {-link 1} {
1160 if {[cc-check-flags "-Wl,-soname,${libname}"]} {
1161 define LDFLAGS_SONAME_PREFIX "-Wl,-soname,"
1171 # @proj-check-fsanitize ?list-of-opts?
1173 # Checks whether CC supports -fsanitize=X, where X is each entry of
1174 # the given list of flags. If any of those flags are supported, it
1175 # returns the string "-fsanitize=X..." where X... is a comma-separated
1176 # list of all flags from the original set which are supported. If none
1177 # of the given options are supported then it returns an empty string.
1181 # set f [proj-check-fsanitize {address bounds-check just-testing}]
1183 # Will, on many systems, resolve to "-fsanitize=address,bounds-check",
1184 # but may also resolve to "-fsanitize=address".
1186 proc proj-check-fsanitize {{opts {address bounds-strict}}} {
1189 # -nooutput is used because -fsanitize=hwaddress will otherwise
1191 # "hwaddress is not supported for this target".
1192 cc-with {-nooutput 1} {
1193 if {[cc-check-flags "-fsanitize=$opt"]} {
1199 return "-fsanitize=[join $sup ,]"
1205 # Internal helper for proj-dump-defs-json. Expects to be passed a
1207 # proj-dump-defs-json. If it finds a pattern match for the given
1209 # e.g. "-str" or "-bare", else returns an empty string.
1211 proc proj-defs-type_ {name spec} {
1223 # Internal helper for proj-defs-format_: returns a JSON-ish quoted
1224 # form of the given string-type values. It only performs the most
1228 proc proj-quote-str_ {value} {
1233 # An internal impl detail of proj-dump-defs-json. Requires a data
1234 # type specifier, as used by make-config-header, and a value. Returns
1235 # the formatted value or the value $::proj__Config(defs-skip) if the caller
1238 set ::proj__Config(defs-skip) "-proj-defs-format_ sentinel"
1239 proc proj-defs-format_ {type value} {
1240 switch -exact -- $type {
1241 -bare {
1244 -none {
1245 set value $::proj__Config(defs-skip)
1247 -str {
1248 set value [proj-quote-str_ $value]
1250 -auto {
1252 if {![string is integer -strict $value]} {
1253 set value [proj-quote-str_ $value]
1256 -array {
1259 set v [proj-defs-format_ -auto $v]
1260 if {$::proj__Config(defs-skip) ne $v} {
1267 set value $::proj__Config(defs-skip)
1270 proj-fatal "Unknown type in proj-dump-defs-json: $type"
1277 # @proj-dump-defs-json outfile ...flags
1280 # make-config-header but emits its output in JSON form. It is not a
1281 # fully-functional JSON emitter, and will emit broken JSON for
1285 # In addition to the formatting flags supported by make-config-header,
1288 # -array {patterns...}
1291 # values, each of which will be formatted as if it were in an -auto {...}
1296 # Achtung: if a given -array pattern contains values which themselves
1299 # define-append foo {"-DFOO=bar baz" -DBAR="baz barre"}
1303 # ["-DFOO=bar baz", "-DBAR=\"baz", "barre\""]
1309 proc proj-dump-defs-json {file args} {
1312 lappend args -bare {SIZEOF_* HAVE_DECL_*} -auto HAVE_*
1313 foreach n [lsort [dict keys [all-defines]]] {
1314 set type [proj-defs-type_ $n $args]
1315 set value [proj-defs-format_ $type [get-define $n]]
1316 if {$::proj__Config(defs-skip) ne $value} {
1322 write-if-changed $file $buf {
1323 msg-result "Created $file"
1328 # @proj-xfer-option-aliases map
1336 # The names must not have their leading -- part and must be in the
1337 # form which autosetup will expect for passing to [opt-val NAME] and
1342 # For each pair of ALIAS and CANONICAL, if --ALIAS is provided but
1343 # --CANONICAL is not, the value of the former is copied to the
1344 # latter. If --ALIAS is not provided, this is a no-op. If both have
1348 # and elides the aliases from --help output but does no further
1349 # handling of them. For example, when --alias is a hidden alias of
1350 # --canonical and a user passes --alias=X, [opt-val canonical] returns
1351 # no value. i.e. the script must check both [opt-val alias] and
1352 # [opt-val canonical]. The intent here is that this function be
1355 # that [opt-value canonical] will return X if --alias=X is passed to
1358 # That said: autosetup's [opt-str] does support alias forms, but it
1361 # which each down-stream call of [opt-...] has to know.
1363 proc proj-xfer-options-aliases {mapping} {
1364 foreach {hidden - canonical} [proj-strip-hash-comments $mapping] {
1365 if {[proj-opt-was-provided $hidden]} {
1366 if {[proj-opt-was-provided $canonical]} {
1367 proj-fatal "both --$canonical and its alias --$hidden were used. Use only one or the other."
1369 proj-opt-set $canonical [opt-val $hidden]
1378 # When _not_ cross-compiling and CC_FOR_BUILD is _not_ explicitly
1383 # will use CC_FOR_BUILD=clang, instead of cc, for building in-tree
1392 proc proj-redefine-cc-for-build {} {
1393 if {![proj-is-cross-compiling]
1394 && [get-define CC] ne [get-define CC_FOR_BUILD]
1395 && "nope" eq [get-env CC_FOR_BUILD "nope"]} {
1396 …user-notice "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR…
1397 define CC_FOR_BUILD [get-define CC]
1402 # @proj-which-linenoise headerFile
1409 proc proj-which-linenoise {dotH} {
1410 set srcHeader [proj-file-content $dotH]
1419 # @proj-remap-autoconf-dir-vars
1421 # "Re-map" the autoconf-conventional --XYZdir flags into something
1428 # $ ./configure --prefix=/foo
1431 # In that make invocation, $(libdir) would, at make-time, normally be
1432 # hard-coded to /foo/lib, rather than /blah/lib. That happens because
1433 # autosetup exports conventional $prefix-based values for the numerous
1434 # autoconfig-compatible XYZdir vars at configure-time. What we would
1435 # normally want, however, is that --libdir derives from the make-time
1436 # $(prefix). The distinction between configure-time and make-time is
1440 # they will derive, at make-time, from $(prefix) in a conventional
1441 # manner unless they are explicitly overridden at configure-time, in
1444 # Each autoconf-relvant --XYZ flag which is explicitly passed to
1445 # configure is exported as-is, as are those which default to some
1446 # top-level system directory, e.g. /etc or /var. All which derive
1449 # --exec-prefix=FOO is passed to configure, libdir will still derive,
1450 # at make-time, from whatever exec_prefix is passed to make, and will
1451 # use FOO if exec_prefix is not overridden at make-time. Without this
1452 # post-processing, libdir would be cemented in as FOO/lib at
1453 # configure-time, so could be tedious to override properly via a make
1456 proc proj-remap-autoconf-dir-vars {} {
1457 set prefix [get-define prefix]
1458 set exec_prefix [get-define exec_prefix $prefix]
1463 exec-prefix exec_prefix ${prefix}
1477 if {[proj-opt-was-provided $flag]} {
1478 define $makeVar [join [opt-val $flag]]
1484 # e.g. --libdir=\${prefix}/foo/bar. Debian's SQLite package build
1490 # @proj-env-file flag ?default?
1492 # If a file named .env-$flag exists, this function returns a
1494 # usage is that things like developer-specific CFLAGS preferences can
1495 # be stored in .env-CFLAGS.
1497 proc proj-env-file {flag {dflt ""}} {
1498 set fn ".env-${flag}"
1500 return [proj-file-content -trim $fn]
1506 # @proj-get-env var ?default?
1511 # - Passed to configure as $var=...
1512 # - Exists as an environment variable
1513 # - A file named .env-$var (see [proj-env-file])
1517 proc proj-get-env {var {dflt ""}} {
1518 get-env $var [proj-env-file $var $dflt]
1522 # @proj-scope ?lvl?
1530 proc proj-scope {{lvl 0}} {
1533 set offset [expr {$ilvl - $lvl - 1}]
1544 # Deprecated name of [proj-scope].
1546 proc proj-current-scope {{lvl 0}} {
1548 "Deprecated proj-current-scope called from [proj-scope 1]. Use proj-scope instead."
1549 proj-scope [incr lvl]
1560 proc proj-tclConfig-sh-to-autosetup {tclConfigSh} {
1593 # @proj-tweak-default-env-dirs
1596 # --prefix and friends. It should be called as soon after [use system]
1599 # For certain target environments, if --prefix is _not_ passed in by
1600 # the user, set the prefix to an environment-specific default. For
1601 # such environments its does [define prefix ...] and [proj-opt-set
1603 # e.g. exec-prefix. To do so it is generally necessary to also call
1604 # proj-remap-autoconf-dir-vars late in the config process (immediately
1607 # Similar modifications may be made for --mandir.
1611 proc proj-tweak-default-env-dirs {} {
1613 switch -glob -- [get-define host] {
1614 *-haiku {
1615 if {![proj-opt-was-provided prefix]} {
1616 set hdir /boot/home/config/non-packaged
1617 proj-opt-set prefix $hdir
1621 if {![proj-opt-was-provided mandir]} {
1623 proj-opt-set mandir $hdir
1633 # @proj-dot-ins-append file ?fileOut ?postProcessScript??
1635 # Queues up an autosetup [make-template]-style file to be processed
1636 # at a later time using [proj-dot-ins-process].
1644 # [proj-dot-ins-process], it will be eval'd immediately after
1650 # See [proj-dot-ins-process], [proj-dot-ins-list]
1652 proc proj-dot-ins-append {fileIn args} {
1654 switch -exact -- [llength $args] {
1665 proj-fatal "Too many arguments: $fileIn $args"
1668 #puts "******* [proj-scope]: adding $fileIn"
1669 lappend ::proj__Config(dot-in-files) $fileIn
1673 # @proj-dot-ins-list
1675 # Returns the current list of [proj-dot-ins-append]'d files, noting
1676 # that each entry is a 3-element list of (inputFileName,
1679 proc proj-dot-ins-list {} {
1680 return $::proj__Config(dot-in-files)
1684 # @proj-dot-ins-process ?-touch? ?-validate? ?-clear?
1686 # Each file which has previously been passed to [proj-dot-ins-append]
1687 # is processed, with its passing its in-file out-file names to
1688 # [proj-make-from-dot-in].
1696 # -touch: gets passed on to [proj-make-from-dot-in]
1698 # -validate: after processing each file, before running the file's
1700 # proj-validate-no-unresolved-ats, erroring out if that does.
1702 # -clear: after processing, empty the dot-ins list. This effectively
1703 # makes proj-dot-ins-append available for re-use.
1705 proc proj-dot-ins-process {args} {
1706 proj-parse-simple-flags args flags {
1707 -touch "" {return "-touch"}
1708 -clear 0 {expr 1}
1709 -validate 0 {expr 1}
1712 error "Invalid argument to [proj-scope]: $args"
1714 foreach f $::proj__Config(dot-in-files) {
1715 proj-assert {3==[llength $f]} \
1716 "Expecting proj-dot-ins-list to be stored in 3-entry lists"
1719 proj-make-from-dot-in {*}$flags(-touch) $fIn $fOut
1720 if {$flags(-validate)} {
1721 proj-validate-no-unresolved-ats $fOut
1730 if {$flags(-clear)} {
1731 set ::proj__Config(dot-in-files) [list]
1736 # @proj-validate-no-unresolved-ats filenames...
1750 proc proj-validate-no-unresolved-ats {args} {
1754 foreach line [proj-file-content-list $f] {
1756 if {[regexp {(@[A-Za-z0-9_]+@)} $line match]} {
1766 # @proj-first-file-found tgtVar fileList
1772 proc proj-first-file-found {tgtVar fileList} {
1785 # Defines $defName to contain makefile recipe commands for re-running
1789 proc proj-setup-autoreconfig {defName} {
1793 && [get-define AUTOREMAKE "error - missing @AUTOREMAKE@"]]]
1797 # @prop-append-to defineName args...
1799 # A proxy for Autosetup's [define-append]. Appends all non-empty $args
1800 # to [define-append $defineName].
1802 proc proj-define-append {defineName args} {
1805 define-append $defineName {*}$a
1811 # @prod-define-amend ?-p|-prepend? ?-d|-define? defineName args...
1813 # A proxy for Autosetup's [define-append].
1815 # Appends all non-empty $args to the define named by $defineName. If
1816 # one of (-p | -prepend) are used it instead prepends them, in their
1819 # If -define is used then each argument is assumed to be a [define]'d
1820 # flag and [get-define X ""] is used to fetch it.
1822 # Re. linker flags: typically, -lXYZ flags need to be in "reverse"
1823 # order, with each -lY resolving symbols for -lX's to its left. This
1828 # See: proj-append-to
1830 proc proj-define-amend {args} {
1836 switch -exact -- $arg {
1838 -p - -prepend { incr prepend }
1839 -d - -define { incr isdefs }
1850 proj-error "Missing defineName argument in call from [proj-scope 1]"
1856 lappend xargs [get-define $arg ""]
1865 lappend args {*}[get-define $defName ""]
1868 proj-define-append $defName {*}$args
1873 # @proj-define-to-cflag ?-list? ?-quote? ?-zero-undef? defineName...
1878 # -D$name
1879 # -D$name=integer (strict integer matches only)
1880 # '-D$name=value' (without -quote)
1881 # '-D$name="value"' (with -quote)
1887 # The -zero-undef flag causes no -D to be emitted for integer values
1890 # By default it returns the result as string of all -D... flags,
1891 # but if passed the -list flag it will return a list of the
1894 proc proj-define-to-cflag {args} {
1896 proj-parse-simple-flags args flags {
1897 -list 0 {expr 1}
1898 -quote 0 {expr 1}
1899 -zero-undef 0 {expr 1}
1902 set v [get-define $d ""]
1905 set v "-D${d}"
1906 } elseif {[string is integer -strict $v]} {
1907 if {!$flags(-zero-undef) || $v ne "0"} {
1908 set v "-D${d}=$v"
1910 } elseif {$flags(-quote)} {
1911 set v "'-D${d}=\"$v\"'"
1913 set v "'-D${d}=$v'"
1917 expr {$flags(-list) ? $rv : [join $rv]}
1922 # Turns out that autosetup's [options-add] essentially does exactly
1925 # A list of lists of Autosetup [options]-format --flags definitions.
1926 # Append to this using [proj-options-add] and use
1927 # [proj-options-combine] to merge them into a single list for passing
1930 set ::proj__Config(extra-options) {}
1932 # @proj-options-add list
1934 # Adds a list of options to the pending --flag processing. It must be
1940 # Use [proj-options-combine] to get a combined list of all added
1943 # PS: when writing this i wasn't aware of autosetup's [options-add],
1945 proc proj-options-add {list} {
1946 lappend ::proj__Config(extra-options) $list
1949 # @proj-options-combine list1 ?...listN?
1953 # contents of each list into a new top-level list, stripping the outer
1957 # [proj-options-add].
1958 proc proj-options-combine {args} {
1961 set args $::proj__Config(extra-options)
1968 }; # proj-options-*
1970 # Internal cache for use via proj-cache-*.
1974 # @proj-cache-key arg {addLevel 0}
1976 # Helper to generate cache keys for [proj-cache-*].
1983 # use as a key. [proj-scope [expr {1 + $arg + addLevel}]] is
1987 # Anything else: returned as-is
1989 proc proj-cache-key {arg {addLevel 0}} {
1990 if {[string is integer -strict $arg]} {
1991 return [proj-scope [expr {$arg + $addLevel + 1}]]
1997 # @proj-cache-set ?-key KEY? ?-level 0? value
1999 # Sets a feature-check cache entry with the given key.
2001 # See proj-cache-key for -key's and -level's semantics, noting that
2002 # this function adds one to -level for purposes of that call.
2003 proc proj-cache-set {args} {
2004 proj-parse-simple-flags args flags {
2005 -key => 0
2006 -level => 0
2009 set key [proj-cache-key $flags(-key) [expr {1 + $flags(-level)}]]
2015 # @proj-cache-remove ?key? ?addLevel?
2017 # Removes an entry from the proj-cache.
2018 proc proj-cache-remove {{key 0} {addLevel 0}} {
2019 set key [proj-cache-key $key [expr {1 + $addLevel}]]
2029 # @proj-cache-check ?-key KEY? ?-level LEVEL? tgtVarName
2031 # Checks for a feature-check cache entry with the given key.
2033 # If the feature-check cache has a matching entry then this function
2037 # See proj-cache-key for $key's and $addLevel's semantics, noting that
2039 proc proj-cache-check {args} {
2040 proj-parse-simple-flags args flags {
2041 -key => 0
2042 -level => 0
2047 set key [proj-cache-key $flags(-key) [expr {1 + $flags(-level)}]]
2059 # @proj-coalesce ...args
2063 proc proj-coalesce {args} {
2073 # @proj-parse-simple-flags ...
2078 # -flag values to, and a prototype object which declares the flags.
2082 # -flag defaultValue {script}
2084 # -flag => defaultValue
2085 # -----^--^ (with spaces there!)
2100 # $argv contains -flag, and the result of that script is the new value
2101 # for $tgtArrayName(-flag). This function intercepts [return $val]
2106 # not described by $prototype. i.e. the first "non-flag" (not counting
2107 # values consumed for flags defined like --flag=>default).
2109 # If a "--" flag is encountered, no more arguments are inspected as
2110 # flags. If "--" is the first non-flag argument, the "--" flag is
2112 # through. If "--" appears after the first non-flag, it is retained.
2115 # more than once behaves in a last-one-wins fashion.
2124 # set args [list -foo -bar {blah} 8 9 10 -theEnd]
2125 # proj-parse-simple-flags args flags {
2126 # -foo 0 {expr 1}
2127 # -bar => 0
2128 # -no-baz 2 {return 0}
2131 # After that $flags would contain {-foo 1 -bar {blah} -no-baz 2}
2132 # and $args would be {8 9 10 -theEnd}.
2137 # argv list, rather than stopping at the first non-flag
2139 proc proj-parse-simple-flags {argvName tgtArrayName prototype} {
2150 proj-assert {[string match -* $k]} \
2154 switch -exact -- [lindex $prototype [expr {$i + 1}]] {
2158 proj-error "Missing argument for $k => flag"
2183 } elseif {"--" eq $arg} {
2188 proj-assert 0 {Cannot happen - bounds already checked}
2213 if {$::proj__Config(self-tests)} {
2215 #proj-warn "Test code for proj-cache"
2216 proj-assert {![proj-cache-check -key here check]}
2217 proj-assert {"here" eq [proj-cache-key here]}
2218 proj-assert {"" eq $check}
2219 proj-cache-set -key here thevalue
2220 proj-assert {[proj-cache-check -key here check]}
2221 proj-assert {"thevalue" eq $check}
2223 proj-assert {![proj-cache-check check]}
2224 #puts "*** key = ([proj-cache-key 0])"
2225 proj-assert {"" eq $check}
2226 proj-cache-set abc
2227 proj-assert {[proj-cache-check check]}
2228 proj-assert {"abc" eq $check}
2231 proj-assert {"" ne [proj-cache-remove]}
2232 proj-assert {![proj-cache-check check]}
2233 proj-assert {"" eq [proj-cache-remove]}
2234 proj-assert {"" eq $check}