Branch data Line data Source code
1 : : #include "cache_hash.hpp"
2 : : #include "os.hpp"
3 : :
4 : : #include <stdio.h>
5 : :
6 : : static Buf saved_compiler_id = BUF_INIT;
7 : : static Buf saved_app_data_dir = BUF_INIT;
8 : : static Buf saved_stage1_path = BUF_INIT;
9 : : static Buf saved_lib_dir = BUF_INIT;
10 : : static Buf saved_special_dir = BUF_INIT;
11 : : static Buf saved_std_dir = BUF_INIT;
12 : :
13 : : static Buf saved_dynamic_linker_path = BUF_INIT;
14 : : static bool searched_for_dyn_linker = false;
15 : :
16 : : static Buf saved_libc_path = BUF_INIT;
17 : : static bool searched_for_libc = false;
18 : :
19 : 104 : Buf *get_stage1_cache_path(void) {
20 [ + + ]: 104 : if (saved_stage1_path.list.length != 0) {
21 : 86 : return &saved_stage1_path;
22 : : }
23 : : Error err;
24 [ - + ]: 18 : if ((err = os_get_app_data_dir(&saved_app_data_dir, "zig"))) {
25 : 0 : fprintf(stderr, "Unable to get app data dir: %s\n", err_str(err));
26 : 0 : exit(1);
27 : : }
28 : 18 : os_path_join(&saved_app_data_dir, buf_create_from_str("stage1"), &saved_stage1_path);
29 : 18 : return &saved_stage1_path;
30 : : }
31 : :
32 : 40 : static void detect_dynamic_linker(Buf *lib_path) {
33 : : #if defined(ZIG_OS_LINUX)
34 [ + + ]: 110 : for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
35 [ + + ]: 75 : if (buf_ends_with_str(lib_path, possible_ld_names[i])) {
36 : 5 : buf_init_from_buf(&saved_dynamic_linker_path, lib_path);
37 : 5 : break;
38 : : }
39 : : }
40 : : #endif
41 : 40 : }
42 : :
43 : 26 : const Buf *get_self_libc_path(void) {
44 : : for (;;) {
45 [ + + ]: 26 : if (saved_libc_path.list.length != 0) {
46 : 26 : return &saved_libc_path;
47 : : }
48 [ - + ]: 18 : if (searched_for_libc)
49 : 0 : return nullptr;
50 : 18 : ZigList<Buf *> lib_paths = {};
51 : : Error err;
52 [ - + ]: 18 : if ((err = os_self_exe_shared_libs(lib_paths)))
53 : 0 : return nullptr;
54 [ + - ]: 126 : for (size_t i = 0; i < lib_paths.length; i += 1) {
55 : 126 : Buf *lib_path = lib_paths.at(i);
56 [ + + ]: 126 : if (buf_ends_with_str(lib_path, "libc.so.6")) {
57 : 18 : buf_init_from_buf(&saved_libc_path, lib_path);
58 : 18 : return &saved_libc_path;
59 : : }
60 : : }
61 : 0 : searched_for_libc = true;
62 : 0 : }
63 : : }
64 : :
65 : 4 : Buf *get_self_dynamic_linker_path(void) {
66 : : for (;;) {
67 [ + + ]: 8 : if (saved_dynamic_linker_path.list.length != 0) {
68 : 4 : return &saved_dynamic_linker_path;
69 : : }
70 [ - + ]: 4 : if (searched_for_dyn_linker)
71 : 0 : return nullptr;
72 : 4 : ZigList<Buf *> lib_paths = {};
73 : : Error err;
74 [ - + ]: 4 : if ((err = os_self_exe_shared_libs(lib_paths)))
75 : 0 : return nullptr;
76 [ + + ]: 36 : for (size_t i = 0; i < lib_paths.length; i += 1) {
77 : 32 : Buf *lib_path = lib_paths.at(i);
78 : 32 : detect_dynamic_linker(lib_path);
79 : : }
80 : 4 : searched_for_dyn_linker = true;
81 : 4 : }
82 : : }
83 : :
84 : 153 : Error get_compiler_id(Buf **result) {
85 [ + + ]: 153 : if (saved_compiler_id.list.length != 0) {
86 : 135 : *result = &saved_compiler_id;
87 : 135 : return ErrorNone;
88 : : }
89 : :
90 : : Error err;
91 : 18 : Buf *stage1_dir = get_stage1_cache_path();
92 : 18 : Buf *manifest_dir = buf_alloc();
93 : 18 : os_path_join(stage1_dir, buf_create_from_str("exe"), manifest_dir);
94 : :
95 : : CacheHash cache_hash;
96 : 18 : CacheHash *ch = &cache_hash;
97 : 18 : cache_init(ch, manifest_dir);
98 : 18 : Buf self_exe_path = BUF_INIT;
99 [ - + ]: 18 : if ((err = os_self_exe_path(&self_exe_path)))
100 : 0 : return err;
101 : :
102 : 18 : cache_file(ch, &self_exe_path);
103 : :
104 : 18 : buf_resize(&saved_compiler_id, 0);
105 [ - + ]: 18 : if ((err = cache_hit(ch, &saved_compiler_id))) {
106 [ # # ]: 0 : if (err != ErrorInvalidFormat)
107 : 0 : return err;
108 : : }
109 [ + + ]: 18 : if (buf_len(&saved_compiler_id) != 0) {
110 : 17 : cache_release(ch);
111 : 17 : *result = &saved_compiler_id;
112 : 17 : return ErrorNone;
113 : : }
114 : 1 : ZigList<Buf *> lib_paths = {};
115 [ - + ]: 1 : if ((err = os_self_exe_shared_libs(lib_paths)))
116 : 0 : return err;
117 [ + + ]: 9 : for (size_t i = 0; i < lib_paths.length; i += 1) {
118 : 8 : Buf *lib_path = lib_paths.at(i);
119 : 8 : detect_dynamic_linker(lib_path);
120 [ - + ]: 8 : if ((err = cache_add_file(ch, lib_path)))
121 : 0 : return err;
122 : : }
123 [ - + ]: 1 : if ((err = cache_final(ch, &saved_compiler_id)))
124 : 0 : return err;
125 : :
126 : 1 : cache_release(ch);
127 : :
128 : 1 : *result = &saved_compiler_id;
129 : 153 : return ErrorNone;
130 : : }
131 : :
132 : 18 : static bool test_zig_install_prefix(Buf *test_path, Buf *out_zig_lib_dir) {
133 : 18 : Buf lib_buf = BUF_INIT;
134 : 18 : buf_init_from_str(&lib_buf, "lib");
135 : :
136 : 18 : Buf zig_buf = BUF_INIT;
137 : 18 : buf_init_from_str(&zig_buf, "zig");
138 : :
139 : 18 : Buf std_buf = BUF_INIT;
140 : 18 : buf_init_from_str(&std_buf, "std");
141 : :
142 : 18 : Buf std_zig_buf = BUF_INIT;
143 : 18 : buf_init_from_str(&std_zig_buf, "std.zig");
144 : :
145 : 18 : Buf test_lib_dir = BUF_INIT;
146 : 18 : Buf test_zig_dir = BUF_INIT;
147 : 18 : Buf test_std_dir = BUF_INIT;
148 : 18 : Buf test_index_file = BUF_INIT;
149 : :
150 : 18 : os_path_join(test_path, &lib_buf, &test_lib_dir);
151 : 18 : os_path_join(&test_lib_dir, &zig_buf, &test_zig_dir);
152 : 18 : os_path_join(&test_zig_dir, &std_buf, &test_std_dir);
153 : 18 : os_path_join(&test_std_dir, &std_zig_buf, &test_index_file);
154 : :
155 : : int err;
156 : : bool exists;
157 [ - + ]: 18 : if ((err = os_file_exists(&test_index_file, &exists))) {
158 : 0 : exists = false;
159 : : }
160 [ + - ]: 18 : if (exists) {
161 : 18 : buf_init_from_buf(out_zig_lib_dir, &test_zig_dir);
162 : 18 : return true;
163 : : }
164 : 18 : return false;
165 : : }
166 : :
167 : 18 : static int find_zig_lib_dir(Buf *out_path) {
168 : : int err;
169 : :
170 : 18 : Buf self_exe_path = BUF_INIT;
171 : 18 : buf_resize(&self_exe_path, 0);
172 [ + - ]: 18 : if (!(err = os_self_exe_path(&self_exe_path))) {
173 : 18 : Buf *cur_path = &self_exe_path;
174 : :
175 : : for (;;) {
176 : 18 : Buf *test_dir = buf_alloc();
177 : 18 : os_path_dirname(cur_path, test_dir);
178 : :
179 [ - + ]: 18 : if (buf_eql_buf(test_dir, cur_path)) {
180 : 0 : break;
181 : : }
182 : :
183 [ + - ]: 18 : if (test_zig_install_prefix(test_dir, out_path)) {
184 : 18 : return 0;
185 : : }
186 : :
187 : 0 : cur_path = test_dir;
188 : 0 : }
189 : : }
190 : :
191 : 18 : return ErrorFileNotFound;
192 : : }
193 : :
194 : 20 : Buf *get_zig_lib_dir(void) {
195 [ + + ]: 20 : if (saved_lib_dir.list.length != 0) {
196 : 2 : return &saved_lib_dir;
197 : : }
198 : 18 : buf_resize(&saved_lib_dir, 0);
199 : :
200 : : int err;
201 [ - + ]: 18 : if ((err = find_zig_lib_dir(&saved_lib_dir))) {
202 : 0 : fprintf(stderr, "Unable to find zig lib directory\n");
203 : 0 : exit(EXIT_FAILURE);
204 : : }
205 : 18 : return &saved_lib_dir;
206 : : }
207 : :
208 : 2 : Buf *get_zig_std_dir(Buf *zig_lib_dir) {
209 [ - + ]: 2 : if (saved_std_dir.list.length != 0) {
210 : 0 : return &saved_std_dir;
211 : : }
212 : 2 : buf_resize(&saved_std_dir, 0);
213 : :
214 : 2 : os_path_join(zig_lib_dir, buf_create_from_str("std"), &saved_std_dir);
215 : :
216 : 2 : return &saved_std_dir;
217 : : }
218 : :
219 : 2 : Buf *get_zig_special_dir(Buf *zig_lib_dir) {
220 [ - + ]: 2 : if (saved_special_dir.list.length != 0) {
221 : 0 : return &saved_special_dir;
222 : : }
223 : 2 : buf_resize(&saved_special_dir, 0);
224 : :
225 : 2 : os_path_join(get_zig_std_dir(zig_lib_dir), buf_sprintf("special"), &saved_special_dir);
226 : :
227 : 2 : return &saved_special_dir;
228 : : }
|