@@ -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 ,
@@ -1601,6 +1600,9 @@ pub const LibExeObjStep = struct {
1601
1600
/// and start of `__TEXT,__text` section to a value fitting all paths expanded to MAXPATHLEN.
1602
1601
headerpad_max_install_names : bool = false ,
1603
1602
1603
+ /// (Darwin) Remove dylibs that are unreachable by the entry point or exported symbols.
1604
+ dead_strip_dylibs : bool = false ,
1605
+
1604
1606
/// Position Independent Code
1605
1607
force_pic : ? bool = null ,
1606
1608
@@ -1640,6 +1642,7 @@ pub const LibExeObjStep = struct {
1640
1642
1641
1643
pub const SystemLib = struct {
1642
1644
name : []const u8 ,
1645
+ needed : bool ,
1643
1646
use_pkg_config : enum {
1644
1647
/// Don't use pkg-config, just pass -lfoo where foo is name.
1645
1648
no ,
@@ -1741,7 +1744,7 @@ pub const LibExeObjStep = struct {
1741
1744
.kind = kind ,
1742
1745
.root_src = root_src ,
1743
1746
.name = name ,
1744
- .frameworks = BufSet .init (builder .allocator ),
1747
+ .frameworks = StringHashMap ( bool ) .init (builder .allocator ),
1745
1748
.step = Step .init (base_id , name , builder .allocator , make ),
1746
1749
.version = ver ,
1747
1750
.out_filename = undefined ,
@@ -1890,8 +1893,11 @@ pub const LibExeObjStep = struct {
1890
1893
}
1891
1894
1892
1895
pub fn linkFramework (self : * LibExeObjStep , framework_name : []const u8 ) void {
1893
- // Note: No need to dupe because frameworks dupes internally.
1894
- 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 ;
1895
1901
}
1896
1902
1897
1903
/// Returns whether the library, executable, or object depends on a particular system library.
@@ -1932,6 +1938,7 @@ pub const LibExeObjStep = struct {
1932
1938
self .link_objects .append (.{
1933
1939
.system_lib = .{
1934
1940
.name = "c" ,
1941
+ .needed = false ,
1935
1942
.use_pkg_config = .no ,
1936
1943
},
1937
1944
}) catch unreachable ;
@@ -1944,6 +1951,7 @@ pub const LibExeObjStep = struct {
1944
1951
self .link_objects .append (.{
1945
1952
.system_lib = .{
1946
1953
.name = "c++" ,
1954
+ .needed = false ,
1947
1955
.use_pkg_config = .no ,
1948
1956
},
1949
1957
}) catch unreachable ;
@@ -1968,6 +1976,19 @@ pub const LibExeObjStep = struct {
1968
1976
self .link_objects .append (.{
1969
1977
.system_lib = .{
1970
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 ,
1971
1992
.use_pkg_config = .no ,
1972
1993
},
1973
1994
}) catch unreachable ;
@@ -1979,6 +2000,19 @@ pub const LibExeObjStep = struct {
1979
2000
self .link_objects .append (.{
1980
2001
.system_lib = .{
1981
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 ,
1982
2016
.use_pkg_config = .force ,
1983
2017
},
1984
2018
}) catch unreachable ;
@@ -2081,6 +2115,14 @@ pub const LibExeObjStep = struct {
2081
2115
}
2082
2116
2083
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 {
2084
2126
if (isLibCLibrary (name )) {
2085
2127
self .linkLibC ();
2086
2128
return ;
@@ -2093,6 +2135,7 @@ pub const LibExeObjStep = struct {
2093
2135
self .link_objects .append (.{
2094
2136
.system_lib = .{
2095
2137
.name = self .builder .dupe (name ),
2138
+ .needed = needed ,
2096
2139
.use_pkg_config = .yes ,
2097
2140
},
2098
2141
}) catch unreachable ;
@@ -2434,7 +2477,7 @@ pub const LibExeObjStep = struct {
2434
2477
if (! other .isDynamicLibrary ()) {
2435
2478
var it = other .frameworks .iterator ();
2436
2479
while (it .next ()) | framework | {
2437
- self .frameworks .insert (framework .* ) catch unreachable ;
2480
+ self .frameworks .put (framework . key_ptr .* , framework . value_ptr .* ) catch unreachable ;
2438
2481
}
2439
2482
}
2440
2483
},
@@ -2470,8 +2513,9 @@ pub const LibExeObjStep = struct {
2470
2513
},
2471
2514
2472
2515
.system_lib = > | system_lib | {
2516
+ const prefix : []const u8 = if (system_lib .needed ) "-needed-l" else "-l" ;
2473
2517
switch (system_lib .use_pkg_config ) {
2474
- .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 })),
2475
2519
.yes , .force = > {
2476
2520
if (self .runPkgConfig (system_lib .name )) | args | {
2477
2521
try zig_args .appendSlice (args );
@@ -2485,7 +2529,10 @@ pub const LibExeObjStep = struct {
2485
2529
.yes = > {
2486
2530
// pkg-config failed, so fall back to linking the library
2487
2531
// by name directly.
2488
- 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
+ }));
2489
2536
},
2490
2537
.force = > {
2491
2538
panic ("pkg-config failed for library {s}" , .{system_lib .name });
@@ -2676,6 +2723,9 @@ pub const LibExeObjStep = struct {
2676
2723
if (self .headerpad_max_install_names ) {
2677
2724
try zig_args .append ("-headerpad_max_install_names" );
2678
2725
}
2726
+ if (self .dead_strip_dylibs ) {
2727
+ try zig_args .append ("-dead_strip_dylibs" );
2728
+ }
2679
2729
2680
2730
if (self .bundle_compiler_rt ) | x | {
2681
2731
if (x ) {
@@ -2966,9 +3016,15 @@ pub const LibExeObjStep = struct {
2966
3016
}
2967
3017
2968
3018
var it = self .frameworks .iterator ();
2969
- while (it .next ()) | framework | {
2970
- zig_args .append ("-framework" ) catch unreachable ;
2971
- 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 ;
2972
3028
}
2973
3029
} else {
2974
3030
if (self .framework_dirs .items .len > 0 ) {
0 commit comments