arm_compute v17.04
diff --git a/sconscript b/sconscript
index e37227b..a821b9c 100644
--- a/sconscript
+++ b/sconscript
@@ -23,157 +23,28 @@
import os.path
import re
import subprocess
+import SCons
-VERSION = "v17.03.1"
+VERSION = "v17.04"
+SONAME_VERSION="1.0.0"
vars = Variables('scons')
vars.Add(EnumVariable('debug','Debug (default=0)', '0', allowed_values=('0','1')))
vars.Add(EnumVariable('asserts','Enable asserts (This flag is forced to 1 for debug=1) (default=0)', '0', allowed_values=('0','1')))
-vars.Add(EnumVariable('arch','Target Architecture (default=armv7a)', 'armv7a', allowed_values=('armv7a','arm64-v8a','arm64-v8.2-a','x86')))
+vars.Add(EnumVariable('arch','Target Architecture (default=armv7a)', 'armv7a', allowed_values=('armv7a','arm64-v8a','arm64-v8.2-a','x86_32','x86_64')))
vars.Add(EnumVariable('os','Target OS (default=linux)', 'linux', allowed_values=('linux','android','bare_metal')))
vars.Add(EnumVariable('build','Build type: (default=cross_compile)', 'cross_compile', allowed_values=('native','cross_compile')))
vars.Add(EnumVariable('Werror','Enable/disable the -Werror compilation flag (Default=1)', '1', allowed_values=('0','1')))
vars.Add(EnumVariable('opencl','Enable OpenCL support(Default=1)', '1', allowed_values=('0','1')))
vars.Add(EnumVariable('neon','Enable Neon support(Default=0)', '0', allowed_values=('0','1')))
vars.Add(EnumVariable('embed_kernels', 'Embed OpenCL kernels in library binary(Default=0)', '0', allowed_values=('0','1')))
+vars.Add(BoolVariable('set_soname','Set the library\'s soname and shlibversion (Requires SCons 2.4 or above)', 0))
+vars.Add(('extra_cxx_flags','Extra CXX flags to be appended to the build command', ''))
env = Environment(platform='posix', variables = vars, ENV = os.environ)
-flags = ['-D_GLIBCXX_USE_NANOSLEEP','-Wno-deprecated-declarations','-Wall','-DARCH_ARM',
- '-Wextra','-Wno-unused-parameter','-pedantic','-Wdisabled-optimization','-Wformat=2',
- '-Winit-self','-Wmissing-include-dirs','-Wstrict-overflow=2','-Wswitch-default',
- '-fpermissive','-std=c++11','-Wno-vla','-Woverloaded-virtual',
- '-Wctor-dtor-privacy','-Wsign-promo','-Weffc++','-Wno-format-nonliteral','-Wno-overlength-strings','-Wno-strict-overflow']
-
Help(vars.GenerateHelpText(env))
-if env['neon'] == '1' and env['arch'] == 'x86':
- print "Cannot compile Neon for x86"
- Exit(1)
-
-
-if os.environ.get('CXX','g++') == 'clang++':
- flags += ['-Wno-format-nonliteral','-Wno-deprecated-increment-bool','-Wno-vla-extension','-Wno-mismatched-tags']
-else:
- flags += ['-Wlogical-op','-Wnoexcept','-Wstrict-null-sentinel']
-
-files_to_delete = []
-
-#Generate string with build options library version to embed in the library:
-git_hash="unknown"
-try:
- git_hash = subprocess.check_output(["git", "rev-parse","HEAD"])
-except subprocess.CalledProcessError:
- pass
-
-version_filename = "%s/arm_compute_version.embed" % os.path.dirname(Glob("src/core/*")[0].rstr())
-build_info = "\"arm_compute_version=%s Build options: %s Git hash=%s\"" % (VERSION, vars.args, git_hash.strip())
-open(version_filename,"w").write(build_info)
-files_to_delete.append( version_filename )
-
-def build_library(name, sources, libs, static=False):
- if static:
- obj = env.StaticLibrary(name, source = sources, LIBS=libs )
- else:
- obj = env.SharedLibrary(name, source = sources, LIBS=libs )
- Default(obj)
- return obj
-
-def resolve_includes(target, source, env):
- # File collection
- FileEntry = collections.namedtuple('FileEntry', 'target_name file_contents')
-
- # Include pattern
- pattern = re.compile("#include \"(.*)\"")
-
- # Get file contents
- files = []
- for s in source:
- name = s.rstr().split("/")[-1]
- contents = s.get_contents().splitlines()
- embed_target_name = s.abspath + "embed"
- entry = FileEntry(target_name=embed_target_name, file_contents=contents)
- files.append((name,entry))
-
- # Create dictionary of tupled list
- files_dict = dict(files)
-
- # Check for includes (can only be files in the same folder)
- final_files = []
- for file in files:
- done = False
- tmp_file = file[1].file_contents
- while not(done):
- file_count = 0
- updated_file = []
- for line in tmp_file:
- found = pattern.search(line)
- if found:
- include_file = found.group(1)
- data = files_dict[include_file].file_contents
- updated_file.extend(data)
- else:
- updated_file.append(line)
- file_count += 1
-
- # Check if all include are replaced.
- if file_count == len(tmp_file):
- done = True
-
- # Update temp file
- tmp_file = updated_file
-
- # Append and prepend string literal identifiers and add expanded file to final list
- tmp_file.insert(0, "R\"(\n")
- tmp_file.append("\n)\"")
- entry = FileEntry(target_name=file[1].target_name, file_contents=tmp_file)
- final_files.append((file[0], entry))
-
- # Write output files
- for file in final_files:
- out_file = open(file[1].target_name, 'w+')
- contents = file[1].file_contents
- for line in contents:
- out_file.write("%s\n" % line)
-
-core_libs = []
-libs = []
-
-prefix=""
-
-if env['arch'] == 'armv7a':
- flags += ['-march=armv7-a','-mthumb','-mfpu=neon']
-
- if env['os'] in ['linux','bare_metal']:
- prefix = "arm-linux-gnueabihf-"
- flags += ['-mfloat-abi=hard']
- elif env['os'] == 'android':
- prefix = "arm-linux-androideabi-"
- flags += ['-mfloat-abi=softfp']
-elif env['arch'] == 'arm64-v8a':
- flags += ['-march=armv8-a']
- if env['os'] in ['linux','bare_metal']:
- prefix = "aarch64-linux-gnu-"
- elif env['os'] == 'android':
- prefix = "aarch64-linux-android-"
-elif env['arch'] == 'arm64-v8.2-a':
- flags += ['-march=armv8.2-a+fp16+simd']
- flags += ['-DARM_COMPUTE_ENABLE_FP16']
- if env['os'] in ['linux','bare_metal']:
- prefix = "aarch64-linux-gnu-"
- elif env['os'] == 'android':
- prefix = "aarch64-linux-android-"
-
-if env['build'] == 'native':
- prefix = ""
-
-env['CC'] = prefix + os.environ.get('CC','gcc')
-env['CXX'] = prefix + os.environ.get('CXX','g++')
-env['LD'] = prefix + "ld"
-env['AS'] = prefix + "as"
-env['AR'] = prefix + "ar"
-env['RANLIB'] = prefix + "ranlib"
-
def version_at_least(version, required):
end = min(len(version), len(required))
@@ -185,18 +56,181 @@
return True
-try:
- compiler_ver = subprocess.check_output( [env['CXX'] , "-dumpversion"] ).strip()
-except OSError:
- print "ERROR: Compiler not found"
- compiler_ver = ""
+if not GetOption("help"):
+ flags = ['-D_GLIBCXX_USE_NANOSLEEP','-Wno-deprecated-declarations','-Wall','-DARCH_ARM',
+ '-Wextra','-Wno-unused-parameter','-pedantic','-Wdisabled-optimization','-Wformat=2',
+ '-Winit-self','-Wstrict-overflow=2','-Wswitch-default',
+ '-fpermissive','-std=c++11','-Wno-vla','-Woverloaded-virtual',
+ '-Wctor-dtor-privacy','-Wsign-promo','-Weffc++','-Wno-format-nonliteral','-Wno-overlength-strings','-Wno-strict-overflow']
-if compiler_ver != "":
- if env['arch'] == 'arm64-v8.2-a' and not version_at_least(compiler_ver, '6.2.1'):
- print "GCC 6.2.1 or newer is required to compile armv8.2-a code"
+
+ if env['neon'] == '1' and 'x86' in env['arch']:
+ print "Cannot compile NEON for x86"
+ Exit(1)
+
+ if env['set_soname'] and not version_at_least( SCons.__version__, "2.4"):
+ print "Setting the library's SONAME / SHLIBVERSION requires SCons 2.4 or above"
+ print "Update your version of SCons or use set_soname=0"
+ Exit(1)
+
+ if os.environ.get('CXX','g++') == 'clang++':
+ flags += ['-Wno-format-nonliteral','-Wno-deprecated-increment-bool','-Wno-vla-extension','-Wno-mismatched-tags']
+ else:
+ flags += ['-Wlogical-op','-Wnoexcept','-Wstrict-null-sentinel']
+
+ files_to_delete = []
+
+#Generate string with build options library version to embed in the library:
+ git_hash="unknown"
+ try:
+ git_hash = subprocess.check_output(["git", "rev-parse","HEAD"])
+ except OSError: # In case git is not present
+ pass
+ except subprocess.CalledProcessError:
+ pass
+
+ version_filename = "%s/arm_compute_version.embed" % os.path.dirname(Glob("src/core/*")[0].rstr())
+ build_info = "\"arm_compute_version=%s Build options: %s Git hash=%s\"" % (VERSION, vars.args, git_hash.strip())
+ open(version_filename,"w").write(build_info)
+ files_to_delete.append( version_filename )
+
+ def build_library(name, sources, libs, static=False):
+ if static:
+ obj = env.StaticLibrary(name, source = sources, LIBS=libs )
+ else:
+ if env['set_soname']:
+ obj = env.SharedLibrary(name, source = sources, LIBS=libs, SHLIBVERSION=SONAME_VERSION)
+ symlinks = []
+ # Manually delete symlinks or SCons will get confused:
+ directory = os.path.dirname( obj[0].path )
+ library_prefix = obj[0].path[:-(1+len(SONAME_VERSION))]
+ real_lib="%s.%s" % (library_prefix, SONAME_VERSION)
+ for f in Glob( "#%s*" % library_prefix):
+ if str(f) != real_lib:
+ symlinks.append("%s/%s" % (directory,str(f)))
+ clean = env.Command('clean-%s' % str(obj[0]), [], Delete(symlinks))
+ Default(clean)
+ Depends(obj, clean)
+ else:
+ obj = env.SharedLibrary(name, source = sources, LIBS=libs)
+
+ Default(obj)
+ return obj
+
+ def resolve_includes(target, source, env):
+ # File collection
+ FileEntry = collections.namedtuple('FileEntry', 'target_name file_contents')
+
+ # Include pattern
+ pattern = re.compile("#include \"(.*)\"")
+
+ # Get file contents
+ files = []
+ for s in source:
+ name = s.rstr().split("/")[-1]
+ contents = s.get_contents().splitlines()
+ embed_target_name = s.abspath + "embed"
+ entry = FileEntry(target_name=embed_target_name, file_contents=contents)
+ files.append((name,entry))
+
+ # Create dictionary of tupled list
+ files_dict = dict(files)
+
+ # Check for includes (can only be files in the same folder)
+ final_files = []
+ for file in files:
+ done = False
+ tmp_file = file[1].file_contents
+ while not(done):
+ file_count = 0
+ updated_file = []
+ for line in tmp_file:
+ found = pattern.search(line)
+ if found:
+ include_file = found.group(1)
+ data = files_dict[include_file].file_contents
+ updated_file.extend(data)
+ else:
+ updated_file.append(line)
+ file_count += 1
+
+ # Check if all include are replaced.
+ if file_count == len(tmp_file):
+ done = True
+
+ # Update temp file
+ tmp_file = updated_file
+
+ # Append and prepend string literal identifiers and add expanded file to final list
+ tmp_file.insert(0, "R\"(\n")
+ tmp_file.append("\n)\"")
+ entry = FileEntry(target_name=file[1].target_name, file_contents=tmp_file)
+ final_files.append((file[0], entry))
+
+ # Write output files
+ for file in final_files:
+ out_file = open(file[1].target_name, 'w+')
+ contents = file[1].file_contents
+ for line in contents:
+ out_file.write("%s\n" % line)
+
+ core_libs = []
+ libs = []
+
+ prefix=""
+
+ if env['arch'] == 'armv7a':
+ flags += ['-march=armv7-a','-mthumb','-mfpu=neon']
+
+ if env['os'] in ['linux','bare_metal']:
+ prefix = "arm-linux-gnueabihf-"
+ flags += ['-mfloat-abi=hard']
+ elif env['os'] == 'android':
+ prefix = "arm-linux-androideabi-"
+ flags += ['-mfloat-abi=softfp']
+ elif env['arch'] == 'arm64-v8a':
+ flags += ['-march=armv8-a']
+ if env['os'] in ['linux','bare_metal']:
+ prefix = "aarch64-linux-gnu-"
+ elif env['os'] == 'android':
+ prefix = "aarch64-linux-android-"
+ elif env['arch'] == 'arm64-v8.2-a':
+ flags += ['-march=armv8.2-a+fp16+simd']
+ flags += ['-DARM_COMPUTE_ENABLE_FP16']
+ if env['os'] in ['linux','bare_metal']:
+ prefix = "aarch64-linux-gnu-"
+ elif env['os'] == 'android':
+ prefix = "aarch64-linux-android-"
+ elif env['arch'] == 'x86_32':
+ flags += ['-m32']
+ elif env['arch'] == 'x86_64':
+ flags += ['-m64']
+
+ if env['build'] == 'native':
+ prefix = ""
+
+ env['CC'] = prefix + os.environ.get('CC','gcc')
+ env['CXX'] = prefix + os.environ.get('CXX','g++')
+ env['LD'] = prefix + "ld"
+ env['AS'] = prefix + "as"
+ env['AR'] = prefix + "ar"
+ env['RANLIB'] = prefix + "ranlib"
+
+ try:
+ compiler_ver = subprocess.check_output( [env['CXX'] , "-dumpversion"] ).strip()
+ except OSError:
+ print "ERROR: Compiler '%s' not found" % env['CXX']
Exit(1)
if os.environ.get('CXX','g++') == 'g++':
+ if env['arch'] == 'arm64-v8.2-a' and not version_at_least(compiler_ver, '6.2.1'):
+ print "GCC 6.2.1 or newer is required to compile armv8.2-a code"
+ Exit(1)
+
+ if env['arch'] == 'arm64-v8a' and not version_at_least(compiler_ver, '4.9'):
+ print "GCC 4.9 or newer is required to compile NEON code for AArch64"
+ Exit(1)
+
if version_at_least(compiler_ver, '6.1'):
flags += ['-Wno-ignored-attributes']
@@ -238,6 +272,7 @@
env.Append(CPPPATH=['.','#include'])
env.Append(LIBPATH=['#build','.'])
env.Append(CXXFLAGS=flags)
+ env.Append(CXXFLAGS=env['extra_cxx_flags'])
core_files = Glob('src/core/*.cpp')
core_files += Glob('src/core/CPP/*.cpp')
@@ -246,8 +281,9 @@
embed_files = []
core_files += Glob('src/core/CPP/kernels/*.cpp')
- # CLHarrisCorners uses the Scheduler to run multithreaded CPP kernels
- core_files += Glob('src/runtime/CPP/CPPScheduler.cpp')
+
+ files += Glob('src/runtime/CPP/*.cpp')
+
if env['opencl'] == '1':
example_libs += ['OpenCL']
core_files += Glob('src/core/CL/*.cpp')
@@ -295,14 +331,14 @@
objects.append(arm_compute_so)
Export('arm_compute_so')
- # Delete produced embed files
+# Delete produced embed files
clean_embed = env.Command('clean-embed', [], Delete(files_to_delete))
Default(clean_embed)
env.Depends(clean_embed, objects)
alias = env.Alias("arm_compute",objects)
Default(alias)
- # Build examples
+# Build examples
test_helpers = env.Object("test_helpers/Utils.cpp")
if env['opencl'] == '1' and env['neon'] == '1':