@@ -18,6 +18,9 @@ use syn::{
1818 WhereClause , WherePredicate ,
1919} ;
2020
21+ use std:: collections:: hash_map:: DefaultHasher ;
22+ use std:: hash:: { Hash , Hasher } ;
23+
2124/// Checks if any attribute in `attrs_to_check` is in `reject_list` and returns a compiler error if there's a match
2225///
2326/// The compiler error will indicate that the attribute conflicts with `attr_name`
@@ -194,7 +197,8 @@ pub fn timestamp(ts: TokenStream) -> TokenStream {
194197 // Unique symbol name to prevent multiple `timestamp!` invocations in the crate graph.
195198 // Uses `#symname` to ensure it is not discarded by the linker.
196199 #[ no_mangle]
197- #[ link_section = ".defmt.end.timestamp" ]
200+ #[ cfg_attr( target_os = "macos" , link_section = ".defmt,end.timestamp" ) ]
201+ #[ cfg_attr( not( target_os = "macos" ) , link_section = ".defmt.end.timestamp" ) ]
198202 static __DEFMT_MARKER_TIMESTAMP_WAS_DEFINED: & u8 = & #symname;
199203 } ;
200204 )
@@ -984,13 +988,16 @@ pub fn internp(ts: TokenStream) -> TokenStream {
984988 let ls = lit. value ( ) ;
985989
986990 let sym = symbol:: Symbol :: new ( "prim" , & ls) . mangle ( ) ;
987- let section = format ! ( ".defmt.prim.{}" , sym) ;
991+
992+ let section = mksection ( false , "prim." , & sym) ;
993+ let section_macos = mksection ( true , "prim." , & sym) ;
988994
989995 if cfg ! ( feature = "unstable-test" ) {
990996 quote ! ( { defmt:: export:: fetch_add_string_index( ) as u8 } )
991997 } else {
992998 quote ! ( {
993- #[ link_section = #section]
999+ #[ cfg_attr( target_os = "macos" , link_section = #section_macos) ]
1000+ #[ cfg_attr( not( target_os = "macos" ) , link_section = #section) ]
9941001 #[ export_name = #sym]
9951002 static S : u8 = 0 ;
9961003 & S as * const u8 as u8
@@ -1039,12 +1046,30 @@ pub fn write(ts: TokenStream) -> TokenStream {
10391046 . into ( )
10401047}
10411048
1049+ /// work around restrictions on length and allowed characters imposed by macos linker
1050+ /// returns (note the comma character for macos):
1051+ /// under macos: ".defmt," + 16 character hex digest of symbol's hash
1052+ /// otherwise: ".defmt." + prefix + symbol
1053+ fn mksection ( macos : bool , prefix : & str , symbol : & str ) -> String {
1054+ let mut sub_section = format ! ( ".{}{}" , prefix, symbol) ;
1055+
1056+ if macos {
1057+ let mut hasher = DefaultHasher :: new ( ) ;
1058+ sub_section. hash ( & mut hasher) ;
1059+ sub_section = format ! ( ",{:x}" , hasher. finish( ) ) ;
1060+ }
1061+
1062+ format ! ( ".defmt{}" , sub_section)
1063+ }
1064+
10421065fn mkstatic ( varname : Ident2 , string : & str , tag : & str ) -> TokenStream2 {
10431066 let sym = symbol:: Symbol :: new ( tag, string) . mangle ( ) ;
1044- let section = format ! ( ".defmt.{}" , sym) ;
1067+ let section = mksection ( false , "" , & sym) ;
1068+ let section_macos = mksection ( true , "" , & sym) ;
10451069
10461070 quote ! (
1047- #[ link_section = #section]
1071+ #[ cfg_attr( target_os = "macos" , link_section = #section_macos) ]
1072+ #[ cfg_attr( not( target_os = "macos" ) , link_section = #section) ]
10481073 #[ export_name = #sym]
10491074 static #varname: u8 = 0 ;
10501075 )
0 commit comments