| ... | ... | @@ -23,9 +23,9 @@ pub const Builder = struct { |
| 23 | 23 | have_uninstall_step: bool, |
| 24 | 24 | have_install_step: bool, |
| 25 | 25 | allocator: *Allocator, |
| 26 | | lib_paths: ArrayList([]const u8), |
| 27 | | include_paths: ArrayList([]const u8), |
| 28 | | rpaths: ArrayList([]const u8), |
| 26 | native_system_lib_paths: ArrayList([]const u8), |
| 27 | native_system_include_dirs: ArrayList([]const u8), |
| 28 | native_system_rpaths: ArrayList([]const u8), |
| 29 | 29 | user_input_options: UserInputOptionsMap, |
| 30 | 30 | available_options_map: AvailableOptionsMap, |
| 31 | 31 | available_options_list: ArrayList(AvailableOption), |
| ... | ... | @@ -108,9 +108,9 @@ pub const Builder = struct { |
| 108 | 108 | .verbose_cimport = false, |
| 109 | 109 | .invalid_user_input = false, |
| 110 | 110 | .allocator = allocator, |
| 111 | | .lib_paths = ArrayList([]const u8).init(allocator), |
| 112 | | .include_paths = ArrayList([]const u8).init(allocator), |
| 113 | | .rpaths = ArrayList([]const u8).init(allocator), |
| 111 | .native_system_lib_paths = ArrayList([]const u8).init(allocator), |
| 112 | .native_system_include_dirs = ArrayList([]const u8).init(allocator), |
| 113 | .native_system_rpaths = ArrayList([]const u8).init(allocator), |
| 114 | 114 | .user_input_options = UserInputOptionsMap.init(allocator), |
| 115 | 115 | .available_options_map = AvailableOptionsMap.init(allocator), |
| 116 | 116 | .available_options_list = ArrayList(AvailableOption).init(allocator), |
| ... | ... | @@ -134,15 +134,15 @@ pub const Builder = struct { |
| 134 | 134 | .have_install_step = false, |
| 135 | 135 | .release_mode = null, |
| 136 | 136 | }; |
| 137 | | self.processNixOSEnvVars(); |
| 137 | self.detectNativeSystemPaths(); |
| 138 | 138 | self.default_step = self.step("default", "Build the project"); |
| 139 | 139 | return self; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | pub fn deinit(self: *Builder) void { |
| 143 | | self.lib_paths.deinit(); |
| 144 | | self.include_paths.deinit(); |
| 145 | | self.rpaths.deinit(); |
| 143 | self.native_system_lib_paths.deinit(); |
| 144 | self.native_system_include_dirs.deinit(); |
| 145 | self.native_system_rpaths.deinit(); |
| 146 | 146 | self.env_map.deinit(); |
| 147 | 147 | self.top_level_steps.deinit(); |
| 148 | 148 | } |
| ... | ... | @@ -230,16 +230,16 @@ pub const Builder = struct { |
| 230 | 230 | }; |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | | pub fn addCIncludePath(self: *Builder, path: []const u8) void { |
| 234 | | self.include_paths.append(path) catch unreachable; |
| 233 | pub fn addNativeSystemIncludeDir(self: *Builder, path: []const u8) void { |
| 234 | self.native_system_include_dirs.append(path) catch unreachable; |
| 235 | 235 | } |
| 236 | 236 | |
| 237 | | pub fn addRPath(self: *Builder, path: []const u8) void { |
| 238 | | self.rpaths.append(path) catch unreachable; |
| 237 | pub fn addNativeSystemRPath(self: *Builder, path: []const u8) void { |
| 238 | self.native_system_rpaths.append(path) catch unreachable; |
| 239 | 239 | } |
| 240 | 240 | |
| 241 | | pub fn addLibPath(self: *Builder, path: []const u8) void { |
| 242 | | self.lib_paths.append(path) catch unreachable; |
| 241 | pub fn addNativeSystemLibPath(self: *Builder, path: []const u8) void { |
| 242 | self.native_system_lib_paths.append(path) catch unreachable; |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | pub fn make(self: *Builder, step_names: []const []const u8) !void { |
| ... | ... | @@ -323,8 +323,10 @@ pub const Builder = struct { |
| 323 | 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 | 328 | if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { |
| 329 | is_nixos = true; |
| 328 | 330 | var it = mem.tokenize(nix_cflags_compile, " "); |
| 329 | 331 | while (true) { |
| 330 | 332 | const word = it.next() orelse break; |
| ... | ... | @@ -333,7 +335,7 @@ pub const Builder = struct { |
| 333 | 335 | warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n"); |
| 334 | 336 | break; |
| 335 | 337 | }; |
| 336 | | self.addCIncludePath(include_path); |
| 338 | self.addNativeSystemIncludeDir(include_path); |
| 337 | 339 | } else { |
| 338 | 340 | warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", word); |
| 339 | 341 | break; |
| ... | ... | @@ -343,6 +345,7 @@ pub const Builder = struct { |
| 343 | 345 | assert(err == error.EnvironmentVariableNotFound); |
| 344 | 346 | } |
| 345 | 347 | if (os.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| { |
| 348 | is_nixos = true; |
| 346 | 349 | var it = mem.tokenize(nix_ldflags, " "); |
| 347 | 350 | while (true) { |
| 348 | 351 | const word = it.next() orelse break; |
| ... | ... | @@ -351,10 +354,10 @@ pub const Builder = struct { |
| 351 | 354 | warn("Expected argument after -rpath in NIX_LDFLAGS\n"); |
| 352 | 355 | break; |
| 353 | 356 | }; |
| 354 | | self.addRPath(rpath); |
| 357 | self.addNativeSystemRPath(rpath); |
| 355 | 358 | } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') { |
| 356 | 359 | const lib_path = word[2..]; |
| 357 | | self.addLibPath(lib_path); |
| 360 | self.addNativeSystemLibPath(lib_path); |
| 358 | 361 | } else { |
| 359 | 362 | warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", word); |
| 360 | 363 | break; |
| ... | ... | @@ -363,6 +366,26 @@ pub const Builder = struct { |
| 363 | 366 | } else |err| { |
| 364 | 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 | 391 | pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T { |
| ... | ... | @@ -766,6 +789,27 @@ const CrossTarget = struct { |
| 766 | 789 | arch: builtin.Arch, |
| 767 | 790 | os: builtin.Os, |
| 768 | 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 | 815 | pub const Target = union(enum) { |
| ... | ... | @@ -860,6 +904,15 @@ const CSourceFile = struct { |
| 860 | 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 | 916 | pub const LibExeObjStep = struct { |
| 864 | 917 | step: Step, |
| 865 | 918 | builder: *Builder, |
| ... | ... | @@ -898,6 +951,7 @@ pub const LibExeObjStep = struct { |
| 898 | 951 | link_objects: ArrayList(LinkObject), |
| 899 | 952 | include_dirs: ArrayList(IncludeDir), |
| 900 | 953 | output_dir: ?[]const u8, |
| 954 | need_system_paths: bool, |
| 901 | 955 | |
| 902 | 956 | const LinkObject = union(enum) { |
| 903 | 957 | StaticPath: []const u8, |
| ... | ... | @@ -985,6 +1039,7 @@ pub const LibExeObjStep = struct { |
| 985 | 1039 | .filter = null, |
| 986 | 1040 | .disable_gen_h = false, |
| 987 | 1041 | .output_dir = null, |
| 1042 | .need_system_paths = false, |
| 988 | 1043 | }; |
| 989 | 1044 | self.computeOutFileNames(); |
| 990 | 1045 | return self; |
| ... | ... | @@ -1097,6 +1152,9 @@ pub const LibExeObjStep = struct { |
| 1097 | 1152 | |
| 1098 | 1153 | pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void { |
| 1099 | 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 | 1160 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { |
| ... | ... | @@ -1372,16 +1430,8 @@ pub const LibExeObjStep = struct { |
| 1372 | 1430 | switch (self.target) { |
| 1373 | 1431 | Target.Native => {}, |
| 1374 | 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 | 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 | 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 | 1474 | for (self.lib_paths.toSliceConst()) |lib_path| { |
| 1435 | 1475 | zig_args.append("--library-path") catch unreachable; |
| 1436 | 1476 | zig_args.append(lib_path) catch unreachable; |
| 1437 | 1477 | } |
| 1438 | 1478 | |
| 1439 | | for (builder.lib_paths.toSliceConst()) |lib_path| { |
| 1440 | | zig_args.append("--library-path") catch unreachable; |
| 1441 | | zig_args.append(lib_path) catch unreachable; |
| 1479 | if (self.need_system_paths and self.target == Target.Native) { |
| 1480 | for (builder.native_system_include_dirs.toSliceConst()) |include_path| { |
| 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 | 1496 | if (self.target.isDarwin()) { |