@@ -3526,6 +3526,16 @@ impl BuildRequest {
35263526 cargo_args. push ( "-Clink-arg=-Wl,-rpath,$ORIGIN/../lib" . to_string ( ) ) ;
35273527 cargo_args. push ( "-Clink-arg=-Wl,-rpath,$ORIGIN" . to_string ( ) ) ;
35283528 }
3529+ OperatingSystem :: Windows => match self . write_winres ( ) {
3530+ Ok ( res) => {
3531+ cargo_args. extend ( [ "-L" . to_string ( ) , res. path , "-l" . to_string ( ) , res. lib ] ) ;
3532+ }
3533+ Err ( err) => {
3534+ if self . using_dioxus_explicitly {
3535+ tracing:: warn!( "Application may not have an icon: {err}" ) ;
3536+ }
3537+ }
3538+ } ,
35293539 _ => { }
35303540 }
35313541
@@ -3614,6 +3624,123 @@ impl BuildRequest {
36143624 cargo_args
36153625 }
36163626
3627+ pub ( crate ) fn canonicalize_icon_path ( & self , icon_path : & PathBuf ) -> Result < PathBuf , Error > {
3628+ if icon_path. is_absolute ( ) && icon_path. is_file ( ) {
3629+ return Ok ( dunce:: canonicalize ( icon_path) ?) ;
3630+ }
3631+ let crate_icon = self . crate_dir ( ) . join ( icon_path) ;
3632+ if crate_icon. is_file ( ) {
3633+ return Ok ( dunce:: canonicalize ( crate_icon) ?) ;
3634+ }
3635+ let workspace_icon = self . workspace_dir ( ) . join ( icon_path) ;
3636+ if workspace_icon. is_file ( ) {
3637+ return Ok ( dunce:: canonicalize ( workspace_icon) ?) ;
3638+ }
3639+
3640+ Err ( anyhow:: anyhow!(
3641+ "Could not find icon from path {:?}" ,
3642+ icon_path
3643+ ) )
3644+ }
3645+
3646+ // needs to only run when tomls are updated
3647+ fn write_winres ( & self ) -> Result < crate :: winres:: WindowsResourceLinker > {
3648+ use crate :: winres:: * ;
3649+ let bundle = & self . config . bundle ;
3650+ let package = self . package ( ) ;
3651+
3652+ let ( version_str, version) = match bundle. version . as_ref ( ) {
3653+ Some ( v) => ( v, VersionInfo :: version_from_str ( v) ) ,
3654+ None => (
3655+ & format ! (
3656+ "{}.{}.{}" ,
3657+ package. version. major, package. version. minor, package. version. patch
3658+ ) ,
3659+ VersionInfo :: version_from_krate ( & package. version ) ,
3660+ ) ,
3661+ } ;
3662+
3663+ let ( file_version_str, file_version) = match bundle. file_version . as_ref ( ) {
3664+ Some ( v) => ( v, VersionInfo :: version_from_str ( v) ) ,
3665+ None => ( version_str, version) ,
3666+ } ;
3667+
3668+ let productname = match self . config . application . name . as_ref ( ) {
3669+ Some ( n) => n,
3670+ None => & self . bundled_app_name ( ) ,
3671+ } ;
3672+
3673+ let binding = package. description . clone ( ) . unwrap_or_default ( ) ;
3674+ let description = match bundle. short_description . as_ref ( ) {
3675+ Some ( val) => val,
3676+ None => bundle. long_description . as_ref ( ) . unwrap_or ( & binding) ,
3677+ } ;
3678+
3679+ // platform dir gets cleared on bundle
3680+ let mut output_dir = self . platform_dir ( ) ;
3681+ output_dir. push ( "winres" ) ;
3682+
3683+ std:: fs:: create_dir_all ( & output_dir) ?;
3684+
3685+ let mut winres = WindowsResource :: new ( version, file_version) ;
3686+ winres
3687+ . set ( Properties :: ProductVersion , version_str)
3688+ . set ( Properties :: FileVersion , file_version_str)
3689+ . set ( Properties :: ProductName , productname)
3690+ . set ( Properties :: FileDescription , description) ;
3691+
3692+ if let Some ( value) = & bundle. original_file_name {
3693+ winres. set ( Properties :: OriginalFilename , value) ;
3694+ }
3695+
3696+ if let Some ( value) = & bundle. copyright {
3697+ winres. set ( Properties :: Copyright , value) ;
3698+ }
3699+ if let Some ( value) = & bundle. trademark {
3700+ winres. set ( Properties :: Trademark , value) ;
3701+ }
3702+
3703+ if let Some ( value) = & bundle. publisher {
3704+ winres. set ( Properties :: CompanyName , value) ;
3705+ }
3706+
3707+ if let Some ( value) = & bundle. category {
3708+ winres. set ( Properties :: Other ( "Category" ) , value) ;
3709+ }
3710+
3711+ let mut has_default = false ;
3712+ if let Some ( windows) = bundle. windows . as_ref ( ) {
3713+ if let Some ( path) = windows. icon_path . as_ref ( ) {
3714+ winres. set_icon ( path. clone ( ) ) ;
3715+ has_default = true ;
3716+ }
3717+ } ;
3718+
3719+ if let Some ( icons) = bundle. icon . as_ref ( ) {
3720+ for ( id, icon) in icons. iter ( ) . enumerate ( ) {
3721+ if icon. ends_with ( ".ico" ) {
3722+ let icon_path = self . canonicalize_icon_path ( & PathBuf :: from ( icon) ) ?;
3723+ if !has_default {
3724+ // first .ico file will be app icon
3725+ winres. set_icon ( icon_path) ;
3726+ has_default = true ;
3727+ } else {
3728+ // other .ico files can be accessed with their index as id
3729+ winres. set_icon_with_id ( icon_path, id. to_string ( ) ) ;
3730+ } ;
3731+ }
3732+ }
3733+ }
3734+
3735+ if !has_default {
3736+ let default_icon = write_default_icon ( & output_dir) ?;
3737+ let icon = self . canonicalize_icon_path ( & default_icon) ?;
3738+ winres. set_icon ( icon) ;
3739+ }
3740+
3741+ winres. compile ( & self . triple , & output_dir)
3742+ }
3743+
36173744 pub ( crate ) fn cargo_build_env_vars (
36183745 & self ,
36193746 build_mode : & BuildMode ,
0 commit comments