@@ -14,6 +14,7 @@ use cargo::util::command_prelude::{ArgMatches, ArgMatchesExt, CompileMode, Profi
1414use cargo:: util:: interning:: InternedString ;
1515use cargo:: { CliResult , Config } ;
1616
17+ use anyhow:: Context as _;
1718use cargo_util:: paths:: { copy, create, create_dir_all, open, read, read_bytes, write} ;
1819use semver:: Version ;
1920
@@ -400,16 +401,43 @@ pub struct PkgConfigCApiConfig {
400401 pub strip_include_path_components : usize ,
401402}
402403
404+ #[ derive( Debug ) ]
405+ pub enum VersionSuffix {
406+ Major ,
407+ MajorMinor ,
408+ MajorMinorPatch ,
409+ }
410+
403411#[ derive( Debug ) ]
404412pub struct LibraryCApiConfig {
405413 pub name : String ,
406414 pub version : Version ,
407415 pub install_subdir : Option < String > ,
408416 pub versioning : bool ,
417+ pub version_suffix_components : Option < VersionSuffix > ,
409418 pub import_library : bool ,
410419 pub rustflags : Vec < String > ,
411420}
412421
422+ impl LibraryCApiConfig {
423+ pub fn sover ( & self ) -> String {
424+ let major = self . version . major ;
425+ let minor = self . version . minor ;
426+ let patch = self . version . patch ;
427+
428+ match self . version_suffix_components {
429+ None => match ( major, minor, patch) {
430+ ( 0 , 0 , patch) => format ! ( "0.0.{patch}" ) ,
431+ ( 0 , minor, _) => format ! ( "0.{minor}" ) ,
432+ ( major, _, _) => format ! ( "{major}" ) ,
433+ } ,
434+ Some ( VersionSuffix :: Major ) => format ! ( "{major}" ) ,
435+ Some ( VersionSuffix :: MajorMinor ) => format ! ( "{major}.{minor}" ) ,
436+ Some ( VersionSuffix :: MajorMinorPatch ) => format ! ( "{major}.{minor}.{patch}" ) ,
437+ }
438+ }
439+ }
440+
413441#[ derive( Debug , Default ) ]
414442pub struct InstallCApiConfig {
415443 pub include : Vec < InstallTarget > ,
@@ -619,6 +647,7 @@ fn load_manifest_capi_config(pkg: &Package) -> anyhow::Result<CApiConfig> {
619647 let mut version = pkg. version ( ) . clone ( ) ;
620648 let mut install_subdir = None ;
621649 let mut versioning = true ;
650+ let mut version_suffix_components = None ;
622651 let mut import_library = true ;
623652 let mut rustflags = Vec :: new ( ) ;
624653
@@ -636,6 +665,19 @@ fn load_manifest_capi_config(pkg: &Package) -> anyhow::Result<CApiConfig> {
636665 . get ( "versioning" )
637666 . and_then ( |v| v. as_bool ( ) )
638667 . unwrap_or ( true ) ;
668+
669+ if let Some ( value) = library. get ( "version_suffix_components" ) {
670+ let value = value. as_integer ( ) . with_context ( || {
671+ format ! ( "Value for `version_suffix_components` is not an integer: {value:?}" )
672+ } ) ?;
673+ version_suffix_components = Some ( match value {
674+ 1 => VersionSuffix :: Major ,
675+ 2 => VersionSuffix :: MajorMinor ,
676+ 3 => VersionSuffix :: MajorMinorPatch ,
677+ _ => anyhow:: bail!( "Out of range value for version suffix components: {value}" ) ,
678+ } ) ;
679+ }
680+
639681 import_library = library
640682 . get ( "import_library" )
641683 . and_then ( |v| v. as_bool ( ) )
@@ -655,6 +697,7 @@ fn load_manifest_capi_config(pkg: &Package) -> anyhow::Result<CApiConfig> {
655697 version,
656698 install_subdir,
657699 versioning,
700+ version_suffix_components,
658701 import_library,
659702 rustflags,
660703 } ;
@@ -1246,3 +1289,66 @@ pub fn ctest(
12461289
12471290 ops:: run_tests ( ws, & ops, & test_args)
12481291}
1292+
1293+ #[ cfg( test) ]
1294+ mod tests {
1295+ use super :: * ;
1296+ use semver:: Version ;
1297+
1298+ fn make_test_library_config ( version : & str ) -> LibraryCApiConfig {
1299+ LibraryCApiConfig {
1300+ name : "example" . to_string ( ) ,
1301+ version : Version :: parse ( version) . unwrap ( ) ,
1302+ install_subdir : None ,
1303+ versioning : true ,
1304+ version_suffix_components : None ,
1305+ import_library : true ,
1306+ rustflags : vec ! [ ] ,
1307+ }
1308+ }
1309+
1310+ #[ test]
1311+ pub fn test_semver_zero_zero_zero ( ) {
1312+ let library = make_test_library_config ( "0.0.0" ) ;
1313+ let sover = library. sover ( ) ;
1314+ assert_eq ! ( sover, "0.0.0" ) ;
1315+ }
1316+
1317+ #[ test]
1318+ pub fn test_semver_zero_one_zero ( ) {
1319+ let library = make_test_library_config ( "0.1.0" ) ;
1320+ let sover = library. sover ( ) ;
1321+ assert_eq ! ( sover, "0.1" ) ;
1322+ }
1323+
1324+ #[ test]
1325+ pub fn test_semver_one_zero_zero ( ) {
1326+ let library = make_test_library_config ( "1.0.0" ) ;
1327+ let sover = library. sover ( ) ;
1328+ assert_eq ! ( sover, "1" ) ;
1329+ }
1330+
1331+ #[ test]
1332+ pub fn text_one_fixed_zero_zero_zero ( ) {
1333+ let mut library = make_test_library_config ( "0.0.0" ) ;
1334+ library. version_suffix_components = Some ( VersionSuffix :: Major ) ;
1335+ let sover = library. sover ( ) ;
1336+ assert_eq ! ( sover, "0" ) ;
1337+ }
1338+
1339+ #[ test]
1340+ pub fn text_two_fixed_one_zero_zero ( ) {
1341+ let mut library = make_test_library_config ( "1.0.0" ) ;
1342+ library. version_suffix_components = Some ( VersionSuffix :: MajorMinor ) ;
1343+ let sover = library. sover ( ) ;
1344+ assert_eq ! ( sover, "1.0" ) ;
1345+ }
1346+
1347+ #[ test]
1348+ pub fn text_three_fixed_one_zero_zero ( ) {
1349+ let mut library = make_test_library_config ( "1.0.0" ) ;
1350+ library. version_suffix_components = Some ( VersionSuffix :: MajorMinorPatch ) ;
1351+ let sover = library. sover ( ) ;
1352+ assert_eq ! ( sover, "1.0.0" ) ;
1353+ }
1354+ }
0 commit comments