1+ from __future__ import print_function
2+
13from os .path import (join , realpath , dirname , expanduser , exists ,
2- split )
3- from os import environ
4+ split , isdir )
5+ from os import environ , listdir
46import os
57import glob
68import sys
@@ -421,6 +423,7 @@ def __init__(self):
421423 self .toolchain_version = None
422424
423425 self .local_recipes = None
426+ self .copy_libs = False
424427
425428 # root of the toolchain
426429 self .setup_dirs ()
@@ -485,6 +488,9 @@ def get_libs_dir(self, arch):
485488 ensure_dir (join (self .libs_dir , arch ))
486489 return join (self .libs_dir , arch )
487490
491+ def has_lib (self , arch , lib ):
492+ return exists (join (self .get_libs_dir (arch ), lib ))
493+
488494 def has_package (self , name , arch = None ):
489495 try :
490496 recipe = Recipe .get_recipe (name , self )
@@ -622,6 +628,7 @@ def biglink(ctx, arch):
622628 if not len (files ):
623629 info ('{} recipe has no biglinkable files, skipping'
624630 .format (recipe .name ))
631+ continue
625632 info ('{} recipe has object files, copying' .format (recipe .name ))
626633 files .append (obj_dir )
627634 shprint (sh .cp , '-r' , * files )
@@ -636,7 +643,8 @@ def biglink(ctx, arch):
636643 info ('Biglinking' )
637644 info ('target {}' .format (join (ctx .get_libs_dir (arch .arch ),
638645 'libpymodules.so' )))
639- biglink_function (
646+ do_biglink = copylibs_function if ctx .copy_libs else biglink_function
647+ do_biglink (
640648 join (ctx .get_libs_dir (arch .arch ), 'libpymodules.so' ),
641649 obj_dir .split (' ' ),
642650 extra_link_dirs = [join (ctx .bootstrap .build_dir ,
@@ -689,3 +697,137 @@ def biglink_function(soname, objs_paths, extra_link_dirs=[], env=None):
689697 cc = cc .bake (* cc_name .split ()[1 :])
690698
691699 shprint (cc , '-shared' , '-O3' , '-o' , soname , * unique_args , _env = env )
700+
701+
702+ def copylibs_function (soname , objs_paths , extra_link_dirs = [], env = None ):
703+ print ('objs_paths are' , objs_paths )
704+
705+ re_needso = re .compile (r'^.*\(NEEDED\)\s+Shared library: \[lib(.*)\.so\]\s*$' )
706+ blacklist_libs = (
707+ 'c' ,
708+ 'stdc++' ,
709+ 'dl' ,
710+ 'python2.7' ,
711+ 'sdl' ,
712+ 'sdl_image' ,
713+ 'sdl_ttf' ,
714+ 'z' ,
715+ 'm' ,
716+ 'GLESv2' ,
717+ 'jpeg' ,
718+ 'png' ,
719+ 'log' ,
720+
721+ # bootstrap takes care of sdl2 libs (if applicable)
722+ 'SDL2' ,
723+ 'SDL2_ttf' ,
724+ 'SDL2_image' ,
725+ 'SDL2_mixer' ,
726+ )
727+ found_libs = []
728+ sofiles = []
729+ if env and 'READELF' in env :
730+ readelf = env ['READELF' ]
731+ elif 'READELF' in os .environ :
732+ readelf = os .environ ['READELF' ]
733+ else :
734+ readelf = sh .which ('readelf' ).strip ()
735+ readelf = sh .Command (readelf ).bake ('-d' )
736+
737+ dest = dirname (soname )
738+
739+ for directory in objs_paths :
740+ for fn in os .listdir (directory ):
741+ fn = join (directory , fn )
742+
743+ if not fn .endswith ('.libs' ):
744+ continue
745+
746+ dirfn = fn [:- 1 ] + 'dirs'
747+ if not exists (dirfn ):
748+ continue
749+
750+ with open (fn ) as f :
751+ libs = f .read ().strip ().split (' ' )
752+ needed_libs = [lib for lib in libs
753+ if lib and
754+ lib not in blacklist_libs and
755+ lib not in found_libs ]
756+
757+ while needed_libs :
758+ print ('need libs:\n \t ' + '\n \t ' .join (needed_libs ))
759+
760+ start_needed_libs = needed_libs [:]
761+ found_sofiles = []
762+
763+ with open (dirfn ) as f :
764+ libdirs = f .read ().split ()
765+ for libdir in libdirs :
766+ if not needed_libs :
767+ break
768+
769+ if libdir == dest :
770+ # don't need to copy from dest to dest!
771+ continue
772+
773+ libdir = libdir .strip ()
774+ print ('scanning' , libdir )
775+ for lib in needed_libs [:]:
776+ if lib in found_libs :
777+ continue
778+
779+ if lib .endswith ('.a' ):
780+ needed_libs .remove (lib )
781+ found_libs .append (lib )
782+ continue
783+
784+ lib_a = 'lib' + lib + '.a'
785+ libpath_a = join (libdir , lib_a )
786+ lib_so = 'lib' + lib + '.so'
787+ libpath_so = join (libdir , lib_so )
788+ plain_so = lib + '.so'
789+ plainpath_so = join (libdir , plain_so )
790+
791+ sopath = None
792+ if exists (libpath_so ):
793+ sopath = libpath_so
794+ elif exists (plainpath_so ):
795+ sopath = plainpath_so
796+
797+ if sopath :
798+ print ('found' , lib , 'in' , libdir )
799+ found_sofiles .append (sopath )
800+ needed_libs .remove (lib )
801+ found_libs .append (lib )
802+ continue
803+
804+ if exists (libpath_a ):
805+ print ('found' , lib , '(static) in' , libdir )
806+ needed_libs .remove (lib )
807+ found_libs .append (lib )
808+ continue
809+
810+ for sofile in found_sofiles :
811+ print ('scanning dependencies for' , sofile )
812+ out = readelf (sofile )
813+ for line in out .splitlines ():
814+ needso = re_needso .match (line )
815+ if needso :
816+ lib = needso .group (1 )
817+ if (lib not in needed_libs
818+ and lib not in found_libs
819+ and lib not in blacklist_libs ):
820+ needed_libs .append (needso .group (1 ))
821+
822+ sofiles += found_sofiles
823+
824+ if needed_libs == start_needed_libs :
825+ raise RuntimeError (
826+ 'Failed to locate needed libraries!\n \t ' +
827+ '\n \t ' .join (needed_libs ))
828+
829+ print ('Copying libraries' )
830+ cp = sh .cp .bake ('-t' , dest )
831+ for lib in sofiles :
832+ shprint (cp , lib )
833+
0 commit comments