mirror of https://github.com/opencv/opencv.git
parent
f608df9640
commit
f9cf70e93e
1 changed files with 218 additions and 120 deletions
@ -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…
Reference in new issue