@@ -291,6 +291,71 @@ def generate_darwin_toolchain_file(self, platform, arch):
291291
292292 return toolchain_file
293293
294+ def get_linux_abi (self , arch ):
295+ # Map tuples of (platform, arch) to ABI
296+ #
297+ # E.x.: Hard ABI or Soft ABI for Linux map to gnueabihf
298+ arch_platform_to_abi = {
299+ # For now always map to hard float ABI.
300+ 'armv7' : ('arm' , 'gnueabihf' )
301+ }
302+
303+ # Default is just arch, gnu
304+ sysroot_arch , abi = arch_platform_to_abi .get (arch , (arch , 'gnu' ))
305+ return sysroot_arch , abi
306+
307+ def get_linux_sysroot (self , platform , arch ):
308+ if not self .is_cross_compile_target ('{}-{}' .format (platform , arch )):
309+ return None
310+ sysroot_arch , abi = self .get_linux_abi (arch )
311+ # $ARCH-$PLATFORM-$ABI
312+ # E.x.: aarch64-linux-gnu
313+ sysroot_dirname = '{}-{}-{}' .format (sysroot_arch , platform , abi )
314+ return os .path .join (os .sep , 'usr' , sysroot_dirname )
315+
316+ def get_linux_target (self , platform , arch ):
317+ sysroot_arch , abi = self .get_linux_abi (arch )
318+ return '{}-unknown-linux-{}' .format (sysroot_arch , abi )
319+
320+ def generate_linux_toolchain_file (self , platform , arch ):
321+ shell .makedirs (self .build_dir )
322+ toolchain_file = os .path .join (self .build_dir , 'BuildScriptToolchain.cmake' )
323+
324+ toolchain_args = {}
325+
326+ toolchain_args ['CMAKE_SYSTEM_NAME' ] = 'Linux'
327+ toolchain_args ['CMAKE_SYSTEM_PROCESSOR' ] = arch
328+
329+ # We only set the actual sysroot if we are actually cross
330+ # compiling. This is important since otherwise cmake seems to change the
331+ # RUNPATH to be a relative rather than an absolute path, breaking
332+ # certain cmark tests (and maybe others).
333+ maybe_sysroot = self .get_linux_sysroot (platform , arch )
334+ if maybe_sysroot is not None :
335+ toolchain_args ['CMAKE_SYSROOT' ] = maybe_sysroot
336+
337+ target = self .get_linux_target (platform , arch )
338+ if self .toolchain .cc .endswith ('clang' ):
339+ toolchain_args ['CMAKE_C_COMPILER_TARGET' ] = target
340+ if self .toolchain .cxx .endswith ('clang++' ):
341+ toolchain_args ['CMAKE_CXX_COMPILER_TARGET' ] = target
342+ # Swift always supports cross compiling.
343+ toolchain_args ['CMAKE_Swift_COMPILER_TARGET' ] = target
344+ toolchain_args ['CMAKE_FIND_ROOT_PATH_MODE_PROGRAM' ] = 'NEVER'
345+ toolchain_args ['CMAKE_FIND_ROOT_PATH_MODE_LIBRARY' ] = 'ONLY'
346+ toolchain_args ['CMAKE_FIND_ROOT_PATH_MODE_INCLUDE' ] = 'ONLY'
347+ toolchain_args ['CMAKE_FIND_ROOT_PATH_MODE_PACKAGE' ] = 'ONLY'
348+
349+ # Sort by the key so that we always produce the same toolchain file
350+ data = sorted (toolchain_args .items (), key = lambda x : x [0 ])
351+ if not self .args .dry_run :
352+ with open (toolchain_file , 'w' ) as f :
353+ f .writelines ("set({} {})\n " .format (k , v ) for k , v in data )
354+ else :
355+ print ("DRY_RUN! Writing Toolchain file to path: {}" .format (toolchain_file ))
356+
357+ return toolchain_file
358+
294359 def common_cross_c_flags (self , platform , arch ):
295360 cross_flags = []
296361
0 commit comments