|
18 | 18 |
|
19 | 19 | #include "boost/stacktrace/stacktrace.hpp" |
20 | 20 | #include "tcl.h" |
21 | | -#ifdef ENABLE_READLINE |
22 | | -// If you get an error on this include be sure you have |
23 | | -// the package tcl-tclreadline-devel installed |
24 | | -#include "tclreadline.h" |
25 | | -#endif |
26 | 21 | #ifdef ENABLE_PYTHON3 |
27 | 22 | #define PY_SSIZE_T_CLEAN |
28 | 23 | #include "Python.h" |
|
47 | 42 | #include "bazel/tcl_library_init.h" |
48 | 43 | #endif |
49 | 44 |
|
| 45 | +#include "tcl_readline_setup.h" |
| 46 | + |
50 | 47 | using sta::findCmdLineFlag; |
51 | 48 | using sta::findCmdLineKey; |
52 | 49 | using sta::sourceTclFile; |
@@ -317,90 +314,7 @@ int main(int argc, char* argv[]) |
317 | 314 | } |
318 | 315 |
|
319 | 316 | #ifdef ENABLE_READLINE |
320 | | -// A stopgap fallback from the hardcoded TCLRL_LIBRARY path for OpenROAD, |
321 | | -// not essential for OpenSTA |
322 | | -static std::string findPathToTclreadlineInit(Tcl_Interp* interp) |
323 | | -{ |
324 | | - // TL;DR it is possible to run the OpenROAD binary from within the |
325 | | - // official Docker image on a different distribution than the |
326 | | - // distribution within the Docker image. |
327 | | - // |
328 | | - // In this case we have to look up |
329 | | - // the location of the tclreadline scripts instead of using the hardcoded |
330 | | - // path. |
331 | | - // |
332 | | - // It is helpful to use the official Docker image as CI infrastructure and |
333 | | - // also because it is a good way to have as similar an environment as possible |
334 | | - // during testing and deployment. |
335 | | - // |
336 | | - // See |
337 | | - // https://github.com/The-OpenROAD-Project/bazel-orfs/blob/main/docker.BUILD.bazel |
338 | | - // for the details on how this is done. |
339 | | - // |
340 | | - // Running Docker within a bazel isolated environment introduces lots of |
341 | | - // problems and is not really done. |
342 | | - const char* tcl_script = R"( |
343 | | - namespace eval temp { |
344 | | - # Check standard Bazel runfiles relative path |
345 | | - set runfiles_path [file join [pwd] "external/tclreadline/tclreadlineInit.tcl"] |
346 | | - if {[file exists $runfiles_path]} { |
347 | | - return $runfiles_path |
348 | | - } |
349 | | -
|
350 | | - # Check Bazel runfiles in adjacent directories for other run strategies |
351 | | - set runfiles_execroot_path [file join [pwd] "../tclreadline/tclreadlineInit.tcl"] |
352 | | - if {[file exists $runfiles_execroot_path]} { |
353 | | - return $runfiles_execroot_path |
354 | | - } |
355 | | -
|
356 | | - foreach dir $::auto_path { |
357 | | - set folder [file join $dir] |
358 | | - set path [file join $folder "tclreadline)" TCLRL_VERSION_STR |
359 | | - R"(" "tclreadlineInit.tcl"] |
360 | | - if {[file exists $path]} { |
361 | | - return $path |
362 | | - } |
363 | | - } |
364 | | - error "tclreadlineInit.tcl not found in any of the directories in auto_path" |
365 | | - } |
366 | | - )"; |
367 | | - |
368 | | - if (Tcl_Eval(interp, tcl_script) == TCL_ERROR) { |
369 | | - std::cerr << "Tcl_Eval failed: " << Tcl_GetStringResult(interp) << '\n'; |
370 | | - return ""; |
371 | | - } |
372 | | - |
373 | | - return Tcl_GetStringResult(interp); |
374 | | -} |
375 | | - |
376 | | -static bool TryReadlineStaticInit(Tcl_Interp* interp) |
377 | | -{ |
378 | | - Tcl_StaticPackage( |
379 | | - interp, "tclreadline", Tclreadline_Init, Tclreadline_SafeInit); |
380 | | - |
381 | | - return Tcl_EvalFile(interp, TCLRL_LIBRARY "/tclreadlineInit.tcl") == TCL_OK; |
382 | | -} |
383 | | - |
384 | | -static bool TryTclBazelInit(Tcl_Interp* interp) |
385 | | -{ |
386 | | - // Here, ::tclreadline::library is already set up by SetupTclEnvironment |
387 | | - constexpr char kInitializeReadlineLib[] = R"( |
388 | | - set ::tclreadline::setup_path [file join $::tclreadline::library "tclreadlineSetup.tcl"] |
389 | | - set ::tclreadline::completer_path [file join $::tclreadline::library "tclreadlineCompleter.tcl"] |
390 | | - if {[info commands history] == ""} { proc history {args} {} }; |
391 | | - source [file join $::tclreadline::library "tclreadlineInit.tcl"] |
392 | | -)"; |
393 | | - |
394 | | - return Tcl_Eval(interp, kInitializeReadlineLib) == TCL_OK; |
395 | | -} |
396 | | - |
397 | | -static bool TrySearchPathManuallyInit(Tcl_Interp* interp) |
398 | | -{ |
399 | | - const std::string path = findPathToTclreadlineInit(interp); |
400 | | - return !path.empty() && Tcl_EvalFile(interp, path.c_str()) == TCL_OK; |
401 | | -} |
402 | | - |
403 | | -static int tclReadlineInit(Tcl_Interp* interp) |
| 317 | +static int tclOrdReadlineInit(Tcl_Interp* interp) |
404 | 318 | { |
405 | 319 | std::array<const char*, 2> readline_cmds |
406 | 320 | = {"ord::setup_tclreadline", "::tclreadline::Loop"}; |
@@ -452,19 +366,11 @@ static int tclAppInit(int& argc, |
452 | 366 | } |
453 | 367 | #endif |
454 | 368 |
|
455 | | -#ifdef ENABLE_READLINE |
456 | 369 | if (!exit_after_cmd_file) { |
457 | | - if (Tclreadline_Init(interp) == TCL_ERROR) { |
458 | | - return TCL_ERROR; |
459 | | - } |
460 | | - |
461 | | - if (!TryReadlineStaticInit(interp) && // |
462 | | - !TryTclBazelInit(interp) && // |
463 | | - !TrySearchPathManuallyInit(interp)) { |
| 370 | + if (ord::SetupTclReadlineLibrary(interp) == TCL_ERROR) { |
464 | 371 | printf("Failed to load tclreadline\n"); |
465 | 372 | } |
466 | 373 | } |
467 | | -#endif |
468 | 374 |
|
469 | 375 | ord::initOpenRoad( |
470 | 376 | interp, log_filename, metrics_filename, exit_after_cmd_file); |
@@ -545,7 +451,7 @@ static int tclAppInit(int& argc, |
545 | 451 | } |
546 | 452 | #ifdef ENABLE_READLINE |
547 | 453 | if (!gui::Gui::enabled() && !exit_after_cmd_file) { |
548 | | - return tclReadlineInit(interp); |
| 454 | + return tclOrdReadlineInit(interp); |
549 | 455 | } |
550 | 456 | #endif |
551 | 457 | return TCL_OK; |
|
0 commit comments