@@ -11,7 +11,6 @@ const ArrayList = std.ArrayList;
11
11
const StringHashMap = std .StringHashMap ;
12
12
const Allocator = mem .Allocator ;
13
13
const process = std .process ;
14
- const BufSet = std .BufSet ;
15
14
const EnvMap = std .process .EnvMap ;
16
15
const fmt_lib = std .fmt ;
17
16
const File = std .fs .File ;
@@ -1484,7 +1483,7 @@ pub const LibExeObjStep = struct {
1484
1483
lib_paths : ArrayList ([]const u8 ),
1485
1484
rpaths : ArrayList ([]const u8 ),
1486
1485
framework_dirs : ArrayList ([]const u8 ),
1487
- frameworks : BufSet ,
1486
+ frameworks : StringHashMap ( bool ) ,
1488
1487
verbose_link : bool ,
1489
1488
verbose_cc : bool ,
1490
1489
emit_analysis : EmitOption = .default ,
@@ -1643,6 +1642,7 @@ pub const LibExeObjStep = struct {
1643
1642
1644
1643
pub const SystemLib = struct {
1645
1644
name : []const u8 ,
1645
+ needed : bool ,
1646
1646
use_pkg_config : enum {
1647
1647
/// Don't use pkg-config, just pass -lfoo where foo is name.
1648
1648
no ,
@@ -1744,7 +1744,7 @@ pub const LibExeObjStep = struct {
1744
1744
.kind = kind ,
1745
1745
.root_src = root_src ,
1746
1746
.name = name ,
1747
- .frameworks = BufSet .init (builder .allocator ),
1747
+ .frameworks = StringHashMap ( bool ) .init (builder .allocator ),
1748
1748
.step = Step .init (base_id , name , builder .allocator , make ),
1749
1749
.version = ver ,
1750
1750
.out_filename = undefined ,
@@ -1893,8 +1893,11 @@ pub const LibExeObjStep = struct {
1893
1893
}
1894
1894
1895
1895
pub fn linkFramework (self : * LibExeObjStep , framework_name : []const u8 ) void {
1896
- // Note: No need to dupe because frameworks dupes internally.
1897
- self .frameworks .insert (framework_name ) catch unreachable ;
1896
+ self .frameworks .put (self .builder .dupe (framework_name ), false ) catch unreachable ;
1897
+ }
1898
+
1899
+ pub fn linkFrameworkNeeded (self : * LibExeObjStep , framework_name : []const u8 ) void {
1900
+ self .frameworks .put (self .builder .dupe (framework_name ), true ) catch unreachable ;
1898
1901
}
1899
1902
1900
1903
/// Returns whether the library, executable, or object depends on a particular system library.
@@ -1935,6 +1938,7 @@ pub const LibExeObjStep = struct {
1935
1938
self .link_objects .append (.{
1936
1939
.system_lib = .{
1937
1940
.name = "c" ,
1941
+ .needed = false ,
1938
1942
.use_pkg_config = .no ,
1939
1943
},
1940
1944
}) catch unreachable ;
@@ -1947,6 +1951,7 @@ pub const LibExeObjStep = struct {
1947
1951
self .link_objects .append (.{
1948
1952
.system_lib = .{
1949
1953
.name = "c++" ,
1954
+ .needed = false ,
1950
1955
.use_pkg_config = .no ,
1951
1956
},
1952
1957
}) catch unreachable ;
@@ -1971,6 +1976,19 @@ pub const LibExeObjStep = struct {
1971
1976
self .link_objects .append (.{
1972
1977
.system_lib = .{
1973
1978
.name = self .builder .dupe (name ),
1979
+ .needed = false ,
1980
+ .use_pkg_config = .no ,
1981
+ },
1982
+ }) catch unreachable ;
1983
+ }
1984
+
1985
+ /// This one has no integration with anything, it just puts -needed-lname on the command line.
1986
+ /// Prefer to use `linkSystemLibraryNeeded` instead.
1987
+ pub fn linkSystemLibraryNeededName (self : * LibExeObjStep , name : []const u8 ) void {
1988
+ self .link_objects .append (.{
1989
+ .system_lib = .{
1990
+ .name = self .builder .dupe (name ),
1991
+ .needed = true ,
1974
1992
.use_pkg_config = .no ,
1975
1993
},
1976
1994
}) catch unreachable ;
@@ -1982,6 +2000,19 @@ pub const LibExeObjStep = struct {
1982
2000
self .link_objects .append (.{
1983
2001
.system_lib = .{
1984
2002
.name = self .builder .dupe (lib_name ),
2003
+ .needed = false ,
2004
+ .use_pkg_config = .force ,
2005
+ },
2006
+ }) catch unreachable ;
2007
+ }
2008
+
2009
+ /// This links against a system library, exclusively using pkg-config to find the library.
2010
+ /// Prefer to use `linkSystemLibraryNeeded` instead.
2011
+ pub fn linkSystemLibraryNeededPkgConfigOnly (self : * LibExeObjStep , lib_name : []const u8 ) void {
2012
+ self .link_objects .append (.{
2013
+ .system_lib = .{
2014
+ .name = self .builder .dupe (lib_name ),
2015
+ .needed = true ,
1985
2016
.use_pkg_config = .force ,
1986
2017
},
1987
2018
}) catch unreachable ;
@@ -2084,6 +2115,14 @@ pub const LibExeObjStep = struct {
2084
2115
}
2085
2116
2086
2117
pub fn linkSystemLibrary (self : * LibExeObjStep , name : []const u8 ) void {
2118
+ self .linkSystemLibraryInner (name , false );
2119
+ }
2120
+
2121
+ pub fn linkSystemLibraryNeeded (self : * LibExeObjStep , name : []const u8 ) void {
2122
+ self .linkSystemLibraryInner (name , true );
2123
+ }
2124
+
2125
+ fn linkSystemLibraryInner (self : * LibExeObjStep , name : []const u8 , needed : bool ) void {
2087
2126
if (isLibCLibrary (name )) {
2088
2127
self .linkLibC ();
2089
2128
return ;
@@ -2096,6 +2135,7 @@ pub const LibExeObjStep = struct {
2096
2135
self .link_objects .append (.{
2097
2136
.system_lib = .{
2098
2137
.name = self .builder .dupe (name ),
2138
+ .needed = needed ,
2099
2139
.use_pkg_config = .yes ,
2100
2140
},
2101
2141
}) catch unreachable ;
@@ -2437,7 +2477,7 @@ pub const LibExeObjStep = struct {
2437
2477
if (! other .isDynamicLibrary ()) {
2438
2478
var it = other .frameworks .iterator ();
2439
2479
while (it .next ()) | framework | {
2440
- self .frameworks .insert (framework .* ) catch unreachable ;
2480
+ self .frameworks .put (framework . key_ptr .* , framework . value_ptr .* ) catch unreachable ;
2441
2481
}
2442
2482
}
2443
2483
},
@@ -2473,8 +2513,9 @@ pub const LibExeObjStep = struct {
2473
2513
},
2474
2514
2475
2515
.system_lib = > | system_lib | {
2516
+ const prefix : []const u8 = if (system_lib .needed ) "-needed-l" else "-l" ;
2476
2517
switch (system_lib .use_pkg_config ) {
2477
- .no = > try zig_args .append (builder .fmt ("-l {s}" , .{system_lib .name })),
2518
+ .no = > try zig_args .append (builder .fmt ("{s}{s} " , .{ prefix , system_lib .name })),
2478
2519
.yes , .force = > {
2479
2520
if (self .runPkgConfig (system_lib .name )) | args | {
2480
2521
try zig_args .appendSlice (args );
@@ -2488,7 +2529,10 @@ pub const LibExeObjStep = struct {
2488
2529
.yes = > {
2489
2530
// pkg-config failed, so fall back to linking the library
2490
2531
// by name directly.
2491
- try zig_args .append (builder .fmt ("-l{s}" , .{system_lib .name }));
2532
+ try zig_args .append (builder .fmt ("{s}{s}" , .{
2533
+ prefix ,
2534
+ system_lib .name ,
2535
+ }));
2492
2536
},
2493
2537
.force = > {
2494
2538
panic ("pkg-config failed for library {s}" , .{system_lib .name });
@@ -2972,9 +3016,15 @@ pub const LibExeObjStep = struct {
2972
3016
}
2973
3017
2974
3018
var it = self .frameworks .iterator ();
2975
- while (it .next ()) | framework | {
2976
- zig_args .append ("-framework" ) catch unreachable ;
2977
- zig_args .append (framework .* ) catch unreachable ;
3019
+ while (it .next ()) | entry | {
3020
+ const name = entry .key_ptr .* ;
3021
+ const needed = entry .value_ptr .* ;
3022
+ if (needed ) {
3023
+ zig_args .append ("-needed_framework" ) catch unreachable ;
3024
+ } else {
3025
+ zig_args .append ("-framework" ) catch unreachable ;
3026
+ }
3027
+ zig_args .append (name ) catch unreachable ;
2978
3028
}
2979
3029
} else {
2980
3030
if (self .framework_dirs .items .len > 0 ) {
0 commit comments