authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-11 15:22:05-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-11 15:22:05-04:00
logf2ca2ace0943a81e0fc5b59347feac177a71eb6c
tree1ff83c3186718595fcb98268b17a45e64f3ee350
parenta909efae9fceb15957144194cf1ae646e8111bb6
signaturelock-open Commit is signed but in an unrecognized format.

zig build: do a better job of detecting system paths

See #2041

2 files changed, 95 insertions(+), 44 deletions(-)

std/build.zig+94-42
......@@ -23,9 +23,9 @@ pub const Builder = struct {
2323 have_uninstall_step: bool,
2424 have_install_step: bool,
2525 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),
2929 user_input_options: UserInputOptionsMap,
3030 available_options_map: AvailableOptionsMap,
3131 available_options_list: ArrayList(AvailableOption),
......@@ -108,9 +108,9 @@ pub const Builder = struct {
108108 .verbose_cimport = false,
109109 .invalid_user_input = false,
110110 .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),
114114 .user_input_options = UserInputOptionsMap.init(allocator),
115115 .available_options_map = AvailableOptionsMap.init(allocator),
116116 .available_options_list = ArrayList(AvailableOption).init(allocator),
......@@ -134,15 +134,15 @@ pub const Builder = struct {
134134 .have_install_step = false,
135135 .release_mode = null,
136136 };
137 self.processNixOSEnvVars();
137 self.detectNativeSystemPaths();
138138 self.default_step = self.step("default", "Build the project");
139139 return self;
140140 }
141141
142142 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();
146146 self.env_map.deinit();
147147 self.top_level_steps.deinit();
148148 }
......@@ -230,16 +230,16 @@ pub const Builder = struct {
230230 };
231231 }
232232
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;
235235 }
236236
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;
239239 }
240240
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;
243243 }
244244
245245 pub fn make(self: *Builder, step_names: []const []const u8) !void {
......@@ -323,8 +323,10 @@ pub const Builder = struct {
323323 return error.InvalidStepName;
324324 }
325325
326 fn processNixOSEnvVars(self: *Builder) void {
326 fn detectNativeSystemPaths(self: *Builder) void {
327 var is_nixos = false;
327328 if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
329 is_nixos = true;
328330 var it = mem.tokenize(nix_cflags_compile, " ");
329331 while (true) {
330332 const word = it.next() orelse break;
......@@ -333,7 +335,7 @@ pub const Builder = struct {
333335 warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n");
334336 break;
335337 };
336 self.addCIncludePath(include_path);
338 self.addNativeSystemIncludeDir(include_path);
337339 } else {
338340 warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", word);
339341 break;
......@@ -343,6 +345,7 @@ pub const Builder = struct {
343345 assert(err == error.EnvironmentVariableNotFound);
344346 }
345347 if (os.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
348 is_nixos = true;
346349 var it = mem.tokenize(nix_ldflags, " ");
347350 while (true) {
348351 const word = it.next() orelse break;
......@@ -351,10 +354,10 @@ pub const Builder = struct {
351354 warn("Expected argument after -rpath in NIX_LDFLAGS\n");
352355 break;
353356 };
354 self.addRPath(rpath);
357 self.addNativeSystemRPath(rpath);
355358 } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') {
356359 const lib_path = word[2..];
357 self.addLibPath(lib_path);
360 self.addNativeSystemLibPath(lib_path);
358361 } else {
359362 warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", word);
360363 break;
......@@ -363,6 +366,26 @@ pub const Builder = struct {
363366 } else |err| {
364367 assert(err == error.EnvironmentVariableNotFound);
365368 }
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 }
366389 }
367390
368391 pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
......@@ -766,6 +789,27 @@ const CrossTarget = struct {
766789 arch: builtin.Arch,
767790 os: builtin.Os,
768791 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 }
769813};
770814
771815pub const Target = union(enum) {
......@@ -860,6 +904,15 @@ const CSourceFile = struct {
860904 args: []const []const u8,
861905};
862906
907fn 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
863916pub const LibExeObjStep = struct {
864917 step: Step,
865918 builder: *Builder,
......@@ -898,6 +951,7 @@ pub const LibExeObjStep = struct {
898951 link_objects: ArrayList(LinkObject),
899952 include_dirs: ArrayList(IncludeDir),
900953 output_dir: ?[]const u8,
954 need_system_paths: bool,
901955
902956 const LinkObject = union(enum) {
903957 StaticPath: []const u8,
......@@ -985,6 +1039,7 @@ pub const LibExeObjStep = struct {
9851039 .filter = null,
9861040 .disable_gen_h = false,
9871041 .output_dir = null,
1042 .need_system_paths = false,
9881043 };
9891044 self.computeOutFileNames();
9901045 return self;
......@@ -1097,6 +1152,9 @@ pub const LibExeObjStep = struct {
10971152
10981153 pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void {
10991154 self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable;
1155 if (!isLibCLibrary(name)) {
1156 self.need_system_paths = true;
1157 }
11001158 }
11011159
11021160 pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void {
......@@ -1372,16 +1430,8 @@ pub const LibExeObjStep = struct {
13721430 switch (self.target) {
13731431 Target.Native => {},
13741432 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
13831433 try zig_args.append("-target");
1384 try zig_args.append(triple);
1434 try zig_args.append(cross_target.zigTriple(builder.allocator));
13851435 },
13861436 }
13871437
......@@ -1421,24 +1471,26 @@ pub const LibExeObjStep = struct {
14211471 }
14221472 }
14231473
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
14341474 for (self.lib_paths.toSliceConst()) |lib_path| {
14351475 zig_args.append("--library-path") catch unreachable;
14361476 zig_args.append(lib_path) catch unreachable;
14371477 }
14381478
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 }
14421494 }
14431495
14441496 if (self.target.isDarwin()) {
test/standalone/use_alias/build.zig+1-2
......@@ -1,10 +1,9 @@
11const Builder = @import("std").build.Builder;
22
33pub fn build(b: *Builder) void {
4 b.addCIncludePath(".");
5
64 const main = b.addTest("main.zig");
75 main.setBuildMode(b.standardReleaseOptions());
6 main.addIncludeDir(".");
87
98 const test_step = b.step("test", "Test it");
109 test_step.dependOn(&main.step);