From ae6a38a0317c5d2c36da2f6c9ab90530d5fc4e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Tue, 15 Oct 2024 12:55:58 +0200 Subject: [PATCH 1/4] tcl: add a fallback from hardcoded TCLRL_LIBRARY path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- src/Main.cc | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/Main.cc b/src/Main.cc index cd5775f34c2..bfff9557dc0 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -333,6 +333,39 @@ static int tclReadlineInit(Tcl_Interp* interp) } #endif +namespace { +// A fallback from the hardcoded TCLRL_LIBRARY path. +std::string findPathToTclreadlineInit(Tcl_Interp* interp) +{ + std::string path(TCLRL_LIBRARY "/tclreadlineInit.tcl"); + if (is_regular_file(path.c_str())) { + return path; + } + + const char* tclScript = R"( + proc find_path {} { + foreach dir $::auto_path { + set folder [file join $dir] + set path [file join $folder "tclreadline2.3.8" "tclreadlineInit.tcl"] + if {[file exists $path]} { + return $path + } + } + error "tclreadlineInit.tcl not found in any of the directories in auto_path" + } + find_path + )"; + + if (Tcl_Eval(interp, tclScript) == TCL_ERROR) { + std::cerr << "Tcl_Eval failed: " << Tcl_GetStringResult(interp) + << std::endl; + return ""; + } + + return Tcl_GetStringResult(interp); +} +} // namespace + // Tcl init executed inside Tcl_Main. static int tclAppInit(int& argc, char* argv[], @@ -373,8 +406,9 @@ static int tclAppInit(int& argc, // script is done. Tcl_StaticPackage( interp, "tclreadline", Tclreadline_Init, Tclreadline_SafeInit); - if (Tcl_EvalFile(interp, TCLRL_LIBRARY "/tclreadlineInit.tcl") - != TCL_OK) { + + std::string path = findPathToTclreadlineInit(interp); + if (path.empty() || Tcl_EvalFile(interp, path.c_str()) != TCL_OK) { printf("Failed to load tclreadline\n"); } } From 5ff3bb2ff99c5779b11e39c2e3bc1f460ef3d9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Tue, 15 Oct 2024 14:19:19 +0200 Subject: [PATCH 2/4] tcl: clean up code to get path to tclreadline library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- src/Main.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Main.cc b/src/Main.cc index bfff9557dc0..a96181188f1 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -343,17 +343,17 @@ std::string findPathToTclreadlineInit(Tcl_Interp* interp) } const char* tclScript = R"( - proc find_path {} { - foreach dir $::auto_path { - set folder [file join $dir] - set path [file join $folder "tclreadline2.3.8" "tclreadlineInit.tcl"] - if {[file exists $path]} { - return $path - } + namespace eval temp { + foreach dir $::auto_path { + set folder [file join $dir] + set path [file join $folder "tclreadline)" TCLRL_VERSION_STR + R"(" "tclreadlineInit.tcl"] + if {[file exists $path]} { + return $path } - error "tclreadlineInit.tcl not found in any of the directories in auto_path" } - find_path + error "tclreadlineInit.tcl not found in any of the directories in auto_path" + } )"; if (Tcl_Eval(interp, tclScript) == TCL_ERROR) { From cdfabc7e098cdf168e8f760a53be4b8d4f5c49a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Tue, 15 Oct 2024 14:29:22 +0200 Subject: [PATCH 3/4] tcl: add some narrative on why we have to look up the path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- src/Main.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Main.cc b/src/Main.cc index a96181188f1..910cfff6a1c 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -342,6 +342,24 @@ std::string findPathToTclreadlineInit(Tcl_Interp* interp) return path; } + // TL;DR it is possible to run the OpenROAD binary from within the + // official Docker image on a different distribution than the + // distribution within the Docker image. + // + // In this case we have to look up + // the location of the tclreadline scripts instead of using the hardcoded + // path. + // + // It is helpful to use the official Docker image as CI infrastructure and + // also because it is a good way to have as similar an environment as possible + // during testing and deployment. + // + // See + // https://github.com/The-OpenROAD-Project/bazel-orfs/blob/main/docker.BUILD.bazel + // for the details on how this is done. + // + // Running Docker within a bazel isolated environment introduces lots of + // problems and is not really done. const char* tclScript = R"( namespace eval temp { foreach dir $::auto_path { From 1858ebdc54cc2695b1b2b342b4890d5d5586895f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Harboe?= Date: Tue, 15 Oct 2024 19:23:08 +0200 Subject: [PATCH 4/4] tclinit: fallback case only is changed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Øyvind Harboe --- src/Main.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Main.cc b/src/Main.cc index 910cfff6a1c..522a9f6fcad 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -334,14 +334,10 @@ static int tclReadlineInit(Tcl_Interp* interp) #endif namespace { -// A fallback from the hardcoded TCLRL_LIBRARY path. +// A stopgap fallback from the hardcoded TCLRL_LIBRARY path for OpenROAD, +// not essential for OpenSTA std::string findPathToTclreadlineInit(Tcl_Interp* interp) { - std::string path(TCLRL_LIBRARY "/tclreadlineInit.tcl"); - if (is_regular_file(path.c_str())) { - return path; - } - // TL;DR it is possible to run the OpenROAD binary from within the // official Docker image on a different distribution than the // distribution within the Docker image. @@ -425,9 +421,12 @@ static int tclAppInit(int& argc, Tcl_StaticPackage( interp, "tclreadline", Tclreadline_Init, Tclreadline_SafeInit); - std::string path = findPathToTclreadlineInit(interp); - if (path.empty() || Tcl_EvalFile(interp, path.c_str()) != TCL_OK) { - printf("Failed to load tclreadline\n"); + if (Tcl_EvalFile(interp, TCLRL_LIBRARY "/tclreadlineInit.tcl") + != TCL_OK) { + std::string path = findPathToTclreadlineInit(interp); + if (path.empty() || Tcl_EvalFile(interp, path.c_str()) != TCL_OK) { + printf("Failed to load tclreadline\n"); + } } } #endif