authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-01 23:14:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-08-03 09:52:14-07:00
loge565ff305ae208b15058a462d348fde515b3e950
tree31fd4344027677cf9c854d610c1b6ee9eeae4c44
parent9e50f960875601dbaaf7245cedb7d9e429678aeb

CLI: revert -l behavior

chicken out and make -l match the status quo behavior, where it looks for dynamic libraries and then falls back to static libraries. library resolution is still done in the CLI now though, and these options are added: -search_static_first Search for static libs in all library search paths, then dynamic libs. -search_dylibs_only Only search for dynamic libs. -search_static_only Only search for static libs. this matches the already existing options below: -search_paths_first For each library search path, check for dynamic lib then static lib before proceeding to next path. -search_dylibs_first Search for dynamic libs in all library search So, it is still possible to get the strict behavior by passing `-search_dylibs_only` or `-search_static_only`. This commit also makes -dynamic and -static affect the preferred link mode and search strategy.

2 files changed, 102 insertions(+), 58 deletions(-)

cmake/Findllvm.cmake+57-21
...@@ -52,8 +52,6 @@ if(ZIG_USE_LLVM_CONFIG)...@@ -52,8 +52,6 @@ if(ZIG_USE_LLVM_CONFIG)
52 set(STATIC_OR_SHARED_LINK "--link-shared")52 set(STATIC_OR_SHARED_LINK "--link-shared")
53 elseif (ZIG_STATIC_LLVM)53 elseif (ZIG_STATIC_LLVM)
54 set(STATIC_OR_SHARED_LINK "--link-static")54 set(STATIC_OR_SHARED_LINK "--link-static")
55 else()
56 set(STATIC_OR_SHARED_LINK "")
57 endif()55 endif()
5856
59 execute_process(57 execute_process(
...@@ -105,31 +103,69 @@ if(ZIG_USE_LLVM_CONFIG)...@@ -105,31 +103,69 @@ if(ZIG_USE_LLVM_CONFIG)
105 break()103 break()
106 endwhile()104 endwhile()
107105
106 if(ZIG_SHARED_LLVM OR ZIG_STATIC_LLVM)
107 execute_process(
108 COMMAND ${LLVM_CONFIG_EXE} --libfiles ${STATIC_OR_SHARED_LINK}
109 OUTPUT_VARIABLE LLVM_LIBRARIES_SPACES
110 OUTPUT_STRIP_TRAILING_WHITESPACE)
111 string(REPLACE " " ";" LLVM_LIBRARIES "${LLVM_LIBRARIES_SPACES}")
108112
109 execute_process(113 execute_process(
110 COMMAND ${LLVM_CONFIG_EXE} --shared-mode ${STATIC_OR_SHARED_LINK}114 COMMAND ${LLVM_CONFIG_EXE} --libdir ${STATIC_OR_SHARED_LINK}
111 OUTPUT_VARIABLE LLVM_LINK_MODE115 OUTPUT_VARIABLE LLVM_LIBDIRS_SPACES
112 OUTPUT_STRIP_TRAILING_WHITESPACE)116 OUTPUT_STRIP_TRAILING_WHITESPACE)
117 string(REPLACE " " ";" LLVM_LIBDIRS "${LLVM_LIBDIRS_SPACES}")
113118
114 execute_process(119 execute_process(
115 COMMAND ${LLVM_CONFIG_EXE} --libfiles ${STATIC_OR_SHARED_LINK}120 COMMAND ${LLVM_CONFIG_EXE} --system-libs ${STATIC_OR_SHARED_LINK}
116 OUTPUT_VARIABLE LLVM_LIBRARIES_SPACES121 OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_SPACES
117 OUTPUT_STRIP_TRAILING_WHITESPACE)122 OUTPUT_STRIP_TRAILING_WHITESPACE)
118 string(REPLACE " " ";" LLVM_LIBRARIES "${LLVM_LIBRARIES_SPACES}")123 string(REPLACE " " ";" LLVM_SYSTEM_LIBS "${LLVM_SYSTEM_LIBS_SPACES}")
119124
120 execute_process(125 execute_process(
121 COMMAND ${LLVM_CONFIG_EXE} --libdir ${STATIC_OR_SHARED_LINK}126 COMMAND ${LLVM_CONFIG_EXE} --shared-mode ${STATIC_OR_SHARED_LINK}
122 OUTPUT_VARIABLE LLVM_LIBDIRS_SPACES127 OUTPUT_VARIABLE LLVM_LINK_MODE
123 OUTPUT_STRIP_TRAILING_WHITESPACE)128 OUTPUT_STRIP_TRAILING_WHITESPACE)
124 string(REPLACE " " ";" LLVM_LIBDIRS "${LLVM_LIBDIRS_SPACES}")129 else()
130 execute_process(
131 COMMAND ${LLVM_CONFIG_EXE} --libs
132 OUTPUT_VARIABLE LLVM_LIBRARIES_SPACES
133 OUTPUT_STRIP_TRAILING_WHITESPACE)
134 string(REPLACE " " ";" LLVM_LIBRARIES "${LLVM_LIBRARIES_SPACES}")
125135
126 execute_process(136 execute_process(
127 COMMAND ${LLVM_CONFIG_EXE} --system-libs ${STATIC_OR_SHARED_LINK}137 COMMAND ${LLVM_CONFIG_EXE} --libdir
128 OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_SPACES138 OUTPUT_VARIABLE LLVM_LIBDIRS_SPACES
139 OUTPUT_STRIP_TRAILING_WHITESPACE)
140 string(REPLACE " " ";" LLVM_LIBDIRS "${LLVM_LIBDIRS_SPACES}")
141
142 execute_process(
143 COMMAND ${LLVM_CONFIG_EXE} --system-libs
144 OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_SPACES
145 OUTPUT_STRIP_TRAILING_WHITESPACE)
146 string(REPLACE " " ";" LLVM_SYSTEM_LIBS "${LLVM_SYSTEM_LIBS_SPACES}")
147
148 execute_process(
149 COMMAND ${LLVM_CONFIG_EXE} --shared-mode
150 OUTPUT_VARIABLE LLVM_LINK_MODE
129 OUTPUT_STRIP_TRAILING_WHITESPACE)151 OUTPUT_STRIP_TRAILING_WHITESPACE)
130 string(REPLACE " " ";" LLVM_SYSTEM_LIBS "${LLVM_SYSTEM_LIBS_SPACES}")152 endif()
153
154 if (${LLVM_LINK_MODE} STREQUAL "shared")
155 # We always ask for the system libs corresponding to static linking,
156 # since on some distros LLD is only available as a static library
157 # and we need these libraries to link it successfully
158 execute_process(
159 COMMAND ${LLVM_CONFIG_EXE} --system-libs --link-static
160 OUTPUT_VARIABLE LLVM_STATIC_SYSTEM_LIBS_SPACES
161 ERROR_QUIET # Some installations have no static libs, we just ignore the failure
162 OUTPUT_STRIP_TRAILING_WHITESPACE)
163 string(REPLACE " " ";" LLVM_STATIC_SYSTEM_LIBS "${LLVM_STATIC_SYSTEM_LIBS_SPACES}")
131164
132 set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS})165 set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS} ${LLVM_STATIC_SYSTEM_LIBS})
166 else()
167 set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS})
168 endif()
133169
134 execute_process(170 execute_process(
135 COMMAND ${LLVM_CONFIG_EXE} --includedir171 COMMAND ${LLVM_CONFIG_EXE} --includedir
...@@ -337,4 +373,4 @@ endif()...@@ -337,4 +373,4 @@ endif()
337include(FindPackageHandleStandardArgs)373include(FindPackageHandleStandardArgs)
338find_package_handle_standard_args(llvm DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIRS)374find_package_handle_standard_args(llvm DEFAULT_MSG LLVM_LIBRARIES LLVM_INCLUDE_DIRS)
339375
340mark_as_advanced(LLVM_INCLUDE_DIRS LLVM_LIBRARIES LLVM_LIBDIRS LLVM_LINK_MODE)376mark_as_advanced(LLVM_INCLUDE_DIRS LLVM_LIBRARIES LLVM_LIBDIRS)
src/main.zig+45-37
...@@ -482,6 +482,10 @@ const usage_build_generic =...@@ -482,6 +482,10 @@ const usage_build_generic =
482 \\ lib then static lib before proceeding to next path.482 \\ lib then static lib before proceeding to next path.
483 \\ -search_dylibs_first Search for dynamic libs in all library search483 \\ -search_dylibs_first Search for dynamic libs in all library search
484 \\ paths, then static libs.484 \\ paths, then static libs.
485 \\ -search_static_first Search for static libs in all library search
486 \\ paths, then dynamic libs.
487 \\ -search_dylibs_only Only search for dynamic libs.
488 \\ -search_static_only Only search for static libs.
485 \\ -T[script], --script [script] Use a custom linker script489 \\ -T[script], --script [script] Use a custom linker script
486 \\ --version-script [path] Provide a version .map file490 \\ --version-script [path] Provide a version .map file
487 \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)491 \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
...@@ -878,8 +882,8 @@ fn buildOutputType(...@@ -878,8 +882,8 @@ fn buildOutputType(
878 var hash_style: link.HashStyle = .both;882 var hash_style: link.HashStyle = .both;
879 var entitlements: ?[]const u8 = null;883 var entitlements: ?[]const u8 = null;
880 var pagezero_size: ?u64 = null;884 var pagezero_size: ?u64 = null;
881 var lib_search_strategy: ?SystemLib.SearchStrategy = null;885 var lib_search_strategy: SystemLib.SearchStrategy = .paths_first;
882 var lib_preferred_mode: ?std.builtin.LinkMode = null;886 var lib_preferred_mode: std.builtin.LinkMode = .Dynamic;
883 var headerpad_size: ?u32 = null;887 var headerpad_size: ?u32 = null;
884 var headerpad_max_install_names: bool = false;888 var headerpad_max_install_names: bool = false;
885 var dead_strip_dylibs: bool = false;889 var dead_strip_dylibs: bool = false;
...@@ -1111,6 +1115,15 @@ fn buildOutputType(...@@ -1111,6 +1115,15 @@ fn buildOutputType(
1111 } else if (mem.eql(u8, arg, "-search_dylibs_first")) {1115 } else if (mem.eql(u8, arg, "-search_dylibs_first")) {
1112 lib_search_strategy = .mode_first;1116 lib_search_strategy = .mode_first;
1113 lib_preferred_mode = .Dynamic;1117 lib_preferred_mode = .Dynamic;
1118 } else if (mem.eql(u8, arg, "-search_static_first")) {
1119 lib_search_strategy = .mode_first;
1120 lib_preferred_mode = .Static;
1121 } else if (mem.eql(u8, arg, "-search_dylibs_only")) {
1122 lib_search_strategy = .no_fallback;
1123 lib_preferred_mode = .Dynamic;
1124 } else if (mem.eql(u8, arg, "-search_static_only")) {
1125 lib_search_strategy = .no_fallback;
1126 lib_preferred_mode = .Static;
1114 } else if (mem.eql(u8, arg, "-headerpad")) {1127 } else if (mem.eql(u8, arg, "-headerpad")) {
1115 const next_arg = args_iter.nextOrFatal();1128 const next_arg = args_iter.nextOrFatal();
1116 headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| {1129 headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| {
...@@ -1136,8 +1149,8 @@ fn buildOutputType(...@@ -1136,8 +1149,8 @@ fn buildOutputType(
1136 // -l always dynamic links. For static libraries,1149 // -l always dynamic links. For static libraries,
1137 // users are expected to use positional arguments1150 // users are expected to use positional arguments
1138 // which are always unambiguous.1151 // which are always unambiguous.
1139 .preferred_mode = lib_preferred_mode orelse .Dynamic,1152 .preferred_mode = lib_preferred_mode,
1140 .search_strategy = lib_search_strategy orelse .no_fallback,1153 .search_strategy = lib_search_strategy,
1141 });1154 });
1142 } else if (mem.eql(u8, arg, "--needed-library") or1155 } else if (mem.eql(u8, arg, "--needed-library") or
1143 mem.eql(u8, arg, "-needed-l") or1156 mem.eql(u8, arg, "-needed-l") or
...@@ -1147,15 +1160,15 @@ fn buildOutputType(...@@ -1147,15 +1160,15 @@ fn buildOutputType(
1147 try system_libs.put(next_arg, .{1160 try system_libs.put(next_arg, .{
1148 .needed = true,1161 .needed = true,
1149 .weak = false,1162 .weak = false,
1150 .preferred_mode = lib_preferred_mode orelse .Dynamic,1163 .preferred_mode = lib_preferred_mode,
1151 .search_strategy = lib_search_strategy orelse .no_fallback,1164 .search_strategy = lib_search_strategy,
1152 });1165 });
1153 } else if (mem.eql(u8, arg, "-weak_library") or mem.eql(u8, arg, "-weak-l")) {1166 } else if (mem.eql(u8, arg, "-weak_library") or mem.eql(u8, arg, "-weak-l")) {
1154 try system_libs.put(args_iter.nextOrFatal(), .{1167 try system_libs.put(args_iter.nextOrFatal(), .{
1155 .needed = false,1168 .needed = false,
1156 .weak = true,1169 .weak = true,
1157 .preferred_mode = lib_preferred_mode orelse .Dynamic,1170 .preferred_mode = lib_preferred_mode,
1158 .search_strategy = lib_search_strategy orelse .no_fallback,1171 .search_strategy = lib_search_strategy,
1159 });1172 });
1160 } else if (mem.eql(u8, arg, "-D")) {1173 } else if (mem.eql(u8, arg, "-D")) {
1161 try clang_argv.append(arg);1174 try clang_argv.append(arg);
...@@ -1388,8 +1401,12 @@ fn buildOutputType(...@@ -1388,8 +1401,12 @@ fn buildOutputType(
1388 emit_implib_arg_provided = true;1401 emit_implib_arg_provided = true;
1389 } else if (mem.eql(u8, arg, "-dynamic")) {1402 } else if (mem.eql(u8, arg, "-dynamic")) {
1390 link_mode = .Dynamic;1403 link_mode = .Dynamic;
1404 lib_preferred_mode = .Dynamic;
1405 lib_search_strategy = .mode_first;
1391 } else if (mem.eql(u8, arg, "-static")) {1406 } else if (mem.eql(u8, arg, "-static")) {
1392 link_mode = .Static;1407 link_mode = .Static;
1408 lib_preferred_mode = .Static;
1409 lib_search_strategy = .no_fallback;
1393 } else if (mem.eql(u8, arg, "-fdll-export-fns")) {1410 } else if (mem.eql(u8, arg, "-fdll-export-fns")) {
1394 dll_export_fns = true;1411 dll_export_fns = true;
1395 } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) {1412 } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) {
...@@ -1541,22 +1558,22 @@ fn buildOutputType(...@@ -1541,22 +1558,22 @@ fn buildOutputType(
1541 // -l always dynamic links. For static libraries,1558 // -l always dynamic links. For static libraries,
1542 // users are expected to use positional arguments1559 // users are expected to use positional arguments
1543 // which are always unambiguous.1560 // which are always unambiguous.
1544 .preferred_mode = lib_preferred_mode orelse .Dynamic,1561 .preferred_mode = lib_preferred_mode,
1545 .search_strategy = lib_search_strategy orelse .no_fallback,1562 .search_strategy = lib_search_strategy,
1546 });1563 });
1547 } else if (mem.startsWith(u8, arg, "-needed-l")) {1564 } else if (mem.startsWith(u8, arg, "-needed-l")) {
1548 try system_libs.put(arg["-needed-l".len..], .{1565 try system_libs.put(arg["-needed-l".len..], .{
1549 .needed = true,1566 .needed = true,
1550 .weak = false,1567 .weak = false,
1551 .preferred_mode = lib_preferred_mode orelse .Dynamic,1568 .preferred_mode = lib_preferred_mode,
1552 .search_strategy = lib_search_strategy orelse .no_fallback,1569 .search_strategy = lib_search_strategy,
1553 });1570 });
1554 } else if (mem.startsWith(u8, arg, "-weak-l")) {1571 } else if (mem.startsWith(u8, arg, "-weak-l")) {
1555 try system_libs.put(arg["-weak-l".len..], .{1572 try system_libs.put(arg["-weak-l".len..], .{
1556 .needed = false,1573 .needed = false,
1557 .weak = true,1574 .weak = true,
1558 .preferred_mode = lib_preferred_mode orelse .Dynamic,1575 .preferred_mode = lib_preferred_mode,
1559 .search_strategy = lib_search_strategy orelse .no_fallback,1576 .search_strategy = lib_search_strategy,
1560 });1577 });
1561 } else if (mem.startsWith(u8, arg, "-D")) {1578 } else if (mem.startsWith(u8, arg, "-D")) {
1562 try clang_argv.append(arg);1579 try clang_argv.append(arg);
...@@ -1632,7 +1649,6 @@ fn buildOutputType(...@@ -1632,7 +1649,6 @@ fn buildOutputType(
1632 var emit_llvm = false;1649 var emit_llvm = false;
1633 var needed = false;1650 var needed = false;
1634 var must_link = false;1651 var must_link = false;
1635 var force_static_libs = false;
1636 var file_ext: ?Compilation.FileExt = null;1652 var file_ext: ?Compilation.FileExt = null;
1637 while (it.has_next) {1653 while (it.has_next) {
1638 it.next() catch |err| {1654 it.next() catch |err| {
...@@ -1702,22 +1718,12 @@ fn buildOutputType(...@@ -1702,22 +1718,12 @@ fn buildOutputType(
1702 .must_link = must_link,1718 .must_link = must_link,
1703 .loption = true,1719 .loption = true,
1704 });1720 });
1705 } else if (force_static_libs) {
1706 try system_libs.put(it.only_arg, .{
1707 .needed = false,
1708 .weak = false,
1709 .preferred_mode = .Static,
1710 .search_strategy = .no_fallback,
1711 });
1712 } else {1721 } else {
1713 // C compilers are traditionally expected to look
1714 // first for dynamic libraries and then fall back
1715 // to static libraries.
1716 try system_libs.put(it.only_arg, .{1722 try system_libs.put(it.only_arg, .{
1717 .needed = needed,1723 .needed = needed,
1718 .weak = false,1724 .weak = false,
1719 .preferred_mode = lib_preferred_mode orelse .Dynamic,1725 .preferred_mode = lib_preferred_mode,
1720 .search_strategy = lib_search_strategy orelse .paths_first,1726 .search_strategy = lib_search_strategy,
1721 });1727 });
1722 }1728 }
1723 },1729 },
...@@ -1814,13 +1820,15 @@ fn buildOutputType(...@@ -1814,13 +1820,15 @@ fn buildOutputType(
1814 mem.eql(u8, linker_arg, "-dy") or1820 mem.eql(u8, linker_arg, "-dy") or
1815 mem.eql(u8, linker_arg, "-call_shared"))1821 mem.eql(u8, linker_arg, "-call_shared"))
1816 {1822 {
1817 force_static_libs = false;1823 lib_search_strategy = .no_fallback;
1824 lib_preferred_mode = .Dynamic;
1818 } else if (mem.eql(u8, linker_arg, "-Bstatic") or1825 } else if (mem.eql(u8, linker_arg, "-Bstatic") or
1819 mem.eql(u8, linker_arg, "-dn") or1826 mem.eql(u8, linker_arg, "-dn") or
1820 mem.eql(u8, linker_arg, "-non_shared") or1827 mem.eql(u8, linker_arg, "-non_shared") or
1821 mem.eql(u8, linker_arg, "-static"))1828 mem.eql(u8, linker_arg, "-static"))
1822 {1829 {
1823 force_static_libs = true;1830 lib_search_strategy = .no_fallback;
1831 lib_preferred_mode = .Static;
1824 } else if (mem.eql(u8, linker_arg, "-search_paths_first")) {1832 } else if (mem.eql(u8, linker_arg, "-search_paths_first")) {
1825 lib_search_strategy = .paths_first;1833 lib_search_strategy = .paths_first;
1826 lib_preferred_mode = .Dynamic;1834 lib_preferred_mode = .Dynamic;
...@@ -1939,8 +1947,8 @@ fn buildOutputType(...@@ -1939,8 +1947,8 @@ fn buildOutputType(
1939 .weak_library => try system_libs.put(it.only_arg, .{1947 .weak_library => try system_libs.put(it.only_arg, .{
1940 .needed = false,1948 .needed = false,
1941 .weak = true,1949 .weak = true,
1942 .preferred_mode = lib_preferred_mode orelse .Dynamic,1950 .preferred_mode = lib_preferred_mode,
1943 .search_strategy = lib_search_strategy orelse .paths_first,1951 .search_strategy = lib_search_strategy,
1944 }),1952 }),
1945 .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }),1953 .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }),
1946 .headerpad_max_install_names => headerpad_max_install_names = true,1954 .headerpad_max_install_names => headerpad_max_install_names = true,
...@@ -2240,22 +2248,22 @@ fn buildOutputType(...@@ -2240,22 +2248,22 @@ fn buildOutputType(
2240 try system_libs.put(linker_args_it.nextOrFatal(), .{2248 try system_libs.put(linker_args_it.nextOrFatal(), .{
2241 .weak = false,2249 .weak = false,
2242 .needed = true,2250 .needed = true,
2243 .preferred_mode = lib_preferred_mode orelse .Dynamic,2251 .preferred_mode = lib_preferred_mode,
2244 .search_strategy = lib_search_strategy orelse .paths_first,2252 .search_strategy = lib_search_strategy,
2245 });2253 });
2246 } else if (mem.startsWith(u8, arg, "-weak-l")) {2254 } else if (mem.startsWith(u8, arg, "-weak-l")) {
2247 try system_libs.put(arg["-weak-l".len..], .{2255 try system_libs.put(arg["-weak-l".len..], .{
2248 .weak = true,2256 .weak = true,
2249 .needed = false,2257 .needed = false,
2250 .preferred_mode = lib_preferred_mode orelse .Dynamic,2258 .preferred_mode = lib_preferred_mode,
2251 .search_strategy = lib_search_strategy orelse .paths_first,2259 .search_strategy = lib_search_strategy,
2252 });2260 });
2253 } else if (mem.eql(u8, arg, "-weak_library")) {2261 } else if (mem.eql(u8, arg, "-weak_library")) {
2254 try system_libs.put(linker_args_it.nextOrFatal(), .{2262 try system_libs.put(linker_args_it.nextOrFatal(), .{
2255 .weak = true,2263 .weak = true,
2256 .needed = false,2264 .needed = false,
2257 .preferred_mode = lib_preferred_mode orelse .Dynamic,2265 .preferred_mode = lib_preferred_mode,
2258 .search_strategy = lib_search_strategy orelse .paths_first,2266 .search_strategy = lib_search_strategy,
2259 });2267 });
2260 } else if (mem.eql(u8, arg, "-compatibility_version")) {2268 } else if (mem.eql(u8, arg, "-compatibility_version")) {
2261 const compat_version = linker_args_it.nextOrFatal();2269 const compat_version = linker_args_it.nextOrFatal();