@@ -10,7 +10,7 @@ use cranelift_module::{
1010 DataDescription , DataId , FuncId , Init , Linkage , Module , ModuleDeclarations , ModuleError ,
1111 ModuleReloc , ModuleRelocTarget , ModuleResult ,
1212} ;
13- use log:: info;
13+ use log:: { info, warn } ;
1414use object:: write:: {
1515 Object , Relocation , SectionId , StandardSection , Symbol , SymbolId , SymbolSection ,
1616} ;
@@ -21,7 +21,7 @@ use object::{
2121use std:: collections:: HashMap ;
2222use std:: collections:: hash_map:: Entry ;
2323use std:: mem;
24- use target_lexicon:: PointerWidth ;
24+ use target_lexicon:: { PointerWidth , Triple } ;
2525
2626/// A builder for `ObjectModule`.
2727pub struct ObjectBuilder {
@@ -137,6 +137,68 @@ impl ObjectBuilder {
137137 }
138138}
139139
140+ /// See the following for details:
141+ /// <https://github.com/rust-lang/rust/blob/1.95.0/compiler/rustc_codegen_ssa/src/back/metadata.rs#L408-L425>
142+ fn macho_build_version ( triple : & Triple ) -> Option < object:: write:: MachOBuildVersion > {
143+ use target_lexicon:: { DeploymentTarget , OperatingSystem :: * } ;
144+
145+ fn pack_version ( v : DeploymentTarget ) -> u32 {
146+ let ( major, minor, patch) = ( v. major as u32 , v. minor as u32 , v. patch as u32 ) ;
147+ ( major << 16 ) | ( minor << 8 ) | patch
148+ }
149+
150+ match triple. operating_system {
151+ Darwin ( v) | MacOSX ( v) | IOS ( v) | TvOS ( v) | VisionOS ( v) | WatchOS ( v) | XROS ( v) => {
152+ use object:: macho:: * ;
153+ use target_lexicon:: Environment :: * ;
154+ // Same as https://github.com/rust-lang/rust/blob/1.95.0/compiler/rustc_codegen_ssa/src/back/apple.rs#L36-L50.
155+ //
156+ // TODO(madsmtm): Properly support simulator after
157+ // https://github.com/bytecodealliance/target-lexicon/pull/130
158+ let platform = match ( triple. operating_system , triple. environment ) {
159+ ( Darwin ( _) , _) => 0 , // PLATFORM_UNKNOWN
160+ ( MacOSX ( _) , _) => PLATFORM_MACOS ,
161+ ( _, Macabi ) => PLATFORM_MACCATALYST ,
162+ ( IOS ( _) , Sim ) => PLATFORM_IOSSIMULATOR ,
163+ ( IOS ( _) , _) => PLATFORM_IOS ,
164+ ( TvOS ( _) , Sim ) => PLATFORM_TVOSSIMULATOR ,
165+ ( TvOS ( _) , _) => PLATFORM_TVOS ,
166+ ( VisionOS ( _) | XROS ( _) , Sim ) => PLATFORM_XROSSIMULATOR ,
167+ ( VisionOS ( _) | XROS ( _) , _) => PLATFORM_XROS ,
168+ ( WatchOS ( _) , Sim ) => PLATFORM_WATCHOSSIMULATOR ,
169+ ( WatchOS ( _) , _) => PLATFORM_WATCHOS ,
170+ _ => {
171+ warn ! ( "unsupported OS/environment: {triple}" ) ;
172+ 0
173+ }
174+ } ;
175+
176+ let mut build_version = object:: write:: MachOBuildVersion :: default ( ) ;
177+ build_version. platform = platform;
178+
179+ build_version. minos = if let Some ( v) = v {
180+ pack_version ( v)
181+ } else {
182+ // The `minos` in object files is useful for diagnostics, as
183+ // it tells the linker whether the file supports a given OS -
184+ // if the `minos` is higher than what you're linking against,
185+ // that's a signal that something has gone wrong.
186+ //
187+ // Using `0.0.0` here should be fine if we don't have the data
188+ // available.
189+ 0
190+ } ;
191+
192+ // Setting a 0 SDK version is fine, it's only relevant for the
193+ // final linked binary.
194+ build_version. sdk = 0 ;
195+
196+ Some ( build_version)
197+ }
198+ _ => None ,
199+ }
200+ }
201+
140202/// An `ObjectModule` implements `Module` and emits ".o" files using the `object` library.
141203///
142204/// See the `ObjectBuilder` for a convenient way to construct `ObjectModule` instances.
@@ -162,6 +224,13 @@ impl ObjectModule {
162224 object. flags = builder. flags ;
163225 object. set_subsections_via_symbols ( ) ;
164226 object. add_file_symbol ( builder. name ) ;
227+ if let Some ( info) = macho_build_version ( builder. isa . triple ( ) ) {
228+ // Set LC_BUILD_VERSION.
229+ //
230+ // Required when linking Apple targets to avoid warning, see:
231+ // https://github.com/bytecodealliance/wasmtime/issues/8730
232+ object. set_macho_build_version ( info) ;
233+ }
165234 Self {
166235 isa : builder. isa ,
167236 object,
0 commit comments