@@ -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
@@ -1738,12 +1738,13 @@ fn add_rpath_args(
17381738}
17391739
17401740/// Produce the linker command line containing linker path and arguments.
1741- /// `NO-OPT-OUT` marks the arguments that cannot be removed from the command line
1742- /// by the user without creating a custom target specification.
1743- /// `OBJECT-FILES` specify whether the arguments can add object files.
1744- /// `CUSTOMIZATION-POINT` means that arbitrary arguments defined by the user
1745- /// or by the target spec can be inserted here.
1746- /// `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`.
17471748fn linker_with_args < ' a , B : ArchiveBuilder < ' a > > (
17481749 path : & Path ,
17491750 flavor : LinkerFlavor ,
@@ -1761,16 +1762,138 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
17611762 let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor) ;
17621763 let link_output_kind = link_output_kind ( sess, crate_type) ;
17631764
1764- // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1765+ // ------------ Early order-dependent options ------------
1766+
1767+ // Avoid linking to dynamic libraries unless they satisfy some undefined symbols
1768+ // at the point at which they are specified on the command line.
1769+ // Must be passed before any (dynamic) libraries to have effect on them.
1770+ cmd. add_as_needed ( ) ;
1771+
1772+ // If we're building something like a dynamic library then some platforms
1773+ // need to make sure that all symbols are exported correctly from the
1774+ // dynamic library.
1775+ // Must be passed before any libraries to prevent the symbols to export from being thrown away,
1776+ // at least on some platforms (e.g. windows-gnu).
1777+ cmd. export_symbols ( tmpdir, crate_type) ;
1778+
1779+ // Can be used for adding custom CRT objects or overriding order-dependent options above.
1780+ // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
1781+ // introduce a target spec option for order-independent linker options and migrate built-in
1782+ // specs to it.
17651783 add_pre_link_args ( cmd, sess, flavor) ;
17661784
1767- // NO-OPT-OUT, OBJECT-FILES-NO
1785+ // ------------ Object code and libraries, order-dependent ------------
1786+
1787+ // Pre-link CRT objects.
1788+ add_pre_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1789+
1790+ // Sanitizer libraries.
1791+ add_sanitizer_libraries ( sess, crate_type, cmd) ;
1792+
1793+ // Object code from the current crate.
1794+ // Take careful note of the ordering of the arguments we pass to the linker
1795+ // here. Linkers will assume that things on the left depend on things to the
1796+ // right. Things on the right cannot depend on things on the left. This is
1797+ // all formally implemented in terms of resolving symbols (libs on the right
1798+ // resolve unknown symbols of libs on the left, but not vice versa).
1799+ //
1800+ // For this reason, we have organized the arguments we pass to the linker as
1801+ // such:
1802+ //
1803+ // 1. The local object that LLVM just generated
1804+ // 2. Upstream rust libraries
1805+ // 3. Local native libraries
1806+ // 4. Upstream native libraries
1807+ //
1808+ // The rationale behind this ordering is that those items lower down in the
1809+ // list can't depend on items higher up in the list. For example nothing can
1810+ // depend on what we just generated (e.g., that'd be a circular dependency).
1811+ // Upstream rust libraries are not allowed to depend on our local native
1812+ // libraries as that would violate the structure of the DAG, in that
1813+ // scenario they are required to link to them as well in a shared fashion.
1814+ //
1815+ // Note that upstream rust libraries may contain native dependencies as
1816+ // well, but they also can't depend on what we just started to add to the
1817+ // link line. And finally upstream native libraries can't depend on anything
1818+ // in this DAG so far because they can only depend on other native libraries
1819+ // and such dependencies are also required to be specified.
1820+ add_local_crate_regular_objects ( cmd, codegen_results) ;
1821+ add_local_crate_metadata_objects ( cmd, crate_type, codegen_results) ;
1822+ add_local_crate_allocator_objects ( cmd, codegen_results) ;
1823+
1824+ // Rust libraries.
1825+ add_upstream_rust_crates :: < B > ( cmd, sess, codegen_results, crate_type, tmpdir) ;
1826+
1827+ // Native libraries linked with `#[link]` attributes at and `-l` command line options.
1828+ // If -Zlink-native-libraries=false is set, then the assumption is that an
1829+ // external build system already has the native dependencies defined, and it
1830+ // will provide them to the linker itself.
1831+ if sess. opts . debugging_opts . link_native_libraries {
1832+ add_local_native_libraries ( cmd, sess, codegen_results) ;
1833+ add_upstream_native_libraries ( cmd, sess, codegen_results, crate_type) ;
1834+ }
1835+
1836+ // Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
1837+ // command line shorter, reset it to default here before adding more libraries.
1838+ cmd. reset_per_library_state ( ) ;
1839+
1840+ // FIXME: Built-in target specs occasionally use this for linking system libraries,
1841+ // eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)`
1842+ // and remove the option.
1843+ add_late_link_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1844+
1845+ // ------------ Arbitrary order-independent options ------------
1846+
1847+ // Add order-independent options determined by rustc from its compiler options,
1848+ // target properties and source code.
1849+ add_order_independent_options (
1850+ cmd,
1851+ sess,
1852+ link_output_kind,
1853+ crt_objects_fallback,
1854+ flavor,
1855+ crate_type,
1856+ codegen_results,
1857+ out_filename,
1858+ tmpdir,
1859+ ) ;
1860+
1861+ // Can be used for arbitrary order-independent options.
1862+ // In practice may also be occasionally used for linking native libraries.
1863+ // Passed after compiler-generated options to support manual overriding when necessary.
1864+ add_user_defined_link_args ( cmd, sess) ;
1865+
1866+ // ------------ Object code and libraries, order-dependent ------------
1867+
1868+ // Post-link CRT objects.
1869+ add_post_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1870+
1871+ // ------------ Late order-dependent options ------------
1872+
1873+ // Doesn't really make sense.
1874+ // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
1875+ // introduce a target spec option for order-independent linker options, migrate built-in specs
1876+ // to it and remove the option.
1877+ add_post_link_args ( cmd, sess, flavor) ;
1878+
1879+ cmd. take_cmd ( )
1880+ }
1881+
1882+ fn add_order_independent_options (
1883+ cmd : & mut dyn Linker ,
1884+ sess : & Session ,
1885+ link_output_kind : LinkOutputKind ,
1886+ crt_objects_fallback : bool ,
1887+ flavor : LinkerFlavor ,
1888+ crate_type : CrateType ,
1889+ codegen_results : & CodegenResults ,
1890+ out_filename : & Path ,
1891+ tmpdir : & Path ,
1892+ ) {
17681893 add_apple_sdk ( cmd, sess, flavor) ;
17691894
1770- // NO-OPT-OUT
17711895 add_link_script ( cmd, sess, tmpdir, crate_type) ;
17721896
1773- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
17741897 if sess. target . is_like_fuchsia && crate_type == CrateType :: Executable {
17751898 let prefix = if sess. opts . debugging_opts . sanitizer . contains ( SanitizerSet :: ADDRESS ) {
17761899 "asan/"
@@ -1780,36 +1903,17 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
17801903 cmd. arg ( format ! ( "--dynamic-linker={}ld.so.1" , prefix) ) ;
17811904 }
17821905
1783- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
17841906 if sess. target . eh_frame_header {
17851907 cmd. add_eh_frame_header ( ) ;
17861908 }
17871909
1788- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
17891910 // Make the binary compatible with data execution prevention schemes.
17901911 cmd. add_no_exec ( ) ;
17911912
1792- // OBJECT-FILES-YES
1793- add_local_crate_metadata_objects ( cmd, crate_type, codegen_results) ;
1794-
1795- // NO-OPT-OUT, OBJECT-FILES-NO
1796- // Avoid linking to dynamic libraries unless they satisfy some undefined symbols
1797- // at the point at which they are specified on the command line.
1798- // Must be passed before any dynamic libraries.
1799- // On solaris-like systems, this also will ignore unreferenced ELF sections
1800- // from relocatable objects. For that reason, we move the metadata objects
1801- // to before this flag as they would otherwise be removed.
1802- cmd. add_as_needed ( ) ;
1803-
1804- // NO-OPT-OUT, OBJECT-FILES-NO
18051913 if crt_objects_fallback {
18061914 cmd. no_crt_objects ( ) ;
18071915 }
18081916
1809- // NO-OPT-OUT, OBJECT-FILES-YES
1810- add_pre_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1811-
1812- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18131917 if sess. target . is_like_emscripten {
18141918 cmd. arg ( "-s" ) ;
18151919 cmd. arg ( if sess. panic_strategy ( ) == PanicStrategy :: Abort {
@@ -1819,138 +1923,64 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
18191923 } ) ;
18201924 }
18211925
1822- // OBJECT-FILES-YES, AUDIT-ORDER
1823- link_sanitizers ( sess, crate_type, cmd) ;
1926+ if flavor == LinkerFlavor :: PtxLinker {
1927+ // Provide the linker with fallback to internal `target-cpu`.
1928+ cmd. arg ( "--fallback-arch" ) ;
1929+ cmd. arg ( & codegen_results. linker_info . target_cpu ) ;
1930+ } else if flavor == LinkerFlavor :: BpfLinker {
1931+ cmd. arg ( "--cpu" ) ;
1932+ cmd. arg ( & codegen_results. linker_info . target_cpu ) ;
1933+ cmd. arg ( "--cpu-features" ) ;
1934+ cmd. arg ( match & sess. opts . cg . target_feature {
1935+ feat if !feat. is_empty ( ) => feat,
1936+ _ => & sess. target . options . features ,
1937+ } ) ;
1938+ }
18241939
1825- // OBJECT-FILES-NO, AUDIT-ORDER
1826- // Linker plugins should be specified early in the list of arguments
1827- // FIXME: How "early" exactly?
18281940 cmd. linker_plugin_lto ( ) ;
18291941
1830- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1831- // FIXME: Order-dependent, at least relatively to other args adding searh directories.
18321942 add_library_search_dirs ( cmd, sess, crt_objects_fallback) ;
18331943
1834- // OBJECT-FILES-YES
1835- add_local_crate_regular_objects ( cmd, codegen_results) ;
1836-
1837- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18381944 cmd. output_filename ( out_filename) ;
18391945
1840- // OBJECT-FILES-NO, AUDIT-ORDER
18411946 if crate_type == CrateType :: Executable && sess. target . is_like_windows {
18421947 if let Some ( ref s) = codegen_results. windows_subsystem {
18431948 cmd. subsystem ( s) ;
18441949 }
18451950 }
18461951
1847- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1848- // If we're building something like a dynamic library then some platforms
1849- // need to make sure that all symbols are exported correctly from the
1850- // dynamic library.
1851- cmd. export_symbols ( tmpdir, crate_type) ;
1852-
1853- // OBJECT-FILES-YES
1854- add_local_crate_allocator_objects ( cmd, codegen_results) ;
1855-
1856- // OBJECT-FILES-NO, AUDIT-ORDER
1857- // FIXME: Order dependent, applies to the following objects. Where should it be placed?
18581952 // Try to strip as much out of the generated object by removing unused
18591953 // sections if possible. See more comments in linker.rs
18601954 if !sess. link_dead_code ( ) {
18611955 let keep_metadata = crate_type == CrateType :: Dylib ;
18621956 cmd. gc_sections ( keep_metadata) ;
18631957 }
18641958
1865- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
18661959 cmd. set_output_kind ( link_output_kind, out_filename) ;
18671960
1868- // OBJECT-FILES-NO, AUDIT-ORDER
18691961 add_relro_args ( cmd, sess) ;
18701962
1871- // OBJECT-FILES-NO, AUDIT-ORDER
18721963 // Pass optimization flags down to the linker.
18731964 cmd. optimize ( ) ;
18741965
1875- // OBJECT-FILES-NO, AUDIT-ORDER
18761966 // Pass debuginfo and strip flags down to the linker.
18771967 cmd. debuginfo ( sess. opts . debugging_opts . strip ) ;
18781968
1879- // OBJECT-FILES-NO, AUDIT-ORDER
18801969 // We want to prevent the compiler from accidentally leaking in any system libraries,
18811970 // so by default we tell linkers not to link to any default libraries.
18821971 if !sess. opts . cg . default_linker_libraries && sess. target . no_default_libraries {
18831972 cmd. no_default_libraries ( ) ;
18841973 }
18851974
1886- // OBJECT-FILES-NO, AUDIT-ORDER
1887- // Take careful note of the ordering of the arguments we pass to the linker
1888- // here. Linkers will assume that things on the left depend on things to the
1889- // right. Things on the right cannot depend on things on the left. This is
1890- // all formally implemented in terms of resolving symbols (libs on the right
1891- // resolve unknown symbols of libs on the left, but not vice versa).
1892- //
1893- // For this reason, we have organized the arguments we pass to the linker as
1894- // such:
1895- //
1896- // 1. The local object that LLVM just generated
1897- // 2. Local native libraries
1898- // 3. Upstream rust libraries
1899- // 4. Upstream native libraries
1900- //
1901- // The rationale behind this ordering is that those items lower down in the
1902- // list can't depend on items higher up in the list. For example nothing can
1903- // depend on what we just generated (e.g., that'd be a circular dependency).
1904- // Upstream rust libraries are not allowed to depend on our local native
1905- // libraries as that would violate the structure of the DAG, in that
1906- // scenario they are required to link to them as well in a shared fashion.
1907- //
1908- // Note that upstream rust libraries may contain native dependencies as
1909- // well, but they also can't depend on what we just started to add to the
1910- // link line. And finally upstream native libraries can't depend on anything
1911- // in this DAG so far because they're only dylibs and dylibs can only depend
1912- // on other dylibs (e.g., other native deps).
1913- //
1914- // If -Zlink-native-libraries=false is set, then the assumption is that an
1915- // external build system already has the native dependencies defined, and it
1916- // will provide them to the linker itself.
1917- if sess. opts . debugging_opts . link_native_libraries {
1918- add_local_native_libraries ( cmd, sess, codegen_results) ;
1919- }
1920- add_upstream_rust_crates :: < B > ( cmd, sess, codegen_results, crate_type, tmpdir) ;
1921- if sess. opts . debugging_opts . link_native_libraries {
1922- add_upstream_native_libraries ( cmd, sess, codegen_results, crate_type) ;
1923- }
1924-
1925- // OBJECT-FILES-NO, AUDIT-ORDER
19261975 if sess. opts . cg . profile_generate . enabled ( ) || sess. instrument_coverage ( ) {
19271976 cmd. pgo_gen ( ) ;
19281977 }
19291978
1930- // OBJECT-FILES-NO, AUDIT-ORDER
19311979 if sess. opts . cg . control_flow_guard != CFGuard :: Disabled {
19321980 cmd. control_flow_guard ( ) ;
19331981 }
19341982
1935- // OBJECT-FILES-NO, AUDIT-ORDER
19361983 add_rpath_args ( cmd, sess, codegen_results, out_filename) ;
1937-
1938- // OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1939- add_user_defined_link_args ( cmd, sess) ;
1940-
1941- // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1942- cmd. finalize ( ) ;
1943-
1944- // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1945- add_late_link_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1946-
1947- // NO-OPT-OUT, OBJECT-FILES-YES
1948- add_post_link_objects ( cmd, sess, link_output_kind, crt_objects_fallback) ;
1949-
1950- // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1951- add_post_link_args ( cmd, sess, flavor) ;
1952-
1953- cmd. take_cmd ( )
19541984}
19551985
19561986/// # Native library linking
0 commit comments