| ... | @@ -20,8 +20,10 @@ pub const LibCInstallation = struct { | ... | @@ -20,8 +20,10 @@ pub const LibCInstallation = struct { |
| 20 | CCompilerExitCode, | 20 | CCompilerExitCode, |
| 21 | CCompilerCrashed, | 21 | CCompilerCrashed, |
| 22 | CCompilerCannotFindHeaders, | 22 | CCompilerCannotFindHeaders, |
| 23 | CCompilerCannotFindCRuntime, | 23 | LibCRuntimeNotFound, |
| 24 | LibCStdLibHeaderNotFound, | 24 | LibCStdLibHeaderNotFound, |
| | 25 | LibCKernel32LibNotFound, |
| | 26 | UnsupportedArchitecture, |
| 25 | }; | 27 | }; |
| 26 | | 28 | |
| 27 | pub fn parse( | 29 | pub fn parse( |
| ... | @@ -111,7 +113,7 @@ pub const LibCInstallation = struct { | ... | @@ -111,7 +113,7 @@ pub const LibCInstallation = struct { |
| 111 | \\lib_dir={} | 113 | \\lib_dir={} |
| 112 | \\ | 114 | \\ |
| 113 | \\# The directory that contains `crtbegin.o`. | 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 | \\# Not needed when targeting MacOS or Windows. | 117 | \\# Not needed when targeting MacOS or Windows. |
| 116 | \\static_lib_dir={} | 118 | \\static_lib_dir={} |
| 117 | \\ | 119 | \\ |
| ... | @@ -142,21 +144,22 @@ pub const LibCInstallation = struct { | ... | @@ -142,21 +144,22 @@ pub const LibCInstallation = struct { |
| 142 | self.initEmpty(); | 144 | self.initEmpty(); |
| 143 | var group = event.Group(FindError!void).init(loop); | 145 | var group = event.Group(FindError!void).init(loop); |
| 144 | errdefer group.cancelAll(); | 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 | switch (builtin.os) { | 150 | switch (builtin.os) { |
| 146 | builtin.Os.windows => { | 151 | builtin.Os.windows => { |
| 147 | var sdk: *c.ZigWindowsSDK = undefined; | 152 | var sdk: *c.ZigWindowsSDK = undefined; |
| 148 | switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) { | 153 | switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) { |
| 149 | c.ZigFindWindowsSdkError.None => { | 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 | if (sdk.msvc_lib_dir_ptr) |ptr| { | 157 | if (sdk.msvc_lib_dir_ptr) |ptr| { |
| 154 | self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, ptr[0..sdk.msvc_lib_dir_len]); | 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); | 160 | try group.call(findNativeKernel32LibDir, self, loop, sdk); |
| 157 | //try group.call(findNativeLibDirWindows, self, loop); | 161 | try group.call(findNativeIncludeDirWindows, self, loop, sdk); |
| 158 | //try group.call(findNativeMsvcLibDir, self, loop); | 162 | try group.call(findNativeLibDirWindows, self, loop, sdk); |
| 159 | //try group.call(findNativeKernel32LibDir, self, loop); | | |
| 160 | }, | 163 | }, |
| 161 | c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory, | 164 | c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory, |
| 162 | c.ZigFindWindowsSdkError.NotFound => return error.NotFound, | 165 | c.ZigFindWindowsSdkError.NotFound => return error.NotFound, |
| ... | @@ -230,61 +233,64 @@ pub const LibCInstallation = struct { | ... | @@ -230,61 +233,64 @@ pub const LibCInstallation = struct { |
| 230 | const stdlib_path = try std.os.path.join(loop.allocator, search_path, "stdlib.h"); | 233 | const stdlib_path = try std.os.path.join(loop.allocator, search_path, "stdlib.h"); |
| 231 | defer loop.allocator.free(stdlib_path); | 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 | self.include_dir = try std.mem.dupe(loop.allocator, u8, search_path); | 237 | self.include_dir = try std.mem.dupe(loop.allocator, u8, search_path); |
| 235 | return; | 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 | return error.LibCStdLibHeaderNotFound; | 242 | return error.LibCStdLibHeaderNotFound; |
| 244 | } | 243 | } |
| 245 | | 244 | |
| 246 | async fn findNativeIncludeDirWindows(self: *LibCInstallation, loop: *event.Loop) !void { | 245 | async fn findNativeIncludeDirWindows(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) !void { |
| 247 | // TODO | 246 | var search_buf: [2]Search = undefined; |
| 248 | //ZigWindowsSDK *sdk = get_windows_sdk(g); | 247 | const searches = fillSearch(&search_buf, sdk); |
| 249 | //g->libc_include_dir = buf_alloc(); | 248 | |
| 250 | //if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { | 249 | var result_buf = try std.Buffer.initSize(loop.allocator, 0); |
| 251 | // fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); | 250 | defer result_buf.deinit(); |
| 252 | // exit(1); | 251 | |
| 253 | //} | 252 | for (searches) |search| { |
| 254 | @panic("TODO"); | 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 { | 269 | async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) FindError!void { |
| 258 | // TODO | 270 | var search_buf: [2]Search = undefined; |
| 259 | //ZigWindowsSDK *sdk = get_windows_sdk(g); | 271 | const searches = fillSearch(&search_buf, sdk); |
| 260 | | 272 | |
| 261 | //if (g->msvc_lib_dir == nullptr) { | 273 | var result_buf = try std.Buffer.initSize(loop.allocator, 0); |
| 262 | // Buf* vc_lib_dir = buf_alloc(); | 274 | defer result_buf.deinit(); |
| 263 | // if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) { | 275 | |
| 264 | // fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir"); | 276 | for (searches) |search| { |
| 265 | // exit(1); | 277 | result_buf.shrink(0); |
| 266 | // } | 278 | const stream = &std.io.BufferOutStream.init(&result_buf).stream; |
| 267 | // g->msvc_lib_dir = vc_lib_dir; | 279 | try stream.print("{}\\Lib\\{}\\ucrt\\", search.path, search.version); |
| 268 | //} | 280 | switch (builtin.arch) { |
| 269 | | 281 | builtin.Arch.i386 => try stream.write("x86"), |
| 270 | //if (g->libc_lib_dir == nullptr) { | 282 | builtin.Arch.x86_64 => try stream.write("x64"), |
| 271 | // Buf* ucrt_lib_path = buf_alloc(); | 283 | builtin.Arch.aarch64 => try stream.write("arm"), |
| 272 | // if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) { | 284 | else => return error.UnsupportedArchitecture, |
| 273 | // fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir"); | 285 | } |
| 274 | // exit(1); | 286 | const ucrt_lib_path = try std.os.path.join(loop.allocator, result_buf.toSliceConst(), "ucrt.lib"); |
| 275 | // } | 287 | defer loop.allocator.free(ucrt_lib_path); |
| 276 | // g->libc_lib_dir = ucrt_lib_path; | 288 | if (try fileExists(loop.allocator, ucrt_lib_path)) { |
| 277 | //} | 289 | self.lib_dir = result_buf.toOwnedSlice(); |
| 278 | | 290 | return; |
| 279 | //if (g->kernel32_lib_dir == nullptr) { | 291 | } |
| 280 | // Buf* kern_lib_path = buf_alloc(); | 292 | } |
| 281 | // if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) { | 293 | return error.LibCRuntimeNotFound; |
| 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"); | | |
| 288 | } | 294 | } |
| 289 | | 295 | |
| 290 | async fn findNativeLibDirLinux(self: *LibCInstallation, loop: *event.Loop) FindError!void { | 296 | async fn findNativeLibDirLinux(self: *LibCInstallation, loop: *event.Loop) FindError!void { |
| ... | @@ -330,17 +336,37 @@ pub const LibCInstallation = struct { | ... | @@ -330,17 +336,37 @@ pub const LibCInstallation = struct { |
| 330 | dyn_test.result = result; | 336 | dyn_test.result = result; |
| 331 | return; | 337 | return; |
| 332 | } else |err| switch (err) { | 338 | } else |err| switch (err) { |
| 333 | error.CCompilerCannotFindCRuntime => return, | 339 | error.LibCRuntimeNotFound => return, |
| 334 | else => return err, | 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 { | 345 | async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop, sdk: *c.ZigWindowsSDK) FindError!void { |
| 343 | @panic("TODO"); | 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 | fn initEmpty(self: *LibCInstallation) void { | 372 | fn initEmpty(self: *LibCInstallation) void { |
| ... | @@ -386,8 +412,8 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo | ... | @@ -386,8 +412,8 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo |
| 386 | }, | 412 | }, |
| 387 | } | 413 | } |
| 388 | var it = std.mem.split(exec_result.stdout, "\n\r"); | 414 | var it = std.mem.split(exec_result.stdout, "\n\r"); |
| 389 | const line = it.next() orelse return error.CCompilerCannotFindCRuntime; | 415 | const line = it.next() orelse return error.LibCRuntimeNotFound; |
| 390 | const dirname = std.os.path.dirname(line) orelse return error.CCompilerCannotFindCRuntime; | 416 | const dirname = std.os.path.dirname(line) orelse return error.LibCRuntimeNotFound; |
| 391 | | 417 | |
| 392 | if (want_dirname) { | 418 | if (want_dirname) { |
| 393 | return std.mem.dupe(loop.allocator, u8, dirname); | 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,3 +421,42 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo |
| 395 | return std.mem.dupe(loop.allocator, u8, line); | 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 | } |