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 )
@@ -617,6 +623,7 @@ def biglink(ctx, arch):
617623 if not len (files ):
618624 info ('{} recipe has no biglinkable files, skipping'
619625 .format (recipe .name ))
626+ continue
620627 info ('{} recipe has object files, copying' .format (recipe .name ))
621628 files .append (obj_dir )
622629 shprint (sh .cp , '-r' , * files )
@@ -631,7 +638,8 @@ def biglink(ctx, arch):
631638 info ('Biglinking' )
632639 info ('target {}' .format (join (ctx .get_libs_dir (arch .arch ),
633640 'libpymodules.so' )))
634- biglink_function (
641+ do_biglink = copylibs_function if ctx .copy_libs else biglink_function
642+ do_biglink (
635643 join (ctx .get_libs_dir (arch .arch ), 'libpymodules.so' ),
636644 obj_dir .split (' ' ),
637645 extra_link_dirs = [join (ctx .bootstrap .build_dir ,
@@ -684,3 +692,137 @@ def biglink_function(soname, objs_paths, extra_link_dirs=[], env=None):
684692 cc = cc .bake (* cc_name .split ()[1 :])
685693
686694 shprint (cc , '-shared' , '-O3' , '-o' , soname , * unique_args , _env = env )
695+
696+
697+ def copylibs_function (soname , objs_paths , extra_link_dirs = [], env = None ):
698+ print ('objs_paths are' , objs_paths )
699+
700+ re_needso = re .compile (r'^.*\(NEEDED\)\s+Shared library: \[lib(.*)\.so\]\s*$' )
701+ blacklist_libs = (
702+ 'c' ,
703+ 'stdc++' ,
704+ 'dl' ,
705+ 'python2.7' ,
706+ 'sdl' ,
707+ 'sdl_image' ,
708+ 'sdl_ttf' ,
709+ 'z' ,
710+ 'm' ,
711+ 'GLESv2' ,
712+ 'jpeg' ,
713+ 'png' ,
714+ 'log' ,
715+
716+ # bootstrap takes care of sdl2 libs (if applicable)
717+ 'SDL2' ,
718+ 'SDL2_ttf' ,
719+ 'SDL2_image' ,
720+ 'SDL2_mixer' ,
721+ )
722+ found_libs = []
723+ sofiles = []
724+ if env and 'READELF' in env :
725+ readelf = env ['READELF' ]
726+ elif 'READELF' in os .environ :
727+ readelf = os .environ ['READELF' ]
728+ else :
729+ readelf = sh .which ('readelf' ).strip ()
730+ readelf = sh .Command (readelf ).bake ('-d' )
731+
732+ dest = dirname (soname )
733+
734+ for directory in objs_paths :
735+ for fn in os .listdir (directory ):
736+ fn = join (directory , fn )
737+
738+ if not fn .endswith ('.libs' ):
739+ continue
740+
741+ dirfn = fn [:- 1 ] + 'dirs'
742+ if not exists (dirfn ):
743+ continue
744+
745+ with open (fn ) as f :
746+ libs = f .read ().strip ().split (' ' )
747+ needed_libs = [lib for lib in libs
748+ if lib and
749+ lib not in blacklist_libs and
750+ lib not in found_libs ]
751+
752+ while needed_libs :
753+ print ('need libs:\n \t ' + '\n \t ' .join (needed_libs ))
754+
755+ start_needed_libs = needed_libs [:]
756+ found_sofiles = []
757+
758+ with open (dirfn ) as f :
759+ libdirs = f .read ().split ()
760+ for libdir in libdirs :
761+ if not needed_libs :
762+ break
763+
764+ if libdir == dest :
765+ # don't need to copy from dest to dest!
766+ continue
767+
768+ libdir = libdir .strip ()
769+ print ('scanning' , libdir )
770+ for lib in needed_libs [:]:
771+ if lib in found_libs :
772+ continue
773+
774+ if lib .endswith ('.a' ):
775+ needed_libs .remove (lib )
776+ found_libs .append (lib )
777+ continue
778+
779+ lib_a = 'lib' + lib + '.a'
780+ libpath_a = join (libdir , lib_a )
781+ lib_so = 'lib' + lib + '.so'
782+ libpath_so = join (libdir , lib_so )
783+ plain_so = lib + '.so'
784+ plainpath_so = join (libdir , plain_so )
785+
786+ sopath = None
787+ if exists (libpath_so ):
788+ sopath = libpath_so
789+ elif exists (plainpath_so ):
790+ sopath = plainpath_so
791+
792+ if sopath :
793+ print ('found' , lib , 'in' , libdir )
794+ found_sofiles .append (sopath )
795+ needed_libs .remove (lib )
796+ found_libs .append (lib )
797+ continue
798+
799+ if exists (libpath_a ):
800+ print ('found' , lib , '(static) in' , libdir )
801+ needed_libs .remove (lib )
802+ found_libs .append (lib )
803+ continue
804+
805+ for sofile in found_sofiles :
806+ print ('scanning dependencies for' , sofile )
807+ out = readelf (sofile )
808+ for line in out .splitlines ():
809+ needso = re_needso .match (line )
810+ if needso :
811+ lib = needso .group (1 )
812+ if (lib not in needed_libs
813+ and lib not in found_libs
814+ and lib not in blacklist_libs ):
815+ needed_libs .append (needso .group (1 ))
816+
817+ sofiles += found_sofiles
818+
819+ if needed_libs == start_needed_libs :
820+ raise RuntimeError (
821+ 'Failed to locate needed libraries!\n \t ' +
822+ '\n \t ' .join (needed_libs ))
823+
824+ print ('Copying libraries' )
825+ cp = sh .cp .bake ('-t' , dest )
826+ for lib in sofiles :
827+ shprint (cp , lib )
828+
0 commit comments