diff --git a/auto.def b/auto.def index 87a9670cae..01badb8b53 100644 --- a/auto.def +++ b/auto.def @@ -150,18 +150,17 @@ set flags { # --with-tcl=DIR may be either a dir containing tclConfig.sh or a # dir one level up from that from which we can derive a dir # containing tclConfig.sh. - with-tcl:DIR => {Root of path containing tclConfig.sh} + with-tcl: => {Root of path containing tclConfig.sh} # If --with-tclsh=X given, it is used for (A) trying to find # tclConfig.sh and (B) all TCL-based code generation. Warning: if # its containing dir has multiple tclsh versions, it may select the # wrong tclConfig.sh! with-tclsh:PATH => {Full pathname of tclsh to use} - # --disable-tcl only disables building of the SQLite TCL extension, - # not the requirement for TCL. This tree requires TCL for code - # generation but can use the in-tree copy of autosetup/jimsh0.c for - # that. The SQLite TCL extension and, by extension, the test code - # require a canonical tclsh. - tcl=1 => {Disable components which require TCL-dev} + # --disable-tcl disables building of components which require TCL, + # including tests. This tree requires TCL for code generation but + # can use the in-tree copy of autosetup/jimsh0.c for that. The + # SQLite TCL extension and the test code require a canonical tclsh. + tcl=1 => {Disable components which require TCL} # # readline=1 => {Disable readline support} @@ -466,22 +465,26 @@ proj-if-opt-truthy with-debug { # # - TCLLIBDIR is the dir to which libtclsqlite3 gets installed. # -# - TCLLIB_RPATH = the -rpath flag specific to libtclsqlite3, which -# will usually differ from the rpath used by the rest of the lib. -# # - BTCLSH = the path to the tcl interpreter used for in-tree code # generation. It may be jimtcl or the canonical tclsh but may not # be empty - this tree requires TCL to generated numerous # components. # +# If --tcl or --with-tcl are provided but no TCL is found, this +# function fails fatally. If they are not explicitly provided then +# failure to find TCL is not fatal but a loud warning will be emitted. +# proc sqlite-check-tcl {} { define TCLSH_CMD false ; # Significant is that it exits with non-0 define HAVE_TCL 0 ; # Will be enabled via --tcl or a successful search define TCLLIBDIR "" ; # Installation dir for TCL extension lib - define TCLLIB_RPATH "" ; # rpath for TCL extension lib define TCL_CONFIG_SH ""; # full path to tclConfig.sh if {![opt-bool tcl]} { - msg-result "TCL disabled via --disable-tcl. Will not be able to run tests." + proj-indented-notice { + NOTE: TCL is disabled via --disable-tcl. This means that none + of the TCL-based components, including tests and sqlite3_analyzer, + will be built. + } return } # TODO: document the steps this is taking. @@ -491,6 +494,9 @@ proc sqlite-check-tcl {} { set use_tcl 1 set with_tclsh [opt-val with-tclsh] set with_tcl [opt-val with-tcl] + if {"prefix" eq $with_tcl} { + set with_tcl [get-define prefix] + } msg-debug "sqlite-check-tcl: use_tcl ${use_tcl}" msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" msg-debug "sqlite-check-tcl: with_tcl=$with_tcl" @@ -501,9 +507,10 @@ proc sqlite-check-tcl {} { msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" } + set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases if {"" ne $with_tclsh} { - # --with-tclsh was provided. Validate it and use it to trump any - # value passed via --with-tcl=DIR. + # --with-tclsh was provided or found above. Validate it and use it + # to trump any value passed via --with-tcl=DIR. if {![file isfile $with_tclsh]} { proj-fatal "TCL shell $with_tclsh is not a file" } elseif {![file-isexec $with_tclsh]} { @@ -512,23 +519,23 @@ proc sqlite-check-tcl {} { define TCLSH_CMD $with_tclsh #msg-result "Using tclsh: $with_tclsh" } - if {[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { + if {$doConfigLookup && + [catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { set with_tcl $result } if {"" ne $with_tcl && [file isdir $with_tcl]} { msg-result "$with_tclsh recommends the tclConfig.sh from $with_tcl" } else { - proj-warn "$with_tclsh is unable to recommand a tclConfig.sh" + proj-warn "$with_tclsh is unable to recommend a tclConfig.sh" set use_tcl 0 } } - set cfg "" set tclSubdirs {tcl9.0 tcl8.6 lib} - while {1} { - if {$use_tcl} { - if {"" ne $with_tcl} { - # Ensure that we can find tclConfig.sh under ${with_tcl}/... + while {$use_tcl} { + if {"" ne $with_tcl} { + # Ensure that we can find tclConfig.sh under ${with_tcl}/... + if {$doConfigLookup} { if {[file readable "${with_tcl}/tclConfig.sh"]} { set cfg "${with_tcl}/tclConfig.sh" } else { @@ -539,39 +546,31 @@ proc sqlite-check-tcl {} { } } } - if {"" eq $cfg} { - proj-fatal "No tclConfig.sh found under ${with_tcl}" - } + } + if {"" eq $cfg} { + proj-fatal "No tclConfig.sh found under ${with_tcl}" + } + } else { + # If we have not yet found a tclConfig.sh file, look in + # $libdir which is set automatically by autosetup or by the + # --prefix command-line option. See + # https://sqlite.org/forum/forumpost/e04e693439a22457 + set libdir [get-define libdir] + if {[file readable "${libdir}/tclConfig.sh"]} { + set cfg "${libdir}/tclConfig.sh" } else { - # If we have not yet found a tclConfig.sh file, look in - # $libdir which is set automatically by autosetup or by the - # --prefix command-line option. See - # https://sqlite.org/forum/forumpost/e04e693439a22457 - set libdir [get-define libdir] - if {[file readable "${libdir}/tclConfig.sh"]} { - set cfg "${libdir}/tclConfig.sh" - } else { - foreach i $tclSubdirs { - if {[file readable "${libdir}/$i/tclConfig.sh"]} { - set cfg "${libdir}/$i/tclConfig.sh" - break - } + foreach i $tclSubdirs { + if {[file readable "${libdir}/$i/tclConfig.sh"]} { + set cfg "${libdir}/$i/tclConfig.sh" + break } } - if {![file readable $cfg]} { - proj-indented-notice { - WARNING: Cannot find a usable tclConfig.sh file. Use - --with-tcl=DIR to specify a directory where tclConfig.sh - can be found. SQLite does not use TCL internally, but TCL - is required for testing. - } - break - } } - msg-result "Using tclConfig.sh: $cfg" - } else { - proj-warn "Unable to run tests because no tclConfig.sh file could be located" + if {![file readable $cfg]} { + break + } } + msg-result "Using tclConfig.sh: $cfg" break } define TCL_CONFIG_SH $cfg @@ -581,6 +580,8 @@ proc sqlite-check-tcl {} { eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] if {"" eq $with_tclsh && $cfg ne ""} { + # We have tclConfig.sh but no tclsh. Attempt to locate a tclsh + # based on info from tclConfig.sh. proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] if {![file-isexec $with_tclsh]} { @@ -594,20 +595,19 @@ proc sqlite-check-tcl {} { } define TCLSH_CMD $with_tclsh if {$use_tcl} { - # Set up the TCLLIBDIR and TCLLIB_RPATH + # Set up the TCLLIBDIR # # 2024-10-28: calculation of TCLLIBDIR is now done via the shell - # in the main.mk (search it for T.tcllibdir) so that + # in main.mk (search it for T.tcl.env.sh) so that # static/hand-written makefiles which import main.mk do not have # to define that before importing main.mk. Even so, we export - # TCLLIBDIR from here for the benefit of those who want to provide - # it at configure-time and have it "stick", without having to - # provide it on each make invocation or set it in their - # environment. + # TCLLIBDIR from here, which will cause the makefile to use this + # one rather than to re-calculate it at make-time. set tcllibdir [get-env TCLLIBDIR ""] if {"" eq $tcllibdir} { # Attempt to extract TCLLIBDIR from TCL's $auto_path - if {[catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { + if {"" ne $with_tclsh && + [catch {exec echo "puts stdout \$auto_path" | "$with_tclsh"} result] == 0} { foreach i $result { if {[file isdir $i]} { set tcllibdir $i/sqlite3 @@ -615,23 +615,13 @@ proc sqlite-check-tcl {} { } } } else { - proj-warn "Cannot determine TCLLIBDIR" + proj-warn "Cannot determine TCLLIBDIR." + # The makefile will fail fatally in this case if a target is + # invoked which requires TCLLIBDIR. } } - set tclrpath "" - if {"" ne $tcllibdir} { - set rp [get-define SH_LINKRPATH] - set tclrpath [string map [list "%s" $tcllibdir] $rp] - # Reminder: tclConfig.sh has TCL_LD_SEARCH_FLAGS to set the - # rpath but (A) it includes an unexpand var ref to - # ${LIB_RUNTIME_DIR}, which must be set in the makefile and (B) - # that flag is inherently compiler-dependent so it's not as - # portable as tclConfig.sh assumes. We'll instead use the rpath - # flag which autosetup determines for the current compiler. - } + #if {"" ne $tcllibdir} { msg-result "TCLLIBDIR = ${tcllibdir}"; } define TCLLIBDIR $tcllibdir - define TCLLIB_RPATH $tclrpath - #msg-debug "TCLLIB_RPATH = [get-define TCLLIB_RPATH]" }; # find TCLLIBDIR if {[file-isexec $with_tclsh]} { @@ -639,12 +629,23 @@ proc sqlite-check-tcl {} { if {$cfg ne ""} { define HAVE_TCL 1 } else { - proj-warn "Found tclsh but no tclConfig.sh, so cannot build TCL components." + proj-warn "Found tclsh but no tclConfig.sh." } - } else { - proj-warn "Cannot find a usable tclsh, so cannot build TCL components." } show-notices + if {![get-define HAVE_TCL] && + ([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} { + proj-fatal "TCL support was requested but no tclConfig.sh could be found." + } + if {"" eq $cfg} { + proj-assert {expr {0 == [get-define HAVE_TCL]}} + proj-indented-notice { + WARNING: Cannot find a usable tclConfig.sh file. Use + --with-tcl=DIR to specify a directory where tclConfig.sh can be + found. SQLite does not use TCL internally, but some optional + components require TCL, including tests and sqlite3_analyzer. + } + } }; # sqlite-check-tcl sqlite-check-tcl @@ -977,7 +978,7 @@ proc sqlite-check-line-editing {} { # Alert the user that, despite outward appearances, we won't be # linking to the GPL'd libreadline. Presumably that distinction is # significant for those using --editline. - proj-indented-notice { + proj-indented-notice -notice { NOTE: the local libedit but uses so we will compile with -DHAVE_READLINE=1 but will link with libedit. diff --git a/autosetup/README.md b/autosetup/README.md index 74e31be583..696569a423 100644 --- a/autosetup/README.md +++ b/autosetup/README.md @@ -78,15 +78,19 @@ In (mostly) alphabetical order: flags. They're rarely needed, though: search [auto.def][] for `TSTRNNR_OPTS` for an example of where they are used. +- **`proj-fatal msg`**\ + Emits `$msg` to stderr and exits with non-zero. + - **`proj-if-opt-truthy flag thenScript ?elseScript?`**\ Evals `thenScript` if the given `--flag` is truthy, else it evals the optional `elseScript`. -- **`proj-indented-notice ?-error? msg`**\ +- **`proj-indented-notice ?-error? ?-notice? msg`**\ Breaks its `msg` argument into lines, trims them, and emits them - with consistent indentation. If the `-error` flag is used, it then - exits with a non-0 result code. This will stick out starkly from - normal output and is intended to be used only for important notices. + with consistent indentation. Exactly how it emits depends on the + flags passed to it (or not), as covered in its docs. This will stick + out starkly from normal output and is intended to be used only for + important notices. - **`proj-opt-truthy flag`**\ Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, @@ -103,6 +107,10 @@ In (mostly) alphabetical order: Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition of "truthy." +- **`proj-warn msg`**\ + Emits `$msg` to stderr. Closely-related is autosetup's `user-notice` + (described below). + - **`sqlite-add-feature-flag ?-shell? FLAG...`**\ Adds the given feature flag to the CFLAGS which are specific to building the library. It's intended to be passed one or more `-DSQLITE_ENABLE_...`, @@ -113,6 +121,13 @@ In (mostly) alphabetical order: - **`sqlite-add-shell-opt FLAG...`**\ The shell-specific counterpart of `sqlite-add-feature-flag`. +- **`user-notice msg`**\ + Queues `$msg` to be sent to stderr, but not until either + `show-notices` is called or the next time autosetup would output + something. This can be used to generate warnings between a "checking + for..." message and its resulting "yes/no/whatever" message in such + a way as to not spoil layout of such messages. + Ensuring TCL Compatibility ======================================================================== diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index a1138a94ed..91a7ca77b1 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -61,7 +61,7 @@ set proj_(isatty) [isatty? stdout] # # Emits a warning message to stderr. proc proj-warn {msg} { - puts stderr [proj-bold "WARNING: $msg"] + puts stderr "WARNING: $msg" } ######################################################################## # @proj-error msg @@ -69,7 +69,7 @@ proc proj-warn {msg} { # Emits an error message to stderr and exits with non-0. proc proj-fatal {msg} { show-notices - puts stderr [proj-bold "ERROR: $msg"] + puts stderr "ERROR: $msg" exit 1 } @@ -101,23 +101,37 @@ proc proj-bold {str} { } ######################################################################## -# @proj-indented-notice ?-error? msg +# @proj-indented-notice ?-error? ?-notice? msg # -# Takes a multi-line message and emits it with consistent indentation -# using [user-notice] (which means its rendering will (A) go to stderr -# and (B) be delayed until the next time autosetup goes to output a -# message). +# Takes a multi-line message and emits it with consistent indentation. # -# If its first argument is -error then it renders the message -# immediately and then exits. +# If the -notice flag it used then it emits using [user-notice], which +# means its rendering will (A) go to stderr and (B) be delayed until +# the next time autosetup goes to output a message. If -notice +# is not used, it will send the message to stdout without delay. +# +# If the -error flag is provided then it renders the message +# immediately to stderr and then exits. proc proj-indented-notice {args} { set fErr "" - if {"-error" eq [lindex $args 0]} { - set args [lassign $args fErr] + set outFunc "puts" + while {[llength $args] > 1} { + switch -exact -- [lindex $args 0] { + -error { + set args [lassign $args fErr] + } + -notice { + set args [lassign $args -] + set outFunc "user-notice" + } + default { + break + } + } } set lines [split [join $args] \n] foreach line $lines { - user-notice " [string trimleft $line]" + $outFunc " [string trimleft $line]" } if {"" ne $fErr} { show-notices diff --git a/main.mk b/main.mk index 2dc7f9ce78..faf8e34c3b 100644 --- a/main.mk +++ b/main.mk @@ -1465,6 +1465,7 @@ install-tcl-1: $(libtclsqlite3.SO) pkgIndex.tcl $(INSTALL) $(libtclsqlite3.SO) "$(DESTDIR)$$TCLLIBDIR"; \ $(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$$TCLLIBDIR" install-tcl-0 install-tcl-: + @echo "TCL support disabled, so not installing $(libtclsqlite3.SO)" install-tcl: install-tcl-$(HAVE_TCL) install: install-tcl @@ -1699,7 +1700,7 @@ sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c $(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) # xbin: target for generic binaries which aren't usually built. It is # used primarily for testing the build process. -xbin: sqltclsh$(T.exe) +xbin: sqltclsh$(T.exe) sqlite3_analyzer$(T.exe) sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/expert.c sqlite3.c @@ -1910,7 +1911,7 @@ install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin) #install: install-rsync install-man1: $(install-dir.man1) - $(INSTALL.noexec) $(TOP)/sqlite3.1 "$(install-dir.man1)" + $(INSTALL.noexec) "$(TOP)/sqlite3.1" "$(install-dir.man1)" install: install-man1 # diff --git a/manifest b/manifest index d5cc26c78e..53d31b6908 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sthe\s".mode\sjson"\soutput\sin\sthe\sCLI. -D 2024-11-07T12:03:53.321 +C tcl\sconfiguration:\s--with-tcl=prefix\sis\sequivalent\sto\spassing\sthe\s--prefix\sdir\sto\sit.\sIf\s--with-tcl\sor\s--enable-tcl\sare\sexplicitly\spassed\sin\sand\stclConfig.sh\sis\snot\sfound,\sfail\sfatally.\sWhen\sTCL\sis\seither\sexplicitly\sdisabled\sor\sdefault\ssearch\sfor\sit\sfails\snon-fatally,\sbe\smore\sexplicit\sabout\swhich\scomponents\sare\snot\savailable. +D 2024-11-07T15:04:15.370 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 8d10658f2d06b0a8ddd558dfff3c111fc2b01b81d88a1bd059544abcf6e3f453 +F auto.def 994745e992211047879521fa05742b9eaedafe8f2600a7b8d784c32e6afa41fa F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,7 +37,7 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e -F autosetup/README.md 6357282be27622b8ce37b46717a5088dc2148a8f3e2ef48bbe465a333f0c70ac +F autosetup/README.md 0fd0e5f83122a5ba12896540f2804921c90165dd475323adf57369b5baad91be F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x @@ -50,7 +50,7 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl d4795a130eedb21d7f2acea0e28cf647e477b6e555817ac4497d62bbaf7b6c23 +F autosetup/proj.tcl f125ba46b08b2ae0aa4afc4c3547fdd6c9487a609e0147217e62b2e4ec5d5e0e F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 @@ -699,7 +699,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 949721d1f7400fd9f2c9a8818d66eed7b4c5937c9fd2635f8364755858ddcc78 +F main.mk beaeb83b8239bf4f9747e1dbd5316536feb9a961c689c9917cf5afb4859feafb F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2200,8 +2200,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 574515290058ddfaf39a4221fa0f7a99222c4b040dd455348550816b18492c20 -R d6d415bcc0f47f8fdfd469ff669d9a21 -U drh -Z 19d583f7d9e9d1ca3ecd4ff7c1dcf90f +P 6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 +R 159b8b906d14c083582767b8ea344e43 +U stephan +Z a561785360eeb191a2906420651521c2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5d85b4470e..80e093e1e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6201b5707f8c895028f9c08cb4f83d33a16a91bf04ed3830ac51aa763d6b7205 +c5389d39a90047683e80ae9081d5d10aaa95da00dfc8a133b4a1a6949a11620d