| ... | @@ -23,9 +23,9 @@ pub const Builder = struct { | ... | @@ -23,9 +23,9 @@ pub const Builder = struct { |
| 23 | have_uninstall_step: bool, | 23 | have_uninstall_step: bool, |
| 24 | have_install_step: bool, | 24 | have_install_step: bool, |
| 25 | allocator: *Allocator, | 25 | allocator: *Allocator, |
| 26 | lib_paths: ArrayList([]const u8), | 26 | native_system_lib_paths: ArrayList([]const u8), |
| 27 | include_paths: ArrayList([]const u8), | 27 | native_system_include_dirs: ArrayList([]const u8), |
| 28 | rpaths: ArrayList([]const u8), | 28 | native_system_rpaths: ArrayList([]const u8), |
| 29 | user_input_options: UserInputOptionsMap, | 29 | user_input_options: UserInputOptionsMap, |
| 30 | available_options_map: AvailableOptionsMap, | 30 | available_options_map: AvailableOptionsMap, |
| 31 | available_options_list: ArrayList(AvailableOption), | 31 | available_options_list: ArrayList(AvailableOption), |
| ... | @@ -108,9 +108,9 @@ pub const Builder = struct { | ... | @@ -108,9 +108,9 @@ pub const Builder = struct { |
| 108 | .verbose_cimport = false, | 108 | .verbose_cimport = false, |
| 109 | .invalid_user_input = false, | 109 | .invalid_user_input = false, |
| 110 | .allocator = allocator, | 110 | .allocator = allocator, |
| 111 | .lib_paths = ArrayList([]const u8).init(allocator), | 111 | .native_system_lib_paths = ArrayList([]const u8).init(allocator), |
| 112 | .include_paths = ArrayList([]const u8).init(allocator), | 112 | .native_system_include_dirs = ArrayList([]const u8).init(allocator), |
| 113 | .rpaths = ArrayList([]const u8).init(allocator), | 113 | .native_system_rpaths = ArrayList([]const u8).init(allocator), |
| 114 | .user_input_options = UserInputOptionsMap.init(allocator), | 114 | .user_input_options = UserInputOptionsMap.init(allocator), |
| 115 | .available_options_map = AvailableOptionsMap.init(allocator), | 115 | .available_options_map = AvailableOptionsMap.init(allocator), |
| 116 | .available_options_list = ArrayList(AvailableOption).init(allocator), | 116 | .available_options_list = ArrayList(AvailableOption).init(allocator), |
| ... | @@ -134,15 +134,15 @@ pub const Builder = struct { | ... | @@ -134,15 +134,15 @@ pub const Builder = struct { |
| 134 | .have_install_step = false, | 134 | .have_install_step = false, |
| 135 | .release_mode = null, | 135 | .release_mode = null, |
| 136 | }; | 136 | }; |
| 137 | self.processNixOSEnvVars(); | 137 | self.detectNativeSystemPaths(); |
| 138 | self.default_step = self.step("default", "Build the project"); | 138 | self.default_step = self.step("default", "Build the project"); |
| 139 | return self; | 139 | return self; |
| 140 | } | 140 | } |
| 141 | | 141 | |
| 142 | pub fn deinit(self: *Builder) void { | 142 | pub fn deinit(self: *Builder) void { |
| 143 | self.lib_paths.deinit(); | 143 | self.native_system_lib_paths.deinit(); |
| 144 | self.include_paths.deinit(); | 144 | self.native_system_include_dirs.deinit(); |
| 145 | self.rpaths.deinit(); | 145 | self.native_system_rpaths.deinit(); |
| 146 | self.env_map.deinit(); | 146 | self.env_map.deinit(); |
| 147 | self.top_level_steps.deinit(); | 147 | self.top_level_steps.deinit(); |
| 148 | } | 148 | } |
| ... | @@ -230,16 +230,16 @@ pub const Builder = struct { | ... | @@ -230,16 +230,16 @@ pub const Builder = struct { |
| 230 | }; | 230 | }; |
| 231 | } | 231 | } |
| 232 | | 232 | |
| 233 | pub fn addCIncludePath(self: *Builder, path: []const u8) void { | 233 | pub fn addNativeSystemIncludeDir(self: *Builder, path: []const u8) void { |
| 234 | self.include_paths.append(path) catch unreachable; | 234 | self.native_system_include_dirs.append(path) catch unreachable; |
| 235 | } | 235 | } |
| 236 | | 236 | |
| 237 | pub fn addRPath(self: *Builder, path: []const u8) void { | 237 | pub fn addNativeSystemRPath(self: *Builder, path: []const u8) void { |
| 238 | self.rpaths.append(path) catch unreachable; | 238 | self.native_system_rpaths.append(path) catch unreachable; |
| 239 | } | 239 | } |
| 240 | | 240 | |
| 241 | pub fn addLibPath(self: *Builder, path: []const u8) void { | 241 | pub fn addNativeSystemLibPath(self: *Builder, path: []const u8) void { |
| 242 | self.lib_paths.append(path) catch unreachable; | 242 | self.native_system_lib_paths.append(path) catch unreachable; |
| 243 | } | 243 | } |
| 244 | | 244 | |
| 245 | pub fn make(self: *Builder, step_names: []const []const u8) !void { | 245 | pub fn make(self: *Builder, step_names: []const []const u8) !void { |
| ... | @@ -323,8 +323,10 @@ pub const Builder = struct { | ... | @@ -323,8 +323,10 @@ pub const Builder = struct { |
| 323 | return error.InvalidStepName; | 323 | return error.InvalidStepName; |
| 324 | } | 324 | } |
| 325 | | 325 | |
| 326 | fn processNixOSEnvVars(self: *Builder) void { | 326 | fn detectNativeSystemPaths(self: *Builder) void { |
| | 327 | var is_nixos = false; |
| 327 | if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { | 328 | if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { |
| | 329 | is_nixos = true; |
| 328 | var it = mem.tokenize(nix_cflags_compile, " "); | 330 | var it = mem.tokenize(nix_cflags_compile, " "); |
| 329 | while (true) { | 331 | while (true) { |
| 330 | const word = it.next() orelse break; | 332 | const word = it.next() orelse break; |
| ... | @@ -333,7 +335,7 @@ pub const Builder = struct { | ... | @@ -333,7 +335,7 @@ pub const Builder = struct { |
| 333 | warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n"); | 335 | warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n"); |
| 334 | break; | 336 | break; |
| 335 | }; | 337 | }; |
| 336 | self.addCIncludePath(include_path); | 338 | self.addNativeSystemIncludeDir(include_path); |
| 337 | } else { | 339 | } else { |
| 338 | warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", word); | 340 | warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", word); |
| 339 | break; | 341 | break; |
| ... | @@ -343,6 +345,7 @@ pub const Builder = struct { | ... | @@ -343,6 +345,7 @@ pub const Builder = struct { |
| 343 | assert(err == error.EnvironmentVariableNotFound); | 345 | assert(err == error.EnvironmentVariableNotFound); |
| 344 | } | 346 | } |
| 345 | if (os.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| { | 347 | if (os.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| { |
| | 348 | is_nixos = true; |
| 346 | var it = mem.tokenize(nix_ldflags, " "); | 349 | var it = mem.tokenize(nix_ldflags, " "); |
| 347 | while (true) { | 350 | while (true) { |
| 348 | const word = it.next() orelse break; | 351 | const word = it.next() orelse break; |
| ... | @@ -351,10 +354,10 @@ pub const Builder = struct { | ... | @@ -351,10 +354,10 @@ pub const Builder = struct { |
| 351 | warn("Expected argument after -rpath in NIX_LDFLAGS\n"); | 354 | warn("Expected argument after -rpath in NIX_LDFLAGS\n"); |
| 352 | break; | 355 | break; |
| 353 | }; | 356 | }; |
| 354 | self.addRPath(rpath); | 357 | self.addNativeSystemRPath(rpath); |
| 355 | } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') { | 358 | } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') { |
| 356 | const lib_path = word[2..]; | 359 | const lib_path = word[2..]; |
| 357 | self.addLibPath(lib_path); | 360 | self.addNativeSystemLibPath(lib_path); |
| 358 | } else { | 361 | } else { |
| 359 | warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", word); | 362 | warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", word); |
| 360 | break; | 363 | break; |
| ... | @@ -363,6 +366,26 @@ pub const Builder = struct { | ... | @@ -363,6 +366,26 @@ pub const Builder = struct { |
| 363 | } else |err| { | 366 | } else |err| { |
| 364 | assert(err == error.EnvironmentVariableNotFound); | 367 | assert(err == error.EnvironmentVariableNotFound); |
| 365 | } | 368 | } |
| | 369 | if (is_nixos) return; |
| | 370 | switch (builtin.os) { |
| | 371 | builtin.Os.windows => {}, |
| | 372 | else => { |
| | 373 | const triple = (CrossTarget{ |
| | 374 | .arch = builtin.arch, |
| | 375 | .os = builtin.os, |
| | 376 | .abi = builtin.abi, |
| | 377 | }).linuxTriple(self.allocator); |
| | 378 | |
| | 379 | self.addNativeSystemIncludeDir("/usr/local/include"); |
| | 380 | self.addNativeSystemLibPath("/usr/local/lib"); |
| | 381 | |
| | 382 | self.addNativeSystemIncludeDir(self.fmt("/usr/include/{}", triple)); |
| | 383 | self.addNativeSystemLibPath(self.fmt("/usr/lib/{}", triple)); |
| | 384 | |
| | 385 | self.addNativeSystemIncludeDir("/usr/include"); |
| | 386 | self.addNativeSystemLibPath("/usr/lib"); |
| | 387 | }, |
| | 388 | } |
| 366 | } | 389 | } |
| 367 | | 390 | |
| 368 | pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T { | 391 | pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T { |
| ... | @@ -766,6 +789,27 @@ const CrossTarget = struct { | ... | @@ -766,6 +789,27 @@ const CrossTarget = struct { |
| 766 | arch: builtin.Arch, | 789 | arch: builtin.Arch, |
| 767 | os: builtin.Os, | 790 | os: builtin.Os, |
| 768 | abi: builtin.Abi, | 791 | abi: builtin.Abi, |
| | 792 | |
| | 793 | pub fn zigTriple(cross_target: CrossTarget, allocator: *Allocator) []u8 { |
| | 794 | return std.fmt.allocPrint( |
| | 795 | allocator, |
| | 796 | "{}{}-{}-{}", |
| | 797 | @tagName(cross_target.arch), |
| | 798 | Target.archSubArchName(cross_target.arch), |
| | 799 | @tagName(cross_target.os), |
| | 800 | @tagName(cross_target.abi), |
| | 801 | ) catch unreachable; |
| | 802 | } |
| | 803 | |
| | 804 | pub fn linuxTriple(cross_target: CrossTarget, allocator: *Allocator) []u8 { |
| | 805 | return std.fmt.allocPrint( |
| | 806 | allocator, |
| | 807 | "{}-{}-{}", |
| | 808 | @tagName(cross_target.arch), |
| | 809 | @tagName(cross_target.os), |
| | 810 | @tagName(cross_target.abi), |
| | 811 | ) catch unreachable; |
| | 812 | } |
| 769 | }; | 813 | }; |
| 770 | | 814 | |
| 771 | pub const Target = union(enum) { | 815 | pub const Target = union(enum) { |
| ... | @@ -860,6 +904,15 @@ const CSourceFile = struct { | ... | @@ -860,6 +904,15 @@ const CSourceFile = struct { |
| 860 | args: []const []const u8, | 904 | args: []const []const u8, |
| 861 | }; | 905 | }; |
| 862 | | 906 | |
| | 907 | fn isLibCLibrary(name: []const u8) bool { |
| | 908 | const libc_libraries = [][]const u8{ "c", "m", "dl", "rt", "pthread" }; |
| | 909 | for (libc_libraries) |libc_lib_name| { |
| | 910 | if (mem.eql(u8, name, libc_lib_name)) |
| | 911 | return true; |
| | 912 | } |
| | 913 | return false; |
| | 914 | } |
| | 915 | |
| 863 | pub const LibExeObjStep = struct { | 916 | pub const LibExeObjStep = struct { |
| 864 | step: Step, | 917 | step: Step, |
| 865 | builder: *Builder, | 918 | builder: *Builder, |
| ... | @@ -898,6 +951,7 @@ pub const LibExeObjStep = struct { | ... | @@ -898,6 +951,7 @@ pub const LibExeObjStep = struct { |
| 898 | link_objects: ArrayList(LinkObject), | 951 | link_objects: ArrayList(LinkObject), |
| 899 | include_dirs: ArrayList(IncludeDir), | 952 | include_dirs: ArrayList(IncludeDir), |
| 900 | output_dir: ?[]const u8, | 953 | output_dir: ?[]const u8, |
| | 954 | need_system_paths: bool, |
| 901 | | 955 | |
| 902 | const LinkObject = union(enum) { | 956 | const LinkObject = union(enum) { |
| 903 | StaticPath: []const u8, | 957 | StaticPath: []const u8, |
| ... | @@ -985,6 +1039,7 @@ pub const LibExeObjStep = struct { | ... | @@ -985,6 +1039,7 @@ pub const LibExeObjStep = struct { |
| 985 | .filter = null, | 1039 | .filter = null, |
| 986 | .disable_gen_h = false, | 1040 | .disable_gen_h = false, |
| 987 | .output_dir = null, | 1041 | .output_dir = null, |
| | 1042 | .need_system_paths = false, |
| 988 | }; | 1043 | }; |
| 989 | self.computeOutFileNames(); | 1044 | self.computeOutFileNames(); |
| 990 | return self; | 1045 | return self; |
| ... | @@ -1097,6 +1152,9 @@ pub const LibExeObjStep = struct { | ... | @@ -1097,6 +1152,9 @@ pub const LibExeObjStep = struct { |
| 1097 | | 1152 | |
| 1098 | pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void { | 1153 | pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void { |
| 1099 | self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable; | 1154 | self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable; |
| | 1155 | if (!isLibCLibrary(name)) { |
| | 1156 | self.need_system_paths = true; |
| | 1157 | } |
| 1100 | } | 1158 | } |
| 1101 | | 1159 | |
| 1102 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { | 1160 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { |
| ... | @@ -1372,16 +1430,8 @@ pub const LibExeObjStep = struct { | ... | @@ -1372,16 +1430,8 @@ pub const LibExeObjStep = struct { |
| 1372 | switch (self.target) { | 1430 | switch (self.target) { |
| 1373 | Target.Native => {}, | 1431 | Target.Native => {}, |
| 1374 | Target.Cross => |cross_target| { | 1432 | Target.Cross => |cross_target| { |
| 1375 | const triple = builder.fmt( | | |
| 1376 | "{}{}-{}-{}", | | |
| 1377 | @tagName(cross_target.arch), | | |
| 1378 | Target.archSubArchName(cross_target.arch), | | |
| 1379 | @tagName(cross_target.os), | | |
| 1380 | @tagName(cross_target.abi), | | |
| 1381 | ); | | |
| 1382 | | | |
| 1383 | try zig_args.append("-target"); | 1433 | try zig_args.append("-target"); |
| 1384 | try zig_args.append(triple); | 1434 | try zig_args.append(cross_target.zigTriple(builder.allocator)); |
| 1385 | }, | 1435 | }, |
| 1386 | } | 1436 | } |
| 1387 | | 1437 | |
| ... | @@ -1421,24 +1471,26 @@ pub const LibExeObjStep = struct { | ... | @@ -1421,24 +1471,26 @@ pub const LibExeObjStep = struct { |
| 1421 | } | 1471 | } |
| 1422 | } | 1472 | } |
| 1423 | | 1473 | |
| 1424 | for (builder.include_paths.toSliceConst()) |include_path| { | | |
| 1425 | zig_args.append("-isystem") catch unreachable; | | |
| 1426 | zig_args.append(builder.pathFromRoot(include_path)) catch unreachable; | | |
| 1427 | } | | |
| 1428 | | | |
| 1429 | for (builder.rpaths.toSliceConst()) |rpath| { | | |
| 1430 | zig_args.append("-rpath") catch unreachable; | | |
| 1431 | zig_args.append(rpath) catch unreachable; | | |
| 1432 | } | | |
| 1433 | | | |
| 1434 | for (self.lib_paths.toSliceConst()) |lib_path| { | 1474 | for (self.lib_paths.toSliceConst()) |lib_path| { |
| 1435 | zig_args.append("--library-path") catch unreachable; | 1475 | zig_args.append("--library-path") catch unreachable; |
| 1436 | zig_args.append(lib_path) catch unreachable; | 1476 | zig_args.append(lib_path) catch unreachable; |
| 1437 | } | 1477 | } |
| 1438 | | 1478 | |
| 1439 | for (builder.lib_paths.toSliceConst()) |lib_path| { | 1479 | if (self.need_system_paths and self.target == Target.Native) { |
| 1440 | zig_args.append("--library-path") catch unreachable; | 1480 | for (builder.native_system_include_dirs.toSliceConst()) |include_path| { |
| 1441 | zig_args.append(lib_path) catch unreachable; | 1481 | zig_args.append("-isystem") catch unreachable; |
| | 1482 | zig_args.append(builder.pathFromRoot(include_path)) catch unreachable; |
| | 1483 | } |
| | 1484 | |
| | 1485 | for (builder.native_system_rpaths.toSliceConst()) |rpath| { |
| | 1486 | zig_args.append("-rpath") catch unreachable; |
| | 1487 | zig_args.append(rpath) catch unreachable; |
| | 1488 | } |
| | 1489 | |
| | 1490 | for (builder.native_system_lib_paths.toSliceConst()) |lib_path| { |
| | 1491 | zig_args.append("--library-path") catch unreachable; |
| | 1492 | zig_args.append(lib_path) catch unreachable; |
| | 1493 | } |
| 1442 | } | 1494 | } |
| 1443 | | 1495 | |
| 1444 | if (self.target.isDarwin()) { | 1496 | if (self.target.isDarwin()) { |