| ... | ... | @@ -20,8 +20,10 @@ pub const LibCInstallation = struct { |
| 20 | 20 | CCompilerExitCode, |
| 21 | 21 | CCompilerCrashed, |
| 22 | 22 | CCompilerCannotFindHeaders, |
| 23 | | CCompilerCannotFindCRuntime, |
| 23 | LibCRuntimeNotFound, |
| 24 | 24 | LibCStdLibHeaderNotFound, |
| 25 | LibCKernel32LibNotFound, |
| 26 | UnsupportedArchitecture, |
| 25 | 27 | }; |
| 26 | 28 | |
| 27 | 29 | pub fn parse( |
| ... | ... | @@ -111,7 +113,7 @@ pub const LibCInstallation = struct { |
| 111 | 113 | \\lib_dir={} |
| 112 | 114 | \\ |
| 113 | 115 | \\# The directory that contains `crtbegin.o`. |
| 114 | | \\# On Linux, can be found with `cc -print-file-name=crt1.o`. |
| 116 | \\# On Linux, can be found with `cc -print-file-name=crtbegin.o`. |
| 115 | 117 | \\# Not needed when targeting MacOS or Windows. |
| 116 | 118 | \\static_lib_dir={} |
| 117 | 119 | \\ |
| ... | ... | @@ -142,21 +144,22 @@ pub const LibCInstallation = struct { |
| 142 | 144 | self.initEmpty(); |
| 143 | 145 | var group = event.Group(FindError!void).init(loop); |
| 144 | 146 | errdefer group.cancelAll(); |
| 147 | var windows_sdk: ?*c.ZigWindowsSDK = null; |
| 148 | errdefer if (windows_sdk) |sdk| c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk)); |
| 149 | |
| 145 | 150 | switch (builtin.os) { |
| 146 | 151 | builtin.Os.windows => { |
| 147 | 152 | var sdk: *c.ZigWindowsSDK = undefined; |
| 148 | 153 | switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) { |
| 149 | 154 | c.ZigFindWindowsSdkError.None => { |
| 150 | | defer c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk)); |
| 155 | windows_sdk = sdk; |
| 151 | 156 | |
| 152 | | errdefer if (self.msvc_lib_dir) |s| loop.allocator.free(s); |
| 153 | 157 | if (sdk.msvc_lib_dir_ptr) |ptr| { |
| 154 | 158 | self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, ptr[0..sdk.msvc_lib_dir_len]); |
| 155 | 159 | } |
| 156 | | //try group.call(findNativeIncludeDirWindows, self, loop); |
| 157 | | //try group.call(findNativeLibDirWindows, self, loop); |
| 158 | | //try group.call(findNativeMsvcLibDir, self, loop); |
| 159 | | //try group.call(findNativeKernel32LibDir, self, loop); |
| 160 | try group.call(findNativeKernel32LibDir, self, loop, sdk); |
| 161 | try group.call(findNativeIncludeDirWindows, self, loop, sdk); |
| 162 | try group.call(findNativeLibDirWindows, self, loop, sdk); |
| 160 | 163 | }, |
| 161 | 164 | c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory, |
| 162 | 165 | c.ZigFindWindowsSdkError.NotFound => return error.NotFound, |
| ... | ... | @@ -230,61 +233,64 @@ pub const LibCInstallation = struct { |
| 230 | 233 | const stdlib_path = try std.os.path.join(loop.allocator, search_path, "stdlib.h"); |
| 231 | 234 | defer loop.allocator.free(stdlib_path); |
| 232 | 235 | |
| 233 | | if (std.os.File.access(loop.allocator, stdlib_path)) |_| { |
| 236 | if (try fileExists(loop.allocator, stdlib_path)) { |
| 234 | 237 | self.include_dir = try std.mem.dupe(loop.allocator, u8, search_path); |
| 235 | 238 | return; |
| 236 | | } else |err| switch (err) { |
| 237 | | error.NotFound, error.PermissionDenied => continue, |
| 238 | | error.OutOfMemory => return error.OutOfMemory, |
| 239 | | else => return error.FileSystem, |
| 240 | 239 | } |
| 241 | 240 | } |
| 242 | 241 | |
| 243 | 242 | return error.LibCStdLibHeaderNotFound; |
| 244 | 243 | } |
| 245 | 244 | |
| 246 | | async fn findNativeIncludeDirWindows(self: *LibCInstallation, loop: *event.Loop) !void { |
| 247 | | // TODO |
| 248 | | //ZigWindowsSDK *sdk = get_windows_sdk(g); |
| 249 | | //g->libc_include_dir = buf_alloc(); |
| 250 | | //if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { |
| 251 | | // fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); |
| 252 | | // exit(1); |
| 253 | | //} |
| 254 | | @panic("TODO"); |
| 245 | async fn findNativeIncludeDirWindows(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) !void { |
| 246 | var search_buf: [2]Search = undefined; |
| 247 | const searches = fillSearch(&search_buf, sdk); |
| 248 | |
| 249 | var result_buf = try std.Buffer.initSize(loop.allocator, 0); |
| 250 | defer result_buf.deinit(); |
| 251 | |
| 252 | for (searches) |search| { |
| 253 | result_buf.shrink(0); |
| 254 | const stream = &std.io.BufferOutStream.init(&result_buf).stream; |
| 255 | try stream.print("{}\\Include\\{}\\ucrt", search.path, search.version); |
| 256 | |
| 257 | const stdlib_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "stdlib.h"); |
| 258 | defer loop.allocator.free(stdlib_path); |
| 259 | |
| 260 | if (try fileExists(loop.allocator, stdlib_path)) { |
| 261 | self.include_dir = result_buf.toOwnedSlice(); |
| 262 | return; |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | return error.LibCStdLibHeaderNotFound; |
| 255 | 267 | } |
| 256 | 268 | |
| 257 | | async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop) FindError!void { |
| 258 | | // TODO |
| 259 | | //ZigWindowsSDK *sdk = get_windows_sdk(g); |
| 260 | | |
| 261 | | //if (g->msvc_lib_dir == nullptr) { |
| 262 | | // Buf* vc_lib_dir = buf_alloc(); |
| 263 | | // if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) { |
| 264 | | // fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir"); |
| 265 | | // exit(1); |
| 266 | | // } |
| 267 | | // g->msvc_lib_dir = vc_lib_dir; |
| 268 | | //} |
| 269 | | |
| 270 | | //if (g->libc_lib_dir == nullptr) { |
| 271 | | // Buf* ucrt_lib_path = buf_alloc(); |
| 272 | | // if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) { |
| 273 | | // fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir"); |
| 274 | | // exit(1); |
| 275 | | // } |
| 276 | | // g->libc_lib_dir = ucrt_lib_path; |
| 277 | | //} |
| 278 | | |
| 279 | | //if (g->kernel32_lib_dir == nullptr) { |
| 280 | | // Buf* kern_lib_path = buf_alloc(); |
| 281 | | // if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) { |
| 282 | | // fprintf(stderr, "Unable to determine kernel32 path. --kernel32-lib-dir"); |
| 283 | | // exit(1); |
| 284 | | // } |
| 285 | | // g->kernel32_lib_dir = kern_lib_path; |
| 286 | | //} |
| 287 | | @panic("TODO"); |
| 269 | async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) FindError!void { |
| 270 | var search_buf: [2]Search = undefined; |
| 271 | const searches = fillSearch(&search_buf, sdk); |
| 272 | |
| 273 | var result_buf = try std.Buffer.initSize(loop.allocator, 0); |
| 274 | defer result_buf.deinit(); |
| 275 | |
| 276 | for (searches) |search| { |
| 277 | result_buf.shrink(0); |
| 278 | const stream = &std.io.BufferOutStream.init(&result_buf).stream; |
| 279 | try stream.print("{}\\Lib\\{}\\ucrt\\", search.path, search.version); |
| 280 | switch (builtin.arch) { |
| 281 | builtin.Arch.i386 => try stream.write("x86"), |
| 282 | builtin.Arch.x86_64 => try stream.write("x64"), |
| 283 | builtin.Arch.aarch64 => try stream.write("arm"), |
| 284 | else => return error.UnsupportedArchitecture, |
| 285 | } |
| 286 | const ucrt_lib_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "ucrt.lib"); |
| 287 | defer loop.allocator.free(ucrt_lib_path); |
| 288 | if (try fileExists(loop.allocator, ucrt_lib_path)) { |
| 289 | self.lib_dir = result_buf.toOwnedSlice(); |
| 290 | return; |
| 291 | } |
| 292 | } |
| 293 | return error.LibCRuntimeNotFound; |
| 288 | 294 | } |
| 289 | 295 | |
| 290 | 296 | async fn findNativeLibDirLinux(self: *LibCInstallation, loop: *event.Loop) FindError!void { |
| ... | ... | @@ -330,17 +336,37 @@ pub const LibCInstallation = struct { |
| 330 | 336 | dyn_test.result = result; |
| 331 | 337 | return; |
| 332 | 338 | } else |err| switch (err) { |
| 333 | | error.CCompilerCannotFindCRuntime => return, |
| 339 | error.LibCRuntimeNotFound => return, |
| 334 | 340 | else => return err, |
| 335 | 341 | } |
| 336 | 342 | } |
| 337 | 343 | |
| 338 | | async fn findNativeMsvcLibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void { |
| 339 | | @panic("TODO"); |
| 340 | | } |
| 341 | 344 | |
| 342 | | async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void { |
| 343 | | @panic("TODO"); |
| 345 | async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) FindError!void { |
| 346 | var search_buf: [2]Search = undefined; |
| 347 | const searches = fillSearch(&search_buf, sdk); |
| 348 | |
| 349 | var result_buf = try std.Buffer.initSize(loop.allocator, 0); |
| 350 | defer result_buf.deinit(); |
| 351 | |
| 352 | for (searches) |search| { |
| 353 | result_buf.shrink(0); |
| 354 | const stream = &std.io.BufferOutStream.init(&result_buf).stream; |
| 355 | try stream.print("{}\\Lib\\{}\\um\\", search.path, search.version); |
| 356 | switch (builtin.arch) { |
| 357 | builtin.Arch.i386 => try stream.write("x86\\"), |
| 358 | builtin.Arch.x86_64 => try stream.write("x64\\"), |
| 359 | builtin.Arch.aarch64 => try stream.write("arm\\"), |
| 360 | else => return error.UnsupportedArchitecture, |
| 361 | } |
| 362 | const kernel32_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "kernel32.lib"); |
| 363 | defer loop.allocator.free(kernel32_path); |
| 364 | if (try fileExists(loop.allocator, kernel32_path)) { |
| 365 | self.kernel32_lib_dir = result_buf.toOwnedSlice(); |
| 366 | return; |
| 367 | } |
| 368 | } |
| 369 | return error.LibCKernel32LibNotFound; |
| 344 | 370 | } |
| 345 | 371 | |
| 346 | 372 | fn initEmpty(self: *LibCInstallation) void { |
| ... | ... | @@ -386,8 +412,8 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo |
| 386 | 412 | }, |
| 387 | 413 | } |
| 388 | 414 | var it = std.mem.split(exec_result.stdout, "\n\r"); |
| 389 | | const line = it.next() orelse return error.CCompilerCannotFindCRuntime; |
| 390 | | const dirname = std.os.path.dirname(line) orelse return error.CCompilerCannotFindCRuntime; |
| 415 | const line = it.next() orelse return error.LibCRuntimeNotFound; |
| 416 | const dirname = std.os.path.dirname(line) orelse return error.LibCRuntimeNotFound; |
| 391 | 417 | |
| 392 | 418 | if (want_dirname) { |
| 393 | 419 | return std.mem.dupe(loop.allocator, u8, dirname); |
| ... | ... | @@ -395,3 +421,42 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo |
| 395 | 421 | return std.mem.dupe(loop.allocator, u8, line); |
| 396 | 422 | } |
| 397 | 423 | } |
| 424 | |
| 425 | const Search = struct { |
| 426 | path: []const u8, |
| 427 | version: []const u8, |
| 428 | }; |
| 429 | |
| 430 | fn fillSearch(search_buf: *[2]Search, sdk: *c.ZigWindowsSDK) []Search { |
| 431 | var search_end: usize = 0; |
| 432 | if (sdk.path10_ptr) |path10_ptr| { |
| 433 | if (sdk.version10_ptr) |ver10_ptr| { |
| 434 | search_buf[search_end] = Search{ |
| 435 | .path = path10_ptr[0..sdk.path10_len], |
| 436 | .version = ver10_ptr[0..sdk.version10_len], |
| 437 | }; |
| 438 | search_end += 1; |
| 439 | } |
| 440 | } |
| 441 | if (sdk.path81_ptr) |path81_ptr| { |
| 442 | if (sdk.version81_ptr) |ver81_ptr| { |
| 443 | search_buf[search_end] = Search{ |
| 444 | .path = path81_ptr[0..sdk.path81_len], |
| 445 | .version = ver81_ptr[0..sdk.version81_len], |
| 446 | }; |
| 447 | search_end += 1; |
| 448 | } |
| 449 | } |
| 450 | return search_buf[0..search_end]; |
| 451 | } |
| 452 | |
| 453 | |
| 454 | fn fileExists(allocator: *std.mem.Allocator, path: []const u8) !bool { |
| 455 | if (std.os.File.access(allocator, path)) |_| { |
| 456 | return true; |
| 457 | } else |err| switch (err) { |
| 458 | error.NotFound, error.PermissionDenied => return false, |
| 459 | error.OutOfMemory => return error.OutOfMemory, |
| 460 | else => return error.FileSystem, |
| 461 | } |
| 462 | } |