@@ -102,28 +102,27 @@ fn build_pc_files(
102
102
103
103
fn patch_target (
104
104
pkg : & mut Package ,
105
- libkinds : & [ & str ] ,
105
+ library_types : LibraryTypes ,
106
106
capi_config : & CApiConfig ,
107
107
) -> anyhow:: Result < ( ) > {
108
108
use cargo:: core:: compiler:: CrateType ;
109
109
110
110
let manifest = pkg. manifest_mut ( ) ;
111
111
let targets = manifest. targets_mut ( ) ;
112
112
113
- let kinds: Vec < _ > = libkinds
114
- . iter ( )
115
- . map ( |& kind| match kind {
116
- "staticlib" => CrateType :: Staticlib ,
117
- "cdylib" => CrateType :: Cdylib ,
118
- _ => unreachable ! ( ) ,
119
- } )
120
- . collect ( ) ;
113
+ let mut kinds = Vec :: with_capacity ( 2 ) ;
121
114
122
- for target in targets. iter_mut ( ) {
123
- if target. is_lib ( ) {
124
- target. set_kind ( TargetKind :: Lib ( kinds. clone ( ) ) ) ;
125
- target. set_name ( & capi_config. library . name ) ;
126
- }
115
+ if library_types. staticlib {
116
+ kinds. push ( CrateType :: Staticlib ) ;
117
+ }
118
+
119
+ if library_types. cdylib {
120
+ kinds. push ( CrateType :: Cdylib ) ;
121
+ }
122
+
123
+ for target in targets. iter_mut ( ) . filter ( |t| t. is_lib ( ) ) {
124
+ target. set_kind ( TargetKind :: Lib ( kinds. to_vec ( ) ) ) ;
125
+ target. set_name ( & capi_config. library . name ) ;
127
126
}
128
127
129
128
Ok ( ( ) )
@@ -952,7 +951,7 @@ impl CPackage {
952
951
fn from_package (
953
952
pkg : & mut Package ,
954
953
args : & ArgMatches ,
955
- libkinds : & [ & str ] ,
954
+ library_types : LibraryTypes ,
956
955
rustc_target : & target:: Target ,
957
956
root_output : & Path ,
958
957
) -> anyhow:: Result < CPackage > {
@@ -961,16 +960,16 @@ impl CPackage {
961
960
let root_path = pkg. root ( ) . to_path_buf ( ) ;
962
961
let capi_config = load_manifest_capi_config ( pkg, rustc_target) ?;
963
962
964
- patch_target ( pkg, libkinds , & capi_config) ?;
963
+ patch_target ( pkg, library_types , & capi_config) ?;
965
964
966
965
let name = & capi_config. library . name ;
967
966
968
967
let install_paths = InstallPaths :: new ( name, rustc_target, args, & capi_config) ;
969
- let build_targets = BuildTargets :: new (
968
+ let build_targets = BuildTargets :: new_help (
970
969
name,
971
970
rustc_target,
972
971
root_output,
973
- libkinds ,
972
+ library_types ,
974
973
& capi_config,
975
974
args. get_flag ( "meson" ) ,
976
975
) ?;
@@ -998,6 +997,54 @@ fn deprecation_warnings(ws: &Workspace, args: &ArgMatches) -> anyhow::Result<()>
998
997
Ok ( ( ) )
999
998
}
1000
999
1000
+ /// What library types to build
1001
+ #[ derive( Debug , Clone , Copy ) ]
1002
+ pub ( crate ) struct LibraryTypes {
1003
+ pub ( crate ) staticlib : bool ,
1004
+ pub ( crate ) cdylib : bool ,
1005
+ }
1006
+
1007
+ impl LibraryTypes {
1008
+ fn from_target ( target : & target:: Target ) -> Self {
1009
+ Self {
1010
+ staticlib : true ,
1011
+ cdylib : target. os != "none" && target. env != "musl" ,
1012
+ }
1013
+ }
1014
+
1015
+ fn from_config ( target : & target:: Target , args : & ArgMatches ) -> Self {
1016
+ match args. get_many :: < String > ( "library-type" ) {
1017
+ Some ( library_types) => Self :: from_library_types ( target, library_types) ,
1018
+ None => Self :: from_target ( target) ,
1019
+ }
1020
+ }
1021
+
1022
+ pub ( crate ) fn from_library_types < S : AsRef < str > > (
1023
+ target : & target:: Target ,
1024
+ library_types : impl Iterator < Item = S > ,
1025
+ ) -> Self {
1026
+ let ( mut staticlib, mut cdylib) = ( false , false ) ;
1027
+
1028
+ for library_type in library_types {
1029
+ staticlib |= library_type. as_ref ( ) == "staticlib" ;
1030
+ cdylib |= library_type. as_ref ( ) == "cdylib" ;
1031
+ }
1032
+
1033
+ // in this case, a cdylib cannot be produced
1034
+ cdylib &= target. os != "none" ;
1035
+
1036
+ Self { staticlib, cdylib }
1037
+ }
1038
+
1039
+ const fn only_staticlib ( self ) -> bool {
1040
+ self . staticlib && !self . cdylib
1041
+ }
1042
+
1043
+ const fn only_cdylib ( self ) -> bool {
1044
+ self . cdylib && !self . staticlib
1045
+ }
1046
+ }
1047
+
1001
1048
pub fn cbuild (
1002
1049
ws : & mut Workspace ,
1003
1050
config : & GlobalContext ,
@@ -1006,28 +1053,15 @@ pub fn cbuild(
1006
1053
) -> anyhow:: Result < ( Vec < CPackage > , CompileOptions ) > {
1007
1054
deprecation_warnings ( ws, args) ?;
1008
1055
1009
- let rustc = config. load_global_rustc ( Some ( ws) ) ?;
1010
- let targets = args. targets ( ) ?;
1011
- let ( target, is_target_overridden) = match targets. len ( ) {
1012
- 0 => ( rustc. host . to_string ( ) , false ) ,
1013
- 1 => ( targets[ 0 ] . to_string ( ) , true ) ,
1014
- _ => {
1015
- anyhow:: bail!( "Multiple targets not supported yet" ) ;
1016
- }
1056
+ let ( target, is_target_overridden) = match args. targets ( ) ?. as_slice ( ) {
1057
+ [ ] => ( config. load_global_rustc ( Some ( ws) ) ?. host . to_string ( ) , false ) ,
1058
+ [ target] => ( target. to_string ( ) , true ) ,
1059
+ [ ..] => anyhow:: bail!( "Multiple targets not supported yet" ) ,
1017
1060
} ;
1018
1061
1019
1062
let rustc_target = target:: Target :: new ( Some ( & target) , is_target_overridden) ?;
1020
1063
1021
- let default_kind = || match ( rustc_target. os . as_str ( ) , rustc_target. env . as_str ( ) ) {
1022
- ( "none" , _) | ( _, "musl" ) => vec ! [ "staticlib" ] ,
1023
- _ => vec ! [ "staticlib" , "cdylib" ] ,
1024
- } ;
1025
-
1026
- let libkinds = args
1027
- . get_many :: < String > ( "library-type" )
1028
- . map_or_else ( default_kind, |v| v. map ( String :: as_str) . collect :: < Vec < _ > > ( ) ) ;
1029
- let only_staticlib = !libkinds. contains ( & "cdylib" ) ;
1030
- let only_cdylib = !libkinds. contains ( & "staticlib" ) ;
1064
+ let library_types = LibraryTypes :: from_config ( & rustc_target, args) ;
1031
1065
1032
1066
let profile = args. get_profile_name ( default_profile, ProfileChecking :: Custom ) ?;
1033
1067
@@ -1043,10 +1077,7 @@ pub fn cbuild(
1043
1077
. join ( PathBuf :: from ( target) )
1044
1078
. join ( profiles. get_dir_name ( ) ) ;
1045
1079
1046
- let capi_feature = InternedString :: new ( "capi" ) ;
1047
-
1048
1080
let mut members = Vec :: new ( ) ;
1049
-
1050
1081
let mut pristine = false ;
1051
1082
1052
1083
let requested: Vec < _ > = compile_opts
@@ -1056,22 +1087,23 @@ pub fn cbuild(
1056
1087
. map ( |p| p. package_id ( ) )
1057
1088
. collect ( ) ;
1058
1089
1059
- for m in ws. members_mut ( ) . filter ( |m| {
1060
- m. library ( ) . is_some ( )
1061
- && m. summary ( ) . features ( ) . contains_key ( & capi_feature)
1062
- && requested. contains ( & m. package_id ( ) )
1063
- } ) {
1064
- let cpkg = CPackage :: from_package ( m, args, & libkinds, & rustc_target, & root_output) ?;
1090
+ let capi_feature = InternedString :: new ( "capi" ) ;
1091
+ let is_relevant_package = |package : & Package | {
1092
+ package. library ( ) . is_some ( )
1093
+ && package. summary ( ) . features ( ) . contains_key ( & capi_feature)
1094
+ && requested. contains ( & package. package_id ( ) )
1095
+ } ;
1096
+
1097
+ for m in ws. members_mut ( ) . filter ( |p| is_relevant_package ( p) ) {
1098
+ let cpkg = CPackage :: from_package ( m, args, library_types, & rustc_target, & root_output) ?;
1065
1099
1066
- pristine = pristine || cpkg. finger_print . load_previous ( ) . is_err ( ) ;
1100
+ pristine |= cpkg. finger_print . load_previous ( ) . is_err ( ) ;
1067
1101
1068
1102
members. push ( cpkg) ;
1069
1103
}
1070
1104
1071
- if pristine {
1072
- // If the cache is somehow missing force a full rebuild;
1073
- compile_opts. build_config . force_rebuild = true ;
1074
- }
1105
+ // If the cache is somehow missing force a full rebuild;
1106
+ compile_opts. build_config . force_rebuild |= pristine;
1075
1107
1076
1108
let exec = Arc :: new ( Exec :: default ( ) ) ;
1077
1109
let out_dirs = compile_with_exec (
@@ -1111,7 +1143,7 @@ pub fn cbuild(
1111
1143
// if the hash value does not match.
1112
1144
if new_build && !cpkg. finger_print . is_valid ( ) {
1113
1145
let name = & cpkg. capi_config . library . name ;
1114
- let static_libs = if only_cdylib {
1146
+ let static_libs = if library_types . only_cdylib ( ) {
1115
1147
"" . to_string ( )
1116
1148
} else {
1117
1149
exec. link_line
@@ -1126,14 +1158,14 @@ pub fn cbuild(
1126
1158
let build_targets = & cpkg. build_targets ;
1127
1159
1128
1160
let mut pc = PkgConfig :: from_workspace ( name, & cpkg. install_paths , args, capi_config) ;
1129
- if only_staticlib {
1161
+ if library_types . only_staticlib ( ) {
1130
1162
pc. add_lib ( & static_libs) ;
1131
1163
}
1132
1164
pc. add_lib_private ( & static_libs) ;
1133
1165
1134
1166
build_pc_files ( ws, & capi_config. pkg_config . filename , & root_output, & pc) ?;
1135
1167
1136
- if !only_staticlib && capi_config. library . import_library {
1168
+ if !library_types . only_staticlib ( ) && capi_config. library . import_library {
1137
1169
let lib_name = name;
1138
1170
build_def_file ( ws, lib_name, & rustc_target, & root_output) ?;
1139
1171
build_implib_file ( ws, lib_name, & rustc_target, & root_output) ?;
@@ -1155,11 +1187,11 @@ pub fn cbuild(
1155
1187
}
1156
1188
1157
1189
if name. contains ( '-' ) {
1158
- let from_build_targets = BuildTargets :: new (
1190
+ let from_build_targets = BuildTargets :: new_help (
1159
1191
& name. replace ( '-' , "_" ) ,
1160
1192
& rustc_target,
1161
1193
& root_output,
1162
- & libkinds ,
1194
+ library_types ,
1163
1195
capi_config,
1164
1196
args. get_flag ( "meson" ) ,
1165
1197
) ?;
0 commit comments