Skip to content

Commit

Permalink
libraries finding bug fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
abforce committed May 21, 2016
1 parent 2aa3917 commit c939176
Showing 1 changed file with 49 additions and 44 deletions.
93 changes: 49 additions & 44 deletions setup.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
#
#
# Copyright (c) 2013 Groundworks Technologies
#
#
# This code is part PyBFD module (libbfd & libopcodes extension module)
#

Expand Down Expand Up @@ -51,7 +51,7 @@ def initialize_options(self):

class InstallCustomCommandLine( install ):
description = "install"

user_options = install.user_options
user_options.append(
('with-static-binutils=', None, 'Path to specific bintutils')
Expand All @@ -65,7 +65,7 @@ class CustomBuildExtension( build_ext ):
PLATFORMS = {
"linux2": {
"libs": [
"/usr/lib"
"/usr/lib"
],
"includes": [
"/usr/include"
Expand All @@ -92,18 +92,18 @@ class CustomBuildExtension( build_ext ):

def __init__(self, *args, **kargs):
self.libs = None
self.includes = None
self.includes = None
self.platform = None
build_ext.__init__(self, *args, **kargs)
build_ext.__init__(self, *args, **kargs)
def initialize_options(self):
self.with_static_binutils = None # options..
build_ext.initialize_options(self)
def finalize_options(self):
self.set_undefined_options(
'build',
'build',
('with_static_binutils','with_static_binutils'))
self.set_undefined_options(
'install',
'install',
('with_static_binutils','with_static_binutils'))
build_ext.finalize_options(self)

Expand All @@ -116,17 +116,18 @@ def check_includes(self, incdir):

def find_binutils_libs(self, libdir, lib_ext):
"""Find Binutils libraries."""
bfd_expr = re.compile("(lib(?:bfd)|(?:opcodes))(.*?)\%s" % lib_ext )
bfd_expr = re.compile("(lib(?:bfd)|(?:opcodes))(.*?)\%s" % lib_ext )
libs = {}
for root, dirs, files in os.walk(libdir):
for f in files:
m = bfd_expr.search(f)
if m:
lib, version = m.groups()
fp = os.path.join(root, f)
if version in libs:
libs[ version ].append( f )
libs[ version ].append( fp )
else:
libs[ version ] = [f,]
libs[ version ] = [fp,]

# first, search for multiarch files.
# check if we found more than one version of the multiarch libs.
Expand All @@ -137,7 +138,7 @@ def find_binutils_libs(self, libdir, lib_ext):
return multiarch_libs.values()[0]
if len(multiarch_libs) == 1:
return multiarch_libs.values()[0]
# or use the default libs, or .. none
# or use the default libs, or .. none
return libs.get("",[])

def prepare_libs_for_cc(self, lib):
Expand All @@ -161,20 +162,19 @@ def generate_source_files( self ):
get_supported_machines, \
generate_supported_architectures_source, \
generate_supported_disassembler_header, \
gen_supported_archs
gen_supported_archs

#
# Step 1 . Get the patch to libopcodes and nm utility for further
# usage.
#
libs_dir, libs = self.libs
libs_dirs = [os.path.dirname(lib) for lib in self.libs]

libopcodes = [os.path.join(libs_dir,lib) \
for lib in libs if lib.startswith("libopcodes")][0]
libopcodes = [lib for lib in self.libs if os.path.basename(lib).startswith("libopcodes")][0]
print "[+] Detecting libbfd/libopcodes compiled architectures"

if self.with_static_binutils: # use the nm from the binutils distro

nms = [
os.path.join( libs_dir, "..", "bin", "nm" ), # default name of nm
os.path.join( libs_dir, "..", "bin", "gnm" ) # in OSX brew install binutils's nm as gnm.
Expand All @@ -185,7 +185,7 @@ def generate_source_files( self ):
path_to_nm = nm_fullpath
break
if path_to_nm == None:
raise Exception("no suitable 'nm' found.")
raise Exception("no suitable 'nm' found.")
else:
path_to_nm = "nm" # Use the nm in the $PATH (TODO: its assume that nm exists)
#
Expand All @@ -198,7 +198,7 @@ def generate_source_files( self ):

supported_archs = get_supported_architectures(
path_to_nm,
libopcodes,
libopcodes,
supported_machines,
self.with_static_binutils == None)

Expand All @@ -212,17 +212,17 @@ def generate_source_files( self ):
if self.with_static_binutils:
link_to_libs = [] # ...
else:
link_to_libs = [self.prepare_libs_for_cc(lib) for lib in libs]
c_compiler = new_compiler()
link_to_libs = [self.prepare_libs_for_cc(os.path.basename(lib)) for lib in self.libs]

c_compiler = new_compiler()
objects = c_compiler.compile(
[os.path.join(PACKAGE_DIR, "gen_bfd_archs.c"), ],
include_dirs = [self.includes,]
)
program = c_compiler.link_executable(
objects,
libraries = link_to_libs,
library_dirs = [libs_dir, ],
library_dirs = libs_dirs,
output_progname = "gen_bfd_archs",
output_dir = PACKAGE_DIR
)
Expand Down Expand Up @@ -270,7 +270,7 @@ def _darwin_current_arch(self):
if sys.maxsize > 2 ** 32: # 64bits.
return platform.mac_ver()[2] # Both Darwin and Python are 64bits.
else: # Python 32 bits
return platform.processor()
return platform.processor()

def build_extensions(self):
"""Compile the python extension module for further installation."""
Expand Down Expand Up @@ -313,45 +313,50 @@ def build_extensions(self):
for possible_lib_ext in self.platform["possible-lib-ext"]:
libs = self.find_binutils_libs(libdir, possible_lib_ext)
if libs:
self.libs = libdir, libs
if self.libs:
self.libs = self.libs + libs
else:
self.libs = libs
break

if self.libs == None:
raise Exception("unable to find binutils libraries.")

for lib in self.libs[1]:
print "[+] %s" % os.path.join(self.libs[0], lib)
for lib in self.libs:
print "[+] %s" % lib
#
# check for libopcodes / libbfd
#
libraries_path, libs = self.libs
if not all( [lib.startswith("libopcodes") or lib.startswith("libbfd") for lib in libs] ):
raise Exception("missing expected library (libopcodes / libbfd) in %s." % libraries_path)
libnames = [os.path.basename(lib) for lib in self.libs]
libraries_paths = [os.path.dirname(lib) for lib in self.libs]
libraries_paths = list(set(libraries_paths)) # removing duplicates
if not all( [lib.startswith("libopcodes") or lib.startswith("libbfd") for lib in libnames] ):
raise Exception("missing expected library (libopcodes / libbfd) in %s." % "\n".join(libraries_paths))

ext_libs_dir += libraries_paths

ext_libs_dir.append( libraries_path )

if self.with_static_binutils:
# use libs as extra objects...
ext_extra_objects.extend( [os.path.join(libraries_path,lib) for lib in libs] )
ext_extra_objects.extend( self.libs )
else:
ext_libs = [self.prepare_libs_for_cc(lib) for lib in libs]
ext_libs = [self.prepare_libs_for_cc(os.path.basename(lib)) for lib in self.libs]

# add dependecy to libiberty
if self.with_static_binutils or sys.platform == "darwin": # in OSX we always needs a static lib-iverty.
lib_liberty_partialpath = [libraries_path,]

lib_liberty_partialpath = libraries_paths
if sys.platform == "darwin": # in osx the lib-iberty is prefixe by "machine" ppc/i386/x86_64
lib_liberty_partialpath.append( self._darwin_current_arch() )
lib_liberty_partialpath.append( "libiberty.a" )

lib_liberty_fullpath = os.path.join(*lib_liberty_partialpath ) # merge the prefix and the path
if not os.path.isfile(lib_liberty_fullpath):
raise Exception("missing expected library (libiberty) in %s." % libraries_path)
raise Exception("missing expected library (libiberty) in %s." % "\n".join(libraries_paths))
ext_extra_objects.append(lib_liberty_fullpath)

# generate .py / .h files that depends of libopcodes / libbfd currently selected
final_supported_archs = self.generate_source_files()

# final hacks for OSX
if sys.platform == "darwin":
# fix arch value.
Expand All @@ -366,17 +371,17 @@ def build_extensions(self):
]
for d in dirs:
if os.path.exists(d):
ext_libs_dir.append(d)
ext_libs_dir.append(d)

# fix extensions.
# fix extensions.
for extension in self.extensions:
extension.include_dirs.extend( ext_includes )
extension.extra_objects.extend( ext_extra_objects )
extension.libraries.extend( ext_libs )
extension.library_dirs.extend( ext_libs_dir )

return build_ext.build_extensions(self)


def main():
try:
Expand Down Expand Up @@ -431,7 +436,7 @@ def main():
"Topic :: Utilities"
]
)

global final_supported_archs
if final_supported_archs:
print "\n[+] %s %s / Supported architectures:" % (MODULE_NAME, __version__)
Expand Down

0 comments on commit c939176

Please sign in to comment.