Updated script for ABI compliance check

pull/488/head
Anna Kogan 12 years ago
parent f608df9640
commit f9cf70e93e
  1. 338
      android/scripts/ABI_compat_generator.py

@ -1,130 +1,228 @@
#!/usr/bin/python #!/usr/bin/python
from optparse import OptionParser
from shutil import rmtree
import os import os
import sys
ANDROID_SDK_PATH = "/opt/android-sdk-linux" architecture = 'armeabi'
ANDROID_NDK_PATH = None excludedHeaders = set(['hdf5.h', 'cap_ios.h',
INSTALL_DIRECTORY = None 'eigen.hpp', 'cxeigen.hpp' #TOREMOVE
CLASS_PATH = None ])
TMP_HEADER_PATH="tmp_include" systemIncludes = ['sources/cxx-stl/gnu-libstdc++/4.6/include', \
HEADER_EXTS = set(['h', 'hpp']) '/opt/android-ndk-r8c/platforms/android-8/arch-arm', # TODO: check if this one could be passed as command line arg
SYS_INCLUDES = ["platforms/android-8/arch-arm/usr/include", "sources/cxx-stl/gnu-libstdc++/include", "sources/cxx-stl/gnu-libstdc++/libs/armeabi/include"] 'sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi-v7a/include']
targetLibs = ['libopencv_java.so']
PROJECT_NAME = "OpenCV-branch" preamble = ['Eigen/Core']
TARGET_LIBS = ["libopencv_java.so"] # TODO: get gcc_options automatically
ARCH = "armeabi" gcc_options = ['-fexceptions', '-frtti', '-Wno-psabi', '--sysroot=/opt/android-ndk-r8c/platforms/android-8/arch-arm', '-fpic', '-D__ARM_ARCH_5__', '-D__ARM_ARCH_5T__', '-D__ARM_ARCH_5E__', '-D__ARM_ARCH_5TE__', '-fsigned-char', '-march=armv5te', '-mtune=xscale', '-msoft-float', '-fdata-sections', '-ffunction-sections', '-Wa,--noexecstack ', '-W', '-Wall', '-Werror=return-type', '-Werror=address', '-Werror=sequence-point', '-Wformat', '-Werror=format-security', '-Wmissing-declarations', '-Wundef', '-Winit-self', '-Wpointer-arith', '-Wshadow', '-Wsign-promo', '-Wno-narrowing', '-fdiagnostics-show-option', '-fomit-frame-pointer', '-mthumb', '-fomit-frame-pointer', '-O3', '-DNDEBUG ', '-DNDEBUG']
GCC_OPTIONS = "-fpermissive" excludedOptionsPrefix = '-W'
EXCLUDE_HEADERS = set(["hdf5.h", "eigen.hpp", "cxeigen.hpp"]);
def FindClasses(root, prefix):
def GetHeaderFiles(root):
headers = []
for path in os.listdir(root):
if not os.path.isdir(os.path.join(root, path)) \
and os.path.splitext(path)[1] in ['.h', '.hpp'] \
and not path in excludedHeaders:
headers.append(os.path.join(root, path))
return sorted(headers)
def GetClasses(root, prefix):
classes = [] classes = []
if ("" != prefix): if ('' != prefix):
prefix = prefix + "." prefix = prefix + '.'
for path in os.listdir(root): for path in os.listdir(root):
currentPath = os.path.join(root, path) currentPath = os.path.join(root, path)
if (os.path.isdir(currentPath)): if (os.path.isdir(currentPath)):
classes += FindClasses(currentPath, prefix + path) classes += GetClasses(currentPath, prefix + path)
else: else:
name = str.split(path, ".")[0] name = str.split(path, '.')[0]
ext = str.split(path, ".")[1] ext = str.split(path, '.')[1]
if (ext == "class"): if (ext == 'class'):
#print("class: %s" % (prefix + name)) classes.append(prefix + name)
classes.append(prefix+name)
return classes return classes
def FindHeaders(root):
def GetJavaHHeaders():
print('\nGenerating JNI headers for Java API ...')
javahHeaders = os.path.join(managerDir, 'javah_generated_headers')
if os.path.exists(javahHeaders):
rmtree(javahHeaders)
os.makedirs(os.path.join(os.getcwd(), javahHeaders))
AndroidJavaDeps = os.path.join(SDK_path, 'platforms/android-11/android.jar')
classPath = os.path.join(managerDir, 'sdk/java/bin/classes')
if not os.path.exists(classPath):
print('Error: no Java classes found in \'%s\'' % classPath)
quit()
allJavaClasses = GetClasses(classPath, '')
if not allJavaClasses:
print('Error: no Java classes found')
quit()
for currentClass in allJavaClasses:
os.system('javah -d %s -classpath %s:%s %s' % (javahHeaders, classPath, \
AndroidJavaDeps, currentClass))
print('\nBuilding JNI headers list ...')
jniHeaders = GetHeaderFiles(javahHeaders)
return jniHeaders
def GetImmediateSubdirs(dir):
return [name for name in os.listdir(dir)
if os.path.isdir(os.path.join(dir, name))]
def GetOpenCVModules():
makefile = open(os.path.join(managerDir, 'sdk/native/jni/OpenCV.mk'), 'r')
makefileStr = makefile.read()
left = makefileStr.find('OPENCV_MODULES:=') + len('OPENCV_MODULES:=')
right = makefileStr[left:].find('\n')
modules = makefileStr[left:left+right].split()
modules = filter(lambda x: x != 'ts' and x != 'androidcamera', modules)
return modules
def FindHeaders():
headers = [] headers = []
for path in os.listdir(root):
currentPath = os.path.join(root, path) print('\nBuilding Native OpenCV header list ...')
if (os.path.isdir(currentPath)):
headers += FindHeaders(currentPath) cppHeadersFolder = os.path.join(managerDir, 'sdk/native/jni/include/opencv2')
else:
ext = str.split(path, ".")[-1] modulesFolders = GetImmediateSubdirs(cppHeadersFolder)
#print("%s: \"%s\"" % (currentPath, ext)) modules = GetOpenCVModules()
if (ext in HEADER_EXTS):
#print("Added as header file") cppHeaders = []
if (path not in EXCLUDE_HEADERS): for m in modules:
headers.append(currentPath) for f in modulesFolders:
moduleHeaders = []
if f == m:
moduleHeaders += GetHeaderFiles(os.path.join(cppHeadersFolder, f))
if m == 'flann':
flann = os.path.join(cppHeadersFolder, f, 'flann.hpp')
moduleHeaders.remove(flann)
moduleHeaders.insert(0, flann)
cppHeaders += moduleHeaders
cppHeaders += GetHeaderFiles(cppHeadersFolder)
headers += cppHeaders
cHeaders = GetHeaderFiles(os.path.join(managerDir, \
'sdk/native/jni/include/opencv'))
headers += cHeaders
headers += GetJavaHHeaders()
return headers return headers
if (len(sys.argv) < 3):
print("Error: Invalid command line arguments")
exit(-1) def FindLibraries():
libraries = []
INSTALL_DIRECTORY = sys.argv[1] for lib in targetLibs:
PROJECT_NAME = sys.argv[2] libraries.append(os.path.join(managerDir, 'sdk/native/libs', architecture, lib))
return libraries
CLASS_PATH = os.path.join(INSTALL_DIRECTORY, "sdk/java/bin/classes")
if (not os.path.exists(CLASS_PATH)):
print("Error: no java classes found in \"%s\"" % CLASS_PATH)
exit(-2) def FindIncludes():
includes = [os.path.join(managerDir, 'sdk', 'native', 'jni', 'include'),
if (os.environ.has_key("NDK_ROOT")): os.path.join(managerDir, 'sdk', 'native', 'jni', 'include', 'opencv'),
ANDROID_NDK_PATH = os.environ["NDK_ROOT"]; os.path.join(managerDir, 'sdk', 'native', 'jni', 'include', 'opencv2')]
print("Using Android NDK from NDK_ROOT (\"%s\")" % ANDROID_NDK_PATH)
for inc in systemIncludes:
if (not ANDROID_NDK_PATH): includes.append(os.path.join(NDK_path, inc))
pipe = os.popen("which ndk-build")
tmp = str.strip(pipe.readline(), "\n") return includes
while(not tmp):
tmp = str.strip(pipe.readline(), "\n")
pipe.close()
ANDROID_NDK_PATH = os.path.split(tmp)[0] def FilterGCCOptions():
print("Using Android NDK from PATH (\"%s\")" % ANDROID_NDK_PATH) gcc = filter(lambda x: not x.startswith(excludedOptionsPrefix), gcc_options)
return sorted(gcc)
print("Using Android SDK from \"%s\"" % ANDROID_SDK_PATH)
outputFileName = PROJECT_NAME + ".xml"
try: def WriteXml(version, headers, includes, libraries):
outputFile = open(outputFileName, "w") xmlName = version + '.xml'
except:
print("Error: Cannot open output file \"%s\" for writing" % outputFileName) print '\noutput file: ' + xmlName
try:
allJavaClasses = FindClasses(CLASS_PATH, "") xml = open(xmlName, 'w')
if (not allJavaClasses): except:
print("Error: No Java classes found :(") print 'Error: Cannot open output file "%s" for writing' % xmlName
exit(-1) quit()
if (not os.path.exists(TMP_HEADER_PATH)): xml.write('<descriptor>')
os.makedirs(os.path.join(os.getcwd(), TMP_HEADER_PATH))
xml.write('\n\n<version>')
print("Generating JNI headers for Java API ...") xml.write('\n\t%s' % version)
AndroidJavaDeps = os.path.join(ANDROID_SDK_PATH, "platforms/android-11/android.jar") xml.write('\n</version>')
for currentClass in allJavaClasses:
os.system("javah -d %s -classpath %s:%s %s" % (TMP_HEADER_PATH, CLASS_PATH, AndroidJavaDeps, currentClass)) xml.write('\n\n<headers>')
xml.write('\n\t%s' % '\n\t'.join(headers))
print("Building JNI headers list ...") xml.write('\n</headers>')
jniHeaders = FindHeaders(TMP_HEADER_PATH)
#print(jniHeaders) xml.write('\n\n<include_paths>')
xml.write('\n\t%s' % '\n\t'.join(includes))
print("Building Native OpenCV header list ...") xml.write('\n</include_paths>')
cHeaders = FindHeaders(os.path.join(INSTALL_DIRECTORY, "sdk/native/jni/include/opencv"))
cppHeaders = FindHeaders(os.path.join(INSTALL_DIRECTORY, "sdk/native/jni/include/opencv2")) # TODO: uncomment when Eigen problem is solved
#print(cHeaders) # xml.write('\n\n<include_preamble>')
#print(cppHeaders) # xml.write('\n\t%s' % '\n\t'.join(preamble))
# xml.write('\n</include_preamble>')
print("Writing config file ...")
outputFile.write("<descriptor>\n\n<version>\n\t%s\n</version>\n\n<headers>\n" % PROJECT_NAME) xml.write('\n\n<libs>')
outputFile.write("\t" + "\n\t".join(cHeaders)) xml.write('\n\t%s' % '\n\t'.join(libraries))
outputFile.write("\n\t" + "\n\t".join(cppHeaders)) xml.write('\n</libs>')
outputFile.write("\n\t" + "\n\t".join(jniHeaders))
outputFile.write("\n</headers>\n\n") xml.write('\n\n<gcc_options>')
xml.write('\n\t%s' % '\n\t'.join(gcc_options))
includes = [os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include"), xml.write('\n</gcc_options>')
os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include", "opencv"),
os.path.join(INSTALL_DIRECTORY, "sdk", "native", "jni", "include", "opencv2")] xml.write('\n\n</descriptor>')
for inc in SYS_INCLUDES:
includes.append(os.path.join(ANDROID_NDK_PATH, inc))
if __name__ == '__main__':
outputFile.write("<include_paths>\n\t%s\n</include_paths>\n\n" % "\n\t".join(includes)) usage = '%prog <OpenCV_Manager install directory> <OpenCV_Manager version>'
parser = OptionParser(usage = usage)
libraries = []
for lib in TARGET_LIBS: args = parser.parse_args()
libraries.append(os.path.join(INSTALL_DIRECTORY, "sdk/native/libs", ARCH, lib)) if 2 != len(args):
parser.print_help()
outputFile.write("<libs>\n\t%s\n</libs>\n\n" % "\n\t".join(libraries)) quit()
outputFile.write("<gcc_options>\n\t%s\n</gcc_options>\n\n</descriptor>" % GCC_OPTIONS)
managerDir = args[1][0]
print("done!") version = args[1][1]
NDK_path = '/opt/android-ndk-r8c'
print '\nUsing Android NDK from "%s"' % NDK_path
SDK_path = '~/NVPACK/android-sdk-linux'
print '\nUsing Android SDK from "%s"' % SDK_path
headers = FindHeaders()
includes = FindIncludes()
libraries = FindLibraries()
gcc_options = FilterGCCOptions()
WriteXml(version, headers, includes, libraries)

Loading…
Cancel
Save