You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							451 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
	
	
							451 lines
						
					
					
						
							12 KiB
						
					
					
				| import os
 | |
| import subprocess
 | |
| import sys
 | |
| import sysconfig
 | |
| import platform
 | |
| import numpy as np
 | |
| 
 | |
| import SCons.Errors
 | |
| 
 | |
| SCons.Warnings.warningAsException(True)
 | |
| 
 | |
| TICI = os.path.isfile('/TICI')
 | |
| AGNOS = TICI
 | |
| 
 | |
| Decider('MD5-timestamp')
 | |
| 
 | |
| AddOption('--extras',
 | |
|           action='store_true',
 | |
|           help='build misc extras, like setup and installer files')
 | |
| 
 | |
| AddOption('--kaitai',
 | |
|           action='store_true',
 | |
|           help='Regenerate kaitai struct parsers')
 | |
| 
 | |
| AddOption('--asan',
 | |
|           action='store_true',
 | |
|           help='turn on ASAN')
 | |
| 
 | |
| AddOption('--ubsan',
 | |
|           action='store_true',
 | |
|           help='turn on UBSan')
 | |
| 
 | |
| AddOption('--clazy',
 | |
|           action='store_true',
 | |
|           help='build with clazy')
 | |
| 
 | |
| AddOption('--compile_db',
 | |
|           action='store_true',
 | |
|           help='build clang compilation database')
 | |
| 
 | |
| AddOption('--snpe',
 | |
|           action='store_true',
 | |
|           help='use SNPE on PC')
 | |
| 
 | |
| AddOption('--external-sconscript',
 | |
|           action='store',
 | |
|           metavar='FILE',
 | |
|           dest='external_sconscript',
 | |
|           help='add an external SConscript to the build')
 | |
| 
 | |
| AddOption('--no-thneed',
 | |
|           action='store_true',
 | |
|           dest='no_thneed',
 | |
|           help='avoid using thneed')
 | |
| 
 | |
| AddOption('--pc-thneed',
 | |
|           action='store_true',
 | |
|           dest='pc_thneed',
 | |
|           help='use thneed on pc')
 | |
| 
 | |
| AddOption('--no-test',
 | |
|           action='store_false',
 | |
|           dest='test',
 | |
|           default=os.path.islink(Dir('#laika/').abspath),
 | |
|           help='skip building test files')
 | |
| 
 | |
| real_arch = arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
 | |
| if platform.system() == "Darwin":
 | |
|   arch = "Darwin"
 | |
| 
 | |
| if arch == "aarch64" and AGNOS:
 | |
|   arch = "larch64"
 | |
| 
 | |
| 
 | |
| lenv = {
 | |
|   "PATH": os.environ['PATH'],
 | |
|   "LD_LIBRARY_PATH": [Dir(f"#third_party/acados/{arch}/lib").abspath],
 | |
|   "PYTHONPATH": Dir("#").abspath,
 | |
| 
 | |
|   "ACADOS_SOURCE_DIR": Dir("#third_party/acados/include/acados").abspath,
 | |
|   "ACADOS_PYTHON_INTERFACE_PATH": Dir("#third_party/acados/acados_template").abspath,
 | |
|   "TERA_PATH": Dir("#").abspath + f"/third_party/acados/{arch}/t_renderer"
 | |
| }
 | |
| 
 | |
| rpath = lenv["LD_LIBRARY_PATH"].copy()
 | |
| 
 | |
| if arch == "larch64":
 | |
|   lenv["LD_LIBRARY_PATH"] += ['/data/data/com.termux/files/usr/lib']
 | |
| 
 | |
|   cpppath = [
 | |
|     "#third_party/opencl/include",
 | |
|   ]
 | |
| 
 | |
|   libpath = [
 | |
|     "/usr/local/lib",
 | |
|     "/usr/lib",
 | |
|     "/system/vendor/lib64",
 | |
|     f"#third_party/acados/{arch}/lib",
 | |
|   ]
 | |
| 
 | |
|   libpath += [
 | |
|     "#third_party/snpe/larch64",
 | |
|     "#third_party/libyuv/larch64/lib",
 | |
|     "/usr/lib/aarch64-linux-gnu"
 | |
|   ]
 | |
|   cflags = ["-DQCOM2", "-mcpu=cortex-a57"]
 | |
|   cxxflags = ["-DQCOM2", "-mcpu=cortex-a57"]
 | |
|   rpath += ["/usr/local/lib"]
 | |
| else:
 | |
|   cflags = []
 | |
|   cxxflags = []
 | |
|   cpppath = []
 | |
| 
 | |
|   # MacOS
 | |
|   if arch == "Darwin":
 | |
|     if real_arch == "x86_64":
 | |
|       lenv["TERA_PATH"] = Dir("#").abspath + f"/third_party/acados/Darwin_x86_64/t_renderer"
 | |
| 
 | |
|     brew_prefix = subprocess.check_output(['brew', '--prefix'], encoding='utf8').strip()
 | |
|     yuv_dir = "mac" if real_arch != "arm64" else "mac_arm64"
 | |
|     libpath = [
 | |
|       f"#third_party/libyuv/{yuv_dir}/lib",
 | |
|       f"{brew_prefix}/lib",
 | |
|       f"{brew_prefix}/Library",
 | |
|       f"{brew_prefix}/opt/openssl@3.0/lib",
 | |
|       f"{brew_prefix}/Cellar",
 | |
|       "/System/Library/Frameworks/OpenGL.framework/Libraries",
 | |
|     ]
 | |
|     if real_arch == "x86_64":
 | |
|       libpath.append(f"#third_party/acados/Darwin_x86_64/lib")
 | |
|     else:
 | |
|       libpath.append(f"#third_party/acados/{arch}/lib")
 | |
| 
 | |
|     cflags += ["-DGL_SILENCE_DEPRECATION"]
 | |
|     cxxflags += ["-DGL_SILENCE_DEPRECATION"]
 | |
|     cpppath += [
 | |
|       f"{brew_prefix}/include",
 | |
|       f"{brew_prefix}/opt/openssl@3.0/include",
 | |
|     ]
 | |
|   # Linux 86_64
 | |
|   else:
 | |
|     libpath = [
 | |
|       "#third_party/acados/x86_64/lib",
 | |
|       "#third_party/snpe/x86_64-linux-clang",
 | |
|       "#third_party/libyuv/x64/lib",
 | |
|       "#third_party/mapbox-gl-native-qt/x86_64",
 | |
|       "#cereal",
 | |
|       "#common",
 | |
|       "/usr/lib",
 | |
|       "/usr/local/lib",
 | |
|     ]
 | |
| 
 | |
|   rpath += [
 | |
|     Dir("#third_party/snpe/x86_64-linux-clang").abspath,
 | |
|     Dir("#cereal").abspath,
 | |
|     Dir("#common").abspath
 | |
|   ]
 | |
| 
 | |
| if GetOption('asan'):
 | |
|   ccflags = ["-fsanitize=address", "-fno-omit-frame-pointer"]
 | |
|   ldflags = ["-fsanitize=address"]
 | |
| elif GetOption('ubsan'):
 | |
|   ccflags = ["-fsanitize=undefined"]
 | |
|   ldflags = ["-fsanitize=undefined"]
 | |
| else:
 | |
|   ccflags = []
 | |
|   ldflags = []
 | |
| 
 | |
| # no --as-needed on mac linker
 | |
| if arch != "Darwin":
 | |
|   ldflags += ["-Wl,--as-needed", "-Wl,--no-undefined"]
 | |
| 
 | |
| # Enable swaglog include in submodules
 | |
| cflags += ['-DSWAGLOG="\\"common/swaglog.h\\""']
 | |
| cxxflags += ['-DSWAGLOG="\\"common/swaglog.h\\""']
 | |
| 
 | |
| env = Environment(
 | |
|   ENV=lenv,
 | |
|   CCFLAGS=[
 | |
|     "-g",
 | |
|     "-fPIC",
 | |
|     "-O2",
 | |
|     "-Wunused",
 | |
|     "-Werror",
 | |
|     "-Wshadow",
 | |
|     "-Wno-unknown-warning-option",
 | |
|     "-Wno-deprecated-register",
 | |
|     "-Wno-register",
 | |
|     "-Wno-inconsistent-missing-override",
 | |
|     "-Wno-c99-designator",
 | |
|     "-Wno-reorder-init-list",
 | |
|     "-Wno-error=unused-but-set-variable",
 | |
|   ] + cflags + ccflags,
 | |
| 
 | |
|   CPPPATH=cpppath + [
 | |
|     "#",
 | |
|     "#third_party/acados/include",
 | |
|     "#third_party/acados/include/blasfeo/include",
 | |
|     "#third_party/acados/include/hpipm/include",
 | |
|     "#third_party/catch2/include",
 | |
|     "#third_party/libyuv/include",
 | |
|     "#third_party/json11",
 | |
|     "#third_party/curl/include",
 | |
|     "#third_party/linux/include",
 | |
|     "#third_party/snpe/include",
 | |
|     "#third_party/mapbox-gl-native-qt/include",
 | |
|     "#third_party/qrcode",
 | |
|     "#third_party",
 | |
|     "#cereal",
 | |
|     "#opendbc/can",
 | |
|   ],
 | |
| 
 | |
|   CC='clang',
 | |
|   CXX='clang++',
 | |
|   LINKFLAGS=ldflags,
 | |
| 
 | |
|   RPATH=rpath,
 | |
| 
 | |
|   CFLAGS=["-std=gnu11"] + cflags,
 | |
|   CXXFLAGS=["-std=c++1z"] + cxxflags,
 | |
|   LIBPATH=libpath + [
 | |
|     "#cereal",
 | |
|     "#third_party",
 | |
|     "#opendbc/can",
 | |
|     "#selfdrive/boardd",
 | |
|     "#common",
 | |
|   ],
 | |
|   CYTHONCFILESUFFIX=".cpp",
 | |
|   COMPILATIONDB_USE_ABSPATH=True,
 | |
|   tools=["default", "cython", "compilation_db"],
 | |
| )
 | |
| 
 | |
| if arch == "Darwin":
 | |
|   env['RPATHPREFIX'] = "-rpath "
 | |
| 
 | |
| if GetOption('compile_db'):
 | |
|   env.CompilationDatabase('compile_commands.json')
 | |
| 
 | |
| # Setup cache dir
 | |
| cache_dir = '/data/scons_cache' if AGNOS else '/tmp/scons_cache'
 | |
| CacheDir(cache_dir)
 | |
| Clean(["."], cache_dir)
 | |
| 
 | |
| node_interval = 5
 | |
| node_count = 0
 | |
| def progress_function(node):
 | |
|   global node_count
 | |
|   node_count += node_interval
 | |
|   sys.stderr.write("progress: %d\n" % node_count)
 | |
| 
 | |
| if os.environ.get('SCONS_PROGRESS'):
 | |
|   Progress(progress_function, interval=node_interval)
 | |
| 
 | |
| SHARED = False
 | |
| 
 | |
| # TODO: this can probably be removed
 | |
| def abspath(x):
 | |
|   if arch == 'aarch64':
 | |
|     pth = os.path.join("/data/pythonpath", x[0].path)
 | |
|     env.Depends(pth, x)
 | |
|     return File(pth)
 | |
|   else:
 | |
|     # rpath works elsewhere
 | |
|     return x[0].path.rsplit("/", 1)[1][:-3]
 | |
| 
 | |
| # Cython build environment
 | |
| py_include = sysconfig.get_paths()['include']
 | |
| envCython = env.Clone()
 | |
| envCython["CPPPATH"] += [py_include, np.get_include()]
 | |
| envCython["CCFLAGS"] += ["-Wno-#warnings", "-Wno-shadow", "-Wno-deprecated-declarations"]
 | |
| 
 | |
| envCython["LIBS"] = []
 | |
| if arch == "Darwin":
 | |
|   envCython["LINKFLAGS"] = ["-bundle", "-undefined", "dynamic_lookup"]
 | |
| elif arch == "aarch64":
 | |
|   envCython["LINKFLAGS"] = ["-shared"]
 | |
|   envCython["LIBS"] = [os.path.basename(py_include)]
 | |
| else:
 | |
|   envCython["LINKFLAGS"] = ["-pthread", "-shared"]
 | |
| 
 | |
| Export('envCython')
 | |
| 
 | |
| # Qt build environment
 | |
| qt_env = env.Clone()
 | |
| qt_modules = ["Widgets", "Gui", "Core", "Network", "Concurrent", "Multimedia", "Quick", "Qml", "QuickWidgets", "Location", "Positioning", "DBus", "Xml"]
 | |
| 
 | |
| qt_libs = []
 | |
| if arch == "Darwin":
 | |
|   if real_arch == "arm64":
 | |
|     qt_env['QTDIR'] = "/opt/homebrew/opt/qt@5"
 | |
|   else:
 | |
|     qt_env['QTDIR'] = "/usr/local/opt/qt@5"
 | |
|   qt_dirs = [
 | |
|     os.path.join(qt_env['QTDIR'], "include"),
 | |
|   ]
 | |
|   qt_dirs += [f"{qt_env['QTDIR']}/include/Qt{m}" for m in qt_modules]
 | |
|   qt_env["LINKFLAGS"] += ["-F" + os.path.join(qt_env['QTDIR'], "lib")]
 | |
|   qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
 | |
|   qt_env.AppendENVPath('PATH', os.path.join(qt_env['QTDIR'], "bin"))
 | |
| else:
 | |
|   qt_install_prefix = subprocess.check_output(['qmake', '-query', 'QT_INSTALL_PREFIX'], encoding='utf8').strip()
 | |
|   qt_install_headers = subprocess.check_output(['qmake', '-query', 'QT_INSTALL_HEADERS'], encoding='utf8').strip()
 | |
| 
 | |
|   qt_env['QTDIR'] = qt_install_prefix
 | |
|   qt_dirs = [
 | |
|     f"{qt_install_headers}",
 | |
|     f"{qt_install_headers}/QtGui/5.12.8/QtGui",
 | |
|   ]
 | |
|   qt_dirs += [f"{qt_install_headers}/Qt{m}" for m in qt_modules]
 | |
| 
 | |
|   qt_libs = [f"Qt5{m}" for m in qt_modules]
 | |
|   if arch == "larch64":
 | |
|     qt_libs += ["GLESv2", "wayland-client"]
 | |
|     qt_env.PrependENVPath('PATH', Dir("#third_party/qt5/larch64/bin/").abspath)
 | |
|   elif arch != "Darwin":
 | |
|     qt_libs += ["GL"]
 | |
| qt_env['QT3DIR'] = qt_env['QTDIR']
 | |
| 
 | |
| # compatibility for older SCons versions
 | |
| try:
 | |
|   qt_env.Tool('qt3')
 | |
| except SCons.Errors.UserError:
 | |
|   qt_env.Tool('qt')
 | |
| 
 | |
| qt_env['CPPPATH'] += qt_dirs + ["#selfdrive/ui/qt/"]
 | |
| qt_flags = [
 | |
|   "-D_REENTRANT",
 | |
|   "-DQT_NO_DEBUG",
 | |
|   "-DQT_WIDGETS_LIB",
 | |
|   "-DQT_GUI_LIB",
 | |
|   "-DQT_QUICK_LIB",
 | |
|   "-DQT_QUICKWIDGETS_LIB",
 | |
|   "-DQT_QML_LIB",
 | |
|   "-DQT_CORE_LIB",
 | |
|   "-DQT_MESSAGELOGCONTEXT",
 | |
| ]
 | |
| qt_env['CXXFLAGS'] += qt_flags
 | |
| qt_env['LIBPATH'] += ['#selfdrive/ui']
 | |
| qt_env['LIBS'] = qt_libs
 | |
| qt_env['QT_MOCHPREFIX'] = cache_dir + '/moc_files/moc_'
 | |
| 
 | |
| if GetOption("clazy"):
 | |
|   checks = [
 | |
|     "level0",
 | |
|     "level1",
 | |
|     "no-range-loop",
 | |
|     "no-non-pod-global-static",
 | |
|   ]
 | |
|   qt_env['CXX'] = 'clazy'
 | |
|   qt_env['ENV']['CLAZY_IGNORE_DIRS'] = qt_dirs[0]
 | |
|   qt_env['ENV']['CLAZY_CHECKS'] = ','.join(checks)
 | |
| 
 | |
| Export('env', 'qt_env', 'arch', 'real_arch', 'SHARED')
 | |
| 
 | |
| SConscript(['common/SConscript'])
 | |
| Import('_common', '_gpucommon')
 | |
| 
 | |
| if SHARED:
 | |
|   common, gpucommon = abspath(common), abspath(gpucommon)
 | |
| else:
 | |
|   common = [_common, 'json11']
 | |
|   gpucommon = [_gpucommon]
 | |
| 
 | |
| Export('common', 'gpucommon')
 | |
| 
 | |
| # cereal and messaging are shared with the system
 | |
| SConscript(['cereal/SConscript'])
 | |
| if SHARED:
 | |
|   cereal = abspath([File('cereal/libcereal_shared.so')])
 | |
|   messaging = abspath([File('cereal/libmessaging_shared.so')])
 | |
| else:
 | |
|   cereal = [File('#cereal/libcereal.a')]
 | |
|   messaging = [File('#cereal/libmessaging.a')]
 | |
|   visionipc = [File('#cereal/libvisionipc.a')]
 | |
| 
 | |
| Export('cereal', 'messaging', 'visionipc')
 | |
| 
 | |
| # Build rednose library and ekf models
 | |
| 
 | |
| rednose_deps = [
 | |
|   "#selfdrive/locationd/models/constants.py",
 | |
|   "#selfdrive/locationd/models/gnss_helpers.py",
 | |
| ]
 | |
| 
 | |
| rednose_config = {
 | |
|   'generated_folder': '#selfdrive/locationd/models/generated',
 | |
|   'to_build': {
 | |
|     'gnss': ('#selfdrive/locationd/models/gnss_kf.py', True, [], rednose_deps),
 | |
|     'live': ('#selfdrive/locationd/models/live_kf.py', True, ['live_kf_constants.h'], rednose_deps),
 | |
|     'car': ('#selfdrive/locationd/models/car_kf.py', True, [], rednose_deps),
 | |
|   },
 | |
| }
 | |
| 
 | |
| if arch != "larch64":
 | |
|   rednose_config['to_build'].update({
 | |
|     'loc_4': ('#selfdrive/locationd/models/loc_kf.py', True, [], rednose_deps),
 | |
|     'lane': ('#selfdrive/locationd/models/lane_kf.py', True, [], rednose_deps),
 | |
|     'pos_computer_4': ('#rednose/helpers/lst_sq_computer.py', False, [], []),
 | |
|     'pos_computer_5': ('#rednose/helpers/lst_sq_computer.py', False, [], []),
 | |
|     'feature_handler_5': ('#rednose/helpers/feature_handler.py', False, [], []),
 | |
|   })
 | |
| 
 | |
| Export('rednose_config')
 | |
| SConscript(['rednose/SConscript'])
 | |
| 
 | |
| # Build system services
 | |
| SConscript([
 | |
|   'system/camerad/SConscript',
 | |
|   'system/clocksd/SConscript',
 | |
|   'system/proclogd/SConscript',
 | |
|   'system/ubloxd/SConscript',
 | |
| ])
 | |
| if arch != "Darwin":
 | |
|   SConscript(['system/logcatd/SConscript'])
 | |
| 
 | |
| # Build openpilot
 | |
| 
 | |
| # build submodules
 | |
| SConscript([
 | |
|   'body/board/SConscript',
 | |
|   'cereal/SConscript',
 | |
|   'opendbc/can/SConscript',
 | |
|   'panda/SConscript',
 | |
| ])
 | |
| 
 | |
| SConscript(['third_party/SConscript'])
 | |
| 
 | |
| SConscript(['common/kalman/SConscript'])
 | |
| SConscript(['common/transformations/SConscript'])
 | |
| 
 | |
| SConscript(['selfdrive/modeld/SConscript'])
 | |
| 
 | |
| SConscript(['selfdrive/controls/lib/lateral_mpc_lib/SConscript'])
 | |
| SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript'])
 | |
| 
 | |
| SConscript(['selfdrive/boardd/SConscript'])
 | |
| 
 | |
| SConscript(['system/loggerd/SConscript'])
 | |
| 
 | |
| SConscript(['selfdrive/locationd/SConscript'])
 | |
| SConscript(['system/sensord/SConscript'])
 | |
| SConscript(['selfdrive/ui/SConscript'])
 | |
| SConscript(['selfdrive/navd/SConscript'])
 | |
| 
 | |
| if (arch in ['x86_64', 'Darwin'] and Dir('#tools/cabana/').exists()) or GetOption('extras'):
 | |
|   SConscript(['tools/replay/SConscript'])
 | |
|   SConscript(['tools/cabana/SConscript'])
 | |
| 
 | |
| external_sconscript = GetOption('external_sconscript')
 | |
| if external_sconscript:
 | |
|   SConscript([external_sconscript])
 | |
| 
 |