|
3 | 3 |
|
4 | 4 | #include "bazel/tcl_library_init.h" |
5 | 5 |
|
6 | | -#include <cstdlib> |
7 | | -#include <filesystem> |
8 | 6 | #include <iostream> |
9 | 7 | #include <optional> |
10 | 8 | #include <string> |
11 | | -#include <system_error> |
12 | 9 |
|
13 | | -#include "tcl.h" |
14 | | - |
15 | | -// In tcl 9, we can use the //zipfs:/ virtual file system (unless |
16 | | -// we specifically disabled with the --//bazel:use_zipfs=False flag) |
17 | | -#if TCL_MAJOR_VERSION >= 9 && !defined(USE_TCL_RUNFILE_INIT) |
18 | | -#define USE_ZIPFS_INIT 1 |
19 | | -#else |
20 | | -#define USE_ZIPFS_INIT 0 |
21 | | -#endif |
22 | | - |
23 | | -#if USE_ZIPFS_INIT |
24 | 10 | #include "bazel/tcl_resources_zip_data.h" |
25 | | -#else |
26 | | - |
27 | | -#include <limits.h> |
28 | | -#include <unistd.h> |
29 | | - |
30 | | -#if defined(__APPLE__) |
31 | | -#include <mach-o/dyld.h> |
32 | | -#include <sys/param.h> |
33 | | -#endif |
34 | | - |
35 | | -#include <memory> |
36 | | - |
37 | | -#include "rules_cc/cc/runfiles/runfiles.h" |
38 | | -#endif |
| 11 | +#include "tcl.h" |
39 | 12 |
|
40 | 13 | namespace in_bazel { |
41 | 14 |
|
42 | | -#if !USE_ZIPFS_INIT |
43 | | -// Avoid adding any dependencies like boost.filesystem |
44 | | -// Returns path to running binary if possible. |
45 | | -static std::string GetProgramLocation() |
46 | | -{ |
47 | | -#if defined(_WIN32) |
48 | | - char result[MAX_PATH + 1] = {'\0'}; |
49 | | - auto path_len = GetModuleFileNameA(NULL, result, MAX_PATH); |
50 | | -#elif defined(__APPLE__) |
51 | | - char result[MAXPATHLEN + 1] = {'\0'}; |
52 | | - uint32_t path_len = MAXPATHLEN; |
53 | | - if (_NSGetExecutablePath(result, &path_len) != 0) { |
54 | | - path_len = readlink(result, result, MAXPATHLEN); |
55 | | - } |
56 | | -#else |
57 | | - char result[PATH_MAX + 1] = {'\0'}; |
58 | | - ssize_t path_len = readlink("/proc/self/exe", result, PATH_MAX); |
59 | | -#endif |
60 | | - if (path_len > 0) { |
61 | | - return result; |
62 | | - } |
63 | | - return Tcl_GetNameOfExecutable(); |
64 | | -} |
65 | | -#endif |
66 | | - |
67 | 15 | static std::optional<std::string> TclLibraryMountPoint(Tcl_Interp* interp) |
68 | 16 | { |
69 | 17 | // In tcl9, we can use //zipfs:/ otherwise we need to point to the |
70 | 18 | // directory where the tcl library files are extracted. |
71 | | -#if USE_ZIPFS_INIT |
72 | 19 | if (TclZipfs_MountBuffer( |
73 | 20 | interp, kTclResourceZip, sizeof(kTclResourceZip), "/app", 0) |
74 | 21 | != TCL_OK) { |
75 | 22 | std::cerr << "[Warning] Failed to mount Tcl zipfs.\n"; |
76 | 23 | return std::nullopt; |
77 | 24 | } |
78 | 25 | return Tcl_GetStringResult(interp); |
79 | | -#else |
80 | | - using rules_cc::cc::runfiles::Runfiles; |
81 | | - |
82 | | - auto find_tcl_resources |
83 | | - = [](const Runfiles* runfiles) -> std::optional<std::string> { |
84 | | - std::error_code ec; |
85 | | - for (const std::string loc : {"openroad", "opensta", "_main"}) { |
86 | | - const std::string check_loc = loc + "/bazel/tcl_resources_dir"; |
87 | | - const std::string path = runfiles->Rlocation(check_loc); |
88 | | - if (!path.empty() && std::filesystem::exists(path, ec)) { |
89 | | - return path; |
90 | | - } |
91 | | - } |
92 | | - return std::nullopt; |
93 | | - }; |
94 | | - |
95 | | - // First try with the inherited RUNFILES_* env vars. When OpenROAD |
96 | | - // is the direct Bazel target (or invoked from an sh_test whose |
97 | | - // runfiles tree also contains OpenROAD's data), those env vars |
98 | | - // already point at the correct tree. |
99 | | - std::string error; |
100 | | - std::unique_ptr<Runfiles> runfiles( |
101 | | - Runfiles::Create(GetProgramLocation(), BAZEL_CURRENT_REPOSITORY, &error)); |
102 | | - if (runfiles) { |
103 | | - if (auto path = find_tcl_resources(runfiles.get())) { |
104 | | - return path; |
105 | | - } |
106 | | - } |
107 | | - |
108 | | - // Fallback: when OpenROAD is invoked by a build system that |
109 | | - // previously ran another Bazel binary (e.g. a Python wrapper), the |
110 | | - // inherited RUNFILES_* variables point to the *other* binary's |
111 | | - // runfiles tree and won't contain OpenROAD's tcl_resources_dir. |
112 | | - // Unset them and retry so Runfiles::Create falls back to the |
113 | | - // exe_path derived from /proc/self/exe. |
114 | | - unsetenv("RUNFILES_DIR"); |
115 | | - unsetenv("RUNFILES_MANIFEST_FILE"); |
116 | | - unsetenv("RUNFILES_MANIFEST_ONLY"); |
117 | | - |
118 | | - runfiles.reset( |
119 | | - Runfiles::Create(GetProgramLocation(), BAZEL_CURRENT_REPOSITORY, &error)); |
120 | | - if (!runfiles) { |
121 | | - std::cerr << "[Warning] Failed to create bazel runfiles: " << error << "\n"; |
122 | | - return std::nullopt; |
123 | | - } |
124 | | - |
125 | | - if (auto path = find_tcl_resources(runfiles.get())) { |
126 | | - return path; |
127 | | - } |
128 | | - return std::nullopt; |
129 | | -#endif |
130 | 26 | } |
131 | 27 |
|
132 | 28 | int SetupTclEnvironment(Tcl_Interp* interp) |
|
0 commit comments