@@ -1058,7 +1058,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
10581058 }
10591059}
10601060
1061- fn link_sanitizers ( sess : & Session , crate_type : CrateType , linker : & mut dyn Linker ) {
1061+ fn add_sanitizer_libraries ( sess : & Session , crate_type : CrateType , linker : & mut dyn Linker ) {
10621062 // On macOS the runtimes are distributed as dylibs which should be linked to
10631063 // both executables and dynamic shared objects. Everywhere else the runtimes
10641064 // are currently distributed as static liraries which should be linked to
@@ -1680,55 +1680,6 @@ fn add_local_crate_metadata_objects(
16801680 }
16811681}
16821682
1683- /// Link native libraries corresponding to the current crate and all libraries corresponding to
1684- /// all its dependency crates.
1685- /// FIXME: Consider combining this with the functions above adding object files for the local crate.
1686- fn link_local_crate_native_libs_and_dependent_crate_libs < ' a , B : ArchiveBuilder < ' a > > (
1687- cmd : & mut dyn Linker ,
1688- sess : & ' a Session ,
1689- crate_type : CrateType ,
1690- codegen_results : & CodegenResults ,
1691- tmpdir : & Path ,
1692- ) {
1693- // Take careful note of the ordering of the arguments we pass to the linker
1694- // here. Linkers will assume that things on the left depend on things to the
1695- // right. Things on the right cannot depend on things on the left. This is
1696- // all formally implemented in terms of resolving symbols (libs on the right
1697- // resolve unknown symbols of libs on the left, but not vice versa).
1698- //
1699- // For this reason, we have organized the arguments we pass to the linker as
1700- // such:
1701- //
1702- // 1. The local object that LLVM just generated
1703- // 2. Local native libraries
1704- // 3. Upstream rust libraries
1705- // 4. Upstream native libraries
1706- //
1707- // The rationale behind this ordering is that those items lower down in the
1708- // list can't depend on items higher up in the list. For example nothing can
1709- // depend on what we just generated (e.g., that'd be a circular dependency).
1710- // Upstream rust libraries are not allowed to depend on our local native
1711- // libraries as that would violate the structure of the DAG, in that
1712- // scenario they are required to link to them as well in a shared fashion.
1713- //
1714- // Note that upstream rust libraries may contain native dependencies as
1715- // well, but they also can't depend on what we just started to add to the
1716- // link line. And finally upstream native libraries can't depend on anything
1717- // in this DAG so far because they're only dylibs and dylibs can only depend
1718- // on other dylibs (e.g., other native deps).
1719- //
1720- // If -Zlink-native-libraries=false is set, then the assumption is that an
1721- // external build system already has the native dependencies defined, and it
1722- // will provide them to the linker itself.
1723- if sess. opts . debugging_opts . link_native_libraries {
1724- add_local_native_libraries ( cmd, sess, codegen_results) ;
1725- }
1726- add_upstream_rust_crates :: < B > ( cmd, sess, codegen_results, crate_type, tmpdir) ;
1727- if sess. opts . debugging_opts . link_native_libraries {
1728- add_upstream_native_libraries ( cmd, sess, codegen_results, crate_type) ;
1729- }
1730- }
1731-
17321683/// Add sysroot and other globally set directories to the directory search list.
17331684fn add_library_search_dirs ( cmd : & mut dyn Linker , sess : & Session , self_contained : bool ) {
17341685 // The default library location, we need this to find the runtime.
@@ -1787,12 +1738,13 @@ fn add_rpath_args(
17871738}
17881739
17891740/// Produce the linker command line containing linker path and arguments.
1790- /// `NO-OPT-OUT` marks the arguments that cannot be removed from the command line
1791- /// by the user without creating a custom target specification.
1792- /// `OBJECT-FILES` specify whether the arguments can add object files.
1793- /// `CUSTOMIZATION-POINT` means that arbitrary arguments defined by the user
1794- /// or by the target spec can be inserted here.
1795- /// `AUDIT-ORDER` - need to figure out whether the option is order-dependent or not.
1741+ ///
1742+ /// When comments in the function say "order-(in)dependent" they mean order-dependence between
1743+ /// options and libraries/object files. For example `--whole-archive` (order-dependent) applies
1744+ /// to specific libraries passed after it, and `-o` (output file, order-independent) applies
1745+ /// to the linking process as a whole.
1746+ /// Order-independent options may still override each other in order-dependent fashion,
1747+ /// e.g `--foo=yes --foo=no` may be equivalent to `--foo=no`.
17961748fn linker_with_args < ' a , B : ArchiveBuilder < ' a > > (
17971749 path : & Path ,
17981750 flavor : LinkerFlavor ,
@@ -1810,16 +1762,151 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
18101762 let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor) ;
18111763 let link_output_kind = link_output_kind ( sess, crate_type) ;
18121764
1813- // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1765+ // ------------ Early order-dependent options ------------
1766+
1767+ // If we're building something like a dynamic library then some platforms
1768+ // need to make sure that all symbols are exported correctly from the
1769+ // dynamic library.
1770+ // Must be passed before any libraries to prevent the symbols to export from being thrown away,
1771+ // at least on some platforms (e.g. windows-gnu).
1772+ cmd. export_symbols ( tmpdir, crate_type) ;
1773+
1774+ // Can be used for adding custom CRT objects or overriding order-dependent options above.
1775+ // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
1776+ // introduce a target spec option for order-independent linker options and migrate built-in
1777+ // specs to it.
18141778 add_pre_link_args ( cmd, sess, flavor) ;
18151779
1816- // NO-OPT-OUT, OBJECT-FILES-NO
1780+ // ------------ Object code and libraries, order-dependent ------------
1781+
1782+ // Pre-link CRT objects.
1783+ add_pre_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1784+
1785+ // Sanitizer libraries.
1786+ add_sanitizer_libraries ( sess, crate_type, cmd) ;
1787+
1788+ // Object code from the current crate.
1789+ // Take careful note of the ordering of the arguments we pass to the linker
1790+ // here. Linkers will assume that things on the left depend on things to the
1791+ // right. Things on the right cannot depend on things on the left. This is
1792+ // all formally implemented in terms of resolving symbols (libs on the right
1793+ // resolve unknown symbols of libs on the left, but not vice versa).
1794+ //
1795+ // For this reason, we have organized the arguments we pass to the linker as
1796+ // such:
1797+ //
1798+ // 1. The local object that LLVM just generated
1799+ // 2. Local native libraries
1800+ // 3. Upstream rust libraries
1801+ // 4. Upstream native libraries
1802+ //
1803+ // The rationale behind this ordering is that those items lower down in the
1804+ // list can't depend on items higher up in the list. For example nothing can
1805+ // depend on what we just generated (e.g., that'd be a circular dependency).
1806+ // Upstream rust libraries are not supposed to depend on our local native
1807+ // libraries as that would violate the structure of the DAG, in that
1808+ // scenario they are required to link to them as well in a shared fashion.
1809+ // (The current implementation still doesn't prevent it though, see the FIXME below.)
1810+ //
1811+ // Note that upstream rust libraries may contain native dependencies as
1812+ // well, but they also can't depend on what we just started to add to the
1813+ // link line. And finally upstream native libraries can't depend on anything
1814+ // in this DAG so far because they can only depend on other native libraries
1815+ // and such dependencies are also required to be specified.
1816+ add_local_crate_regular_objects ( cmd, codegen_results) ;
1817+ add_local_crate_metadata_objects ( cmd, crate_type, codegen_results) ;
1818+ add_local_crate_allocator_objects ( cmd, codegen_results) ;
1819+
1820+ // Avoid linking to dynamic libraries unless they satisfy some undefined symbols
1821+ // at the point at which they are specified on the command line.
1822+ // Must be passed before any (dynamic) libraries to have effect on them.
1823+ // On Solaris-like systems, `-z ignore` acts as both `--as-needed` and `--gc-sections`
1824+ // so it will ignore unreferenced ELF sections from relocatable objects.
1825+ // For that reason, we put this flag after metadata objects as they would otherwise be removed.
1826+ // FIXME: Support more fine-grained dead code removal on Solaris/illumos
1827+ // and move this option back to the top.
1828+ cmd. add_as_needed ( ) ;
1829+
1830+ // FIXME: Move this below to other native libraries
1831+ // (or alternatively link all native libraries after their respective crates).
1832+ // This change is somewhat breaking in practice due to local static libraries being linked
1833+ // as whole-archive (#85144), so removing whole-archive may be a pre-requisite.
1834+ if sess. opts . debugging_opts . link_native_libraries {
1835+ add_local_native_libraries ( cmd, sess, codegen_results) ;
1836+ }
1837+
1838+ // Rust libraries.
1839+ add_upstream_rust_crates :: < B > ( cmd, sess, codegen_results, crate_type, tmpdir) ;
1840+
1841+ // Native libraries linked with `#[link]` attributes at and `-l` command line options.
1842+ // If -Zlink-native-libraries=false is set, then the assumption is that an
1843+ // external build system already has the native dependencies defined, and it
1844+ // will provide them to the linker itself.
1845+ if sess. opts . debugging_opts . link_native_libraries {
1846+ add_upstream_native_libraries ( cmd, sess, codegen_results, crate_type) ;
1847+ }
1848+
1849+ // Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
1850+ // command line shorter, reset it to default here before adding more libraries.
1851+ cmd. reset_per_library_state ( ) ;
1852+
1853+ // FIXME: Built-in target specs occasionally use this for linking system libraries,
1854+ // eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)`
1855+ // and remove the option.
1856+ add_late_link_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1857+
1858+ // ------------ Arbitrary order-independent options ------------
1859+
1860+ // Add order-independent options determined by rustc from its compiler options,
1861+ // target properties and source code.
1862+ add_order_independent_options (
1863+ cmd,
1864+ sess,
1865+ link_output_kind,
1866+ crt_objects_fallback,
1867+ flavor,
1868+ crate_type,
1869+ codegen_results,
1870+ out_filename,
1871+ tmpdir,
1872+ ) ;
1873+
1874+ // Can be used for arbitrary order-independent options.
1875+ // In practice may also be occasionally used for linking native libraries.
1876+ // Passed after compiler-generated options to support manual overriding when necessary.
1877+ add_user_defined_link_args ( cmd, sess) ;
1878+
1879+ // ------------ Object code and libraries, order-dependent ------------
1880+
1881+ // Post-link CRT objects.
1882+ add_post_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1883+
1884+ // ------------ Late order-dependent options ------------
1885+
1886+ // Doesn't really make sense.
1887+ // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
1888+ // introduce a target spec option for order-independent linker options, migrate built-in specs
1889+ // to it and remove the option.
1890+ add_post_link_args ( cmd, sess, flavor) ;
1891+
1892+ cmd. take_cmd ( )
1893+ }
1894+
1895+ fn add_order_independent_options (
1896+ cmd : & mut dyn Linker ,
1897+ sess : & Session ,
1898+ link_output_kind : LinkOutputKind ,
1899+ crt_objects_fallback : bool ,
1900+ flavor : LinkerFlavor ,
1901+ crate_type : CrateType ,
1902+ codegen_results : & CodegenResults ,
1903+ out_filename : & Path ,
1904+ tmpdir : & Path ,
1905+ ) {
18171906 add_apple_sdk ( cmd, sess, flavor) ;
18181907
1819- // NO-OPT-OUT
18201908 add_link_script ( cmd, sess, tmpdir, crate_type) ;
18211909
1822- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18231910 if sess. target . is_like_fuchsia && crate_type == CrateType :: Executable {
18241911 let prefix = if sess. opts . debugging_opts . sanitizer . contains ( SanitizerSet :: ADDRESS ) {
18251912 "asan/"
@@ -1829,36 +1916,17 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
18291916 cmd. arg ( format ! ( "--dynamic-linker={}ld.so.1" , prefix) ) ;
18301917 }
18311918
1832- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18331919 if sess. target . eh_frame_header {
18341920 cmd. add_eh_frame_header ( ) ;
18351921 }
18361922
1837- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18381923 // Make the binary compatible with data execution prevention schemes.
18391924 cmd. add_no_exec ( ) ;
18401925
1841- // OBJECT-FILES-YES
1842- add_local_crate_metadata_objects ( cmd, crate_type, codegen_results) ;
1843-
1844- // NO-OPT-OUT, OBJECT-FILES-NO
1845- // Avoid linking to dynamic libraries unless they satisfy some undefined symbols
1846- // at the point at which they are specified on the command line.
1847- // Must be passed before any dynamic libraries.
1848- // On solaris-like systems, this also will ignore unreferenced ELF sections
1849- // from relocatable objects. For that reason, we move the metadata objects
1850- // to before this flag as they would otherwise be removed.
1851- cmd. add_as_needed ( ) ;
1852-
1853- // NO-OPT-OUT, OBJECT-FILES-NO
18541926 if crt_objects_fallback {
18551927 cmd. no_crt_objects ( ) ;
18561928 }
18571929
1858- // NO-OPT-OUT, OBJECT-FILES-YES
1859- add_pre_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1860-
1861- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18621930 if sess. target . is_like_emscripten {
18631931 cmd. arg ( "-s" ) ;
18641932 cmd. arg ( if sess. panic_strategy ( ) == PanicStrategy :: Abort {
@@ -1868,108 +1936,64 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
18681936 } ) ;
18691937 }
18701938
1871- // OBJECT-FILES-YES, AUDIT-ORDER
1872- link_sanitizers ( sess, crate_type, cmd) ;
1939+ if flavor == LinkerFlavor :: PtxLinker {
1940+ // Provide the linker with fallback to internal `target-cpu`.
1941+ cmd. arg ( "--fallback-arch" ) ;
1942+ cmd. arg ( & codegen_results. linker_info . target_cpu ) ;
1943+ } else if flavor == LinkerFlavor :: BpfLinker {
1944+ cmd. arg ( "--cpu" ) ;
1945+ cmd. arg ( & codegen_results. linker_info . target_cpu ) ;
1946+ cmd. arg ( "--cpu-features" ) ;
1947+ cmd. arg ( match & sess. opts . cg . target_feature {
1948+ feat if !feat. is_empty ( ) => feat,
1949+ _ => & sess. target . options . features ,
1950+ } ) ;
1951+ }
18731952
1874- // OBJECT-FILES-NO, AUDIT-ORDER
1875- // Linker plugins should be specified early in the list of arguments
1876- // FIXME: How "early" exactly?
18771953 cmd. linker_plugin_lto ( ) ;
18781954
1879- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1880- // FIXME: Order-dependent, at least relatively to other args adding searh directories.
18811955 add_library_search_dirs ( cmd, sess, crt_objects_fallback) ;
18821956
1883- // OBJECT-FILES-YES
1884- add_local_crate_regular_objects ( cmd, codegen_results) ;
1885-
1886- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18871957 cmd. output_filename ( out_filename) ;
18881958
1889- // OBJECT-FILES-NO, AUDIT-ORDER
18901959 if crate_type == CrateType :: Executable && sess. target . is_like_windows {
18911960 if let Some ( ref s) = codegen_results. windows_subsystem {
18921961 cmd. subsystem ( s) ;
18931962 }
18941963 }
18951964
1896- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1897- // If we're building something like a dynamic library then some platforms
1898- // need to make sure that all symbols are exported correctly from the
1899- // dynamic library.
1900- cmd. export_symbols ( tmpdir, crate_type) ;
1901-
1902- // OBJECT-FILES-YES
1903- add_local_crate_allocator_objects ( cmd, codegen_results) ;
1904-
1905- // OBJECT-FILES-NO, AUDIT-ORDER
1906- // FIXME: Order dependent, applies to the following objects. Where should it be placed?
19071965 // Try to strip as much out of the generated object by removing unused
19081966 // sections if possible. See more comments in linker.rs
19091967 if !sess. link_dead_code ( ) {
19101968 let keep_metadata = crate_type == CrateType :: Dylib ;
19111969 cmd. gc_sections ( keep_metadata) ;
19121970 }
19131971
1914- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
19151972 cmd. set_output_kind ( link_output_kind, out_filename) ;
19161973
1917- // OBJECT-FILES-NO, AUDIT-ORDER
19181974 add_relro_args ( cmd, sess) ;
19191975
1920- // OBJECT-FILES-NO, AUDIT-ORDER
19211976 // Pass optimization flags down to the linker.
19221977 cmd. optimize ( ) ;
19231978
1924- // OBJECT-FILES-NO, AUDIT-ORDER
19251979 // Pass debuginfo and strip flags down to the linker.
19261980 cmd. debuginfo ( sess. opts . debugging_opts . strip ) ;
19271981
1928- // OBJECT-FILES-NO, AUDIT-ORDER
19291982 // We want to prevent the compiler from accidentally leaking in any system libraries,
19301983 // so by default we tell linkers not to link to any default libraries.
19311984 if !sess. opts . cg . default_linker_libraries && sess. target . no_default_libraries {
19321985 cmd. no_default_libraries ( ) ;
19331986 }
19341987
1935- // OBJECT-FILES-YES
1936- link_local_crate_native_libs_and_dependent_crate_libs :: < B > (
1937- cmd,
1938- sess,
1939- crate_type,
1940- codegen_results,
1941- tmpdir,
1942- ) ;
1943-
1944- // OBJECT-FILES-NO, AUDIT-ORDER
19451988 if sess. opts . cg . profile_generate . enabled ( ) || sess. instrument_coverage ( ) {
19461989 cmd. pgo_gen ( ) ;
19471990 }
19481991
1949- // OBJECT-FILES-NO, AUDIT-ORDER
19501992 if sess. opts . cg . control_flow_guard != CFGuard :: Disabled {
19511993 cmd. control_flow_guard ( ) ;
19521994 }
19531995
1954- // OBJECT-FILES-NO, AUDIT-ORDER
19551996 add_rpath_args ( cmd, sess, codegen_results, out_filename) ;
1956-
1957- // OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1958- add_user_defined_link_args ( cmd, sess) ;
1959-
1960- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1961- cmd. finalize ( ) ;
1962-
1963- // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1964- add_late_link_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1965-
1966- // NO-OPT-OUT, OBJECT-FILES-YES
1967- add_post_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1968-
1969- // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1970- add_post_link_args ( cmd, sess, flavor) ;
1971-
1972- cmd. take_cmd ( )
19731997}
19741998
19751999/// # Native library linking
0 commit comments