@@ -5,8 +5,8 @@ use std::path::{Path, PathBuf};
55use std:: sync:: { Arc , LazyLock , OnceLock } ;
66use std:: { env, fs, iter} ;
77
8- use rustc_ast as ast;
9- use rustc_attr_parsing:: { AttributeParser , ShouldEmit } ;
8+ use rustc_ast:: { self as ast, NodeId } ;
9+ use rustc_attr_parsing:: { AttributeParser , Early , ShouldEmit } ;
1010use rustc_codegen_ssa:: traits:: CodegenBackend ;
1111use rustc_codegen_ssa:: { CodegenResults , CrateInfo } ;
1212use rustc_data_structures:: jobserver:: Proxy ;
@@ -17,6 +17,7 @@ use rustc_errors::timings::TimingSection;
1717use rustc_expand:: base:: { ExtCtxt , LintStoreExpand } ;
1818use rustc_feature:: Features ;
1919use rustc_fs_util:: try_canonicalize;
20+ use rustc_hir:: Attribute ;
2021use rustc_hir:: attrs:: AttributeKind ;
2122use rustc_hir:: def_id:: { LOCAL_CRATE , StableCrateId , StableCrateIdMap } ;
2223use rustc_hir:: definitions:: Definitions ;
@@ -35,7 +36,7 @@ use rustc_resolve::{Resolver, ResolverOutputs};
3536use rustc_session:: Session ;
3637use rustc_session:: config:: { CrateType , Input , OutFileName , OutputFilenames , OutputType } ;
3738use rustc_session:: cstore:: Untracked ;
38- use rustc_session:: output:: { collect_crate_types , filename_for_input } ;
39+ use rustc_session:: output:: { filename_for_input , invalid_output_for_target } ;
3940use rustc_session:: parse:: feature_err;
4041use rustc_session:: search_paths:: PathKind ;
4142use rustc_span:: {
@@ -1345,6 +1346,92 @@ pub(crate) fn parse_crate_name(
13451346 Some ( ( name, name_span) )
13461347}
13471348
1349+ pub fn collect_crate_types (
1350+ session : & Session ,
1351+ backend_crate_types : & [ CrateType ] ,
1352+ codegen_backend_name : & ' static str ,
1353+ attrs : & [ ast:: Attribute ] ,
1354+ ) -> Vec < CrateType > {
1355+ // If we're generating a test executable, then ignore all other output
1356+ // styles at all other locations
1357+ if session. opts . test {
1358+ if !session. target . executables {
1359+ session. dcx ( ) . emit_warn ( errors:: UnsupportedCrateTypeForTarget {
1360+ crate_type : CrateType :: Executable ,
1361+ target_triple : & session. opts . target_triple ,
1362+ } ) ;
1363+ return Vec :: new ( ) ;
1364+ }
1365+ return vec ! [ CrateType :: Executable ] ;
1366+ }
1367+
1368+ // Shadow `sdylib` crate type in interface build.
1369+ if session. opts . unstable_opts . build_sdylib_interface {
1370+ return vec ! [ CrateType :: Rlib ] ;
1371+ }
1372+
1373+ // Only check command line flags if present. If no types are specified by
1374+ // command line, then reuse the empty `base` Vec to hold the types that
1375+ // will be found in crate attributes.
1376+ // JUSTIFICATION: before wrapper fn is available
1377+ #[ allow( rustc:: bad_opt_access) ]
1378+ let mut base = session. opts . crate_types . clone ( ) ;
1379+ if base. is_empty ( ) {
1380+ if let Some ( Attribute :: Parsed ( AttributeKind :: CrateType ( crate_type) ) ) =
1381+ AttributeParser :: < Early > :: parse_limited (
1382+ session,
1383+ attrs,
1384+ sym:: crate_type,
1385+ rustc_span:: DUMMY_SP ,
1386+ NodeId :: ZERO ,
1387+ None ,
1388+ )
1389+ {
1390+ base. extend ( crate_type) ;
1391+ }
1392+
1393+ if base. is_empty ( ) {
1394+ base. push ( default_output_for_target ( session) ) ;
1395+ } else {
1396+ base. sort ( ) ;
1397+ base. dedup ( ) ;
1398+ }
1399+ }
1400+
1401+ base. retain ( |crate_type| {
1402+ if invalid_output_for_target ( session, * crate_type) {
1403+ session. dcx ( ) . emit_warn ( errors:: UnsupportedCrateTypeForTarget {
1404+ crate_type : * crate_type,
1405+ target_triple : & session. opts . target_triple ,
1406+ } ) ;
1407+ false
1408+ } else if !backend_crate_types. contains ( crate_type) {
1409+ session. dcx ( ) . emit_warn ( errors:: UnsupportedCrateTypeForCodegenBackend {
1410+ crate_type : * crate_type,
1411+ codegen_backend : codegen_backend_name,
1412+ } ) ;
1413+ false
1414+ } else {
1415+ true
1416+ }
1417+ } ) ;
1418+
1419+ base
1420+ }
1421+
1422+ /// Returns default crate type for target
1423+ ///
1424+ /// Default crate type is used when crate type isn't provided neither
1425+ /// through cmd line arguments nor through crate attributes
1426+ ///
1427+ /// It is CrateType::Executable for all platforms but iOS as there is no
1428+ /// way to run iOS binaries anyway without jailbreaking and
1429+ /// interaction with Rust code through static library is the only
1430+ /// option for now
1431+ fn default_output_for_target ( sess : & Session ) -> CrateType {
1432+ if !sess. target . executables { CrateType :: StaticLib } else { CrateType :: Executable }
1433+ }
1434+
13481435fn get_recursion_limit ( krate_attrs : & [ ast:: Attribute ] , sess : & Session ) -> Limit {
13491436 let attr = AttributeParser :: parse_limited_should_emit (
13501437 sess,
0 commit comments