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 {...@@ -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 }
141141
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 }
232232
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 }
236236
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 }
240240
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 }
244244
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 }
325325
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 }
367390
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};
770814
771pub const Target = union(enum) {815pub 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};
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
863pub const LibExeObjStep = struct {916pub 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,
901955
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 {
10971152
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 }
11011159
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 }
13871437
...@@ -1421,24 +1471,26 @@ pub const LibExeObjStep = struct {...@@ -1421,24 +1471,26 @@ pub const LibExeObjStep = struct {
1421 }1471 }
1422 }1472 }
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
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 }
14381478
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 }
14431495
1444 if (self.target.isDarwin()) {1496 if (self.target.isDarwin()) {
test/standalone/use_alias/build.zig+1-2
...@@ -1,10 +1,9 @@...@@ -1,10 +1,9 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: *Builder) void {3pub fn build(b: *Builder) void {
4 b.addCIncludePath(".");
5
6 const main = b.addTest("main.zig");4 const main = b.addTest("main.zig");
7 main.setBuildMode(b.standardReleaseOptions());5 main.setBuildMode(b.standardReleaseOptions());
6 main.addIncludeDir(".");
87
9 const test_step = b.step("test", "Test it");8 const test_step = b.step("test", "Test it");
10 test_step.dependOn(&main.step);9 test_step.dependOn(&main.step);