def deps_handler(builder, path_obj, t, data): if isinstance(builder, (drake.cxx.Linker, drake.cxx.DynLibLinker)): with logger.log('drake.cxx.qt', drake.log.LogLevel.debug, '%s: retrieve linkage to MOC %s', builder, path_obj): if path_obj in drake.Drake.current.nodes: return drake.node(path_obj) path_src = drake.Path(path_obj).with_extension('moc.cc') src = drake.node(path_src) path_header = drake.Path(path_obj).with_extension('hh') header = drake.node(path_header) Moc(builder.toolkit.qt, header, src) obj = drake.cxx.Object(src, builder.toolkit, builder.config) return obj elif isinstance(builder, drake.cxx.Compiler): with logger.log('drake.cxx.qt', drake.log.LogLevel.debug, '%s: retrieve reference to MOC %s', builder, path_obj): source = drake.node(drake.Path(path_obj).with_extension('moc.hh')) qt = builder.toolkit.qt res = qt._Qt__moc_cache.get(source) if res is None: res = moc_file(qt, builder, source) if res is not None: qt._Qt__dependencies.setdefault(builder.object, []).append(res) logger.log('drake.cxx.qt', drake.log.LogLevel.debug, '%s: reference MOC %s', builder, res) else: raise Exception('unexpected Moc dependency for %s' % builder)
def __init__(self, basename, version, dist, arch, top_dir, sources, destination = '.'): if '-' in version: raise Exception('RPM cannot have "-" in version') self.__top_dir = drake.Path(os.getcwd()) / top_dir self.__spec = top_dir / 'SPECS' / ('%s.spec' % basename) self.__arch = arch self.__dist = dist self.__rpm_name = '%(base)s-%(ver)s-1.%(dist)s.%(arch)s.rpm' % \ {'base': basename, 'ver': version, 'dist': dist, 'arch': self.__arch} self.__destination = drake.Path(destination) self.__target = drake.node('%s/%s' % (destination, self.__rpm_name)) all_sources = list() for s in sources: all_sources.append(s) if isinstance(s, drake.cxx.Executable): for d in s.dependencies_recursive: all_sources.append(d) super().__init__(all_sources, [self.__target])
def __init__(self, prefix=None, version=drake.Version(), cxx_toolkit=None): """Build an OpenCV object. prefix -- Prefix where OpenCV is installed. It must contain, among other things, lib/libopencv_core.so. """ # Fill default arguments. if prefix is not None: prefix = [drake.Path(prefix)] else: # pkg-config opencv --variable=prefix prefix = [drake.Path('/usr'), drake.Path('/usr/local')] cxx_toolkit = cxx_toolkit or drake.cxx.Toolkit() # Find the prefix beacon = drake.Path('include/opencv2/core/version.hpp') prefix = self._search(beacon, prefix) # Fill the configuration. self.__config = drake.cxx.Config() self.__config.add_system_include_path(prefix / 'include') self.__config.lib_path(prefix / 'lib') self.__config.lib('opencv_core') # Check the version output = cxx_toolkit.preprocess( '# include<opencv2/core/version.hpp>\nCV_MAJOR_VERSION\nCV_MINOR_VERSION\nCV_SUBMINOR_VERSION' ) eff_version = drake.Version(*map(int, output.split('\n')[-4:-1])) if eff_version not in version: raise Exception('wrong OpenCV version, expected %s, got %s' % (version, eff_version))
def __init__(self, prefix=None): """Find and create a configuration for the Air SDK. prefix -- Where to find the Air SDK, should contain bin/adl. """ # Compute the search path. if prefix is None: test = [drake.Path('/usr'), drake.Path('/usr/local')] else: test = [drake.Path(prefix)] self.__prefix = self._search_all('bin/adl', test)[0]
def hook_bin_src(self, src): if isinstance(src, Ui): p = drake.Path(src.name()) p = p.with_extension('%s.hh' % p.extension) res = drake.cxx.Header(p) Uic(self, src, res) return res elif isinstance(src, Rc): p = drake.Path(src.name()) p = p.with_extension('%s.cc' % p.extension) res = drake.cxx.Source(p) Rcc(self, src, res) return res
def __init__(self, prefix=None): """Find and create a configuration for the Flex SDK. prefix -- Where to find the Flex SDK, should contain bin/acompc. """ # Compute the search path. if prefix is None: test = [drake.Path('/usr'), drake.Path('/usr/local')] else: test = [drake.Path(prefix)] self.__prefix = self._search_all('bin/acompc', test)[0] self.__options = [] self.__external_library_path = []
def __init__(self, version, base_url=None, platform="linux", dest=drake.Path("Assimp"), expected_headers=None): super().__init__("Assimp") self.__base_url = base_url or "https://github.com/assimp/assimp/archive" self.__version = version self.__platform = "linux" self.__tar = drake.Node( dest / "v{version}.tar.gz".format(version=self.__version)) self.__path = dest / "assimp-{version}".format(version=self.__version) self.__include_path = self.__path / "include" self.__library_path = self.__path / "lib" self.__cmake_lists = drake.Node(self.__path / "CMakeLists.txt") self.__makefile = drake.Node(self.__path / "Makefile") drake.HTTPDownload(url=self.url, dest=self.__tar) drake.Extractor( tarball=self.__tar, targets=[ str(self.__cmake_lists.name_absolute())[len(str(dest)) + 1:] ]).targets() drake.ShellCommand(sources=[self.__cmake_lists], targets=self.headers + [self.__makefile], command=['cmake', '.'], cwd=self.__path) drake.ShellCommand(sources=[self.__makefile], targets=self.libraries, command=['make', 'assimp'], cwd=self.__path)
def parse_otool_libraries(self, path): command = ['otool', '-L', str(path)] return [ drake.Path(line[1:].split(' ')[0]) for line in subprocess.check_output(command).decode().split('\n') if line.startswith('\t') ]
def execute(self): root = self.__dockerfile.path().dirname() self.output('Generate %s' % self.__dockerfile) with open(str(self.__dockerfile.path()), 'w') as f: print('FROM %s' % self.__dockerfile.image, file = f) if self.__dockerfile.maintainer is not None: print('MAINTAINER %s' % self.__dockerfile.maintainer, file = f) for k, v in self.__dockerfile.labels.items(): print('LABEL %s="%s"' % (k, v), file = f) for cmd, args in self.__dockerfile.steps: print('{} {}'.format(cmd, args), file = f) for p, nodes in self.__dockerfile._DockerFile__adds.items(): for add in rootify( chain(*(parents(n.path().without_prefix(root)) for n in installed_files(nodes) if n is not drake.Path.dot))): dest = "%s/%s" % (p, add) \ if os.path.isdir(str(drake.Path(root) / add)) \ else p print('ADD %s %s' % (add, dest), file = f) for p in self.__dockerfile.ports_: print('EXPOSE %s' % p, file = f) if self.__dockerfile.volumes_: print('VOLUME %s' % json.dumps(self.__dockerfile.volumes_), file = f) if self.__dockerfile.entry_point_: print('ENTRYPOINT %s' % json.dumps(self.__dockerfile.entry_point_), file = f) if self.__dockerfile.cmd_: print('CMD %s' % json.dumps(self.__dockerfile.cmd_), file = f) return True
def __init__(self, version, base_url=None, platform="linux", dest=drake.Path("GLFW"), expected_headers=None): super().__init__("GLFW") self.__base_url = base_url or "https://github.com/glfw/glfw/releases/download" self.__version = version self.__platform = "linux" self.__zip = drake.node(dest / "{version}.zip".format(version=self.__version)) self.__path = dest / "glfw-{version}".format(version=self.__version) self.__include_path = self.__path / "include" self.__library_path = self.__path / "src" self.__cmake_lists = drake.Node(self.__path / "CMakeLists.txt") self.__makefile = drake.Node(self.__path / "Makefile") drake.HTTPDownload(url=self.url, dest=self.__zip) drake.Extractor(tarball=self.__zip, targets=[str(self.__cmake_lists.name_absolute())[5:] ]).targets() drake.ShellCommand(sources=[self.__cmake_lists], targets=self.headers + [self.__makefile], command=['cmake', '.'], cwd=self.__path) drake.ShellCommand(sources=[self.__makefile], targets=self.libraries, command=['make', 'glfw'], cwd=self.__path)
def __init__(self, version, base_url=None, platform="linux", dest=drake.Path("vulkan"), expected_headers=None): super().__init__("Vulkan") self.__base_url = base_url or "https://sdk.lunarg.com/sdk/download" self.__version = version self.__platform = "linux" self.__run = drake.Node(dest / "install.run") self.__base_path = dest / "VulkanSDK" self.__path = self.__base_path / "{version}/x86_64".format( version=self.__version) self.__include_path = self.__path / "include" self.__library_path = self.__path / "lib" self.__binary_path = self.__path / "bin" drake.HTTPDownload(url=self.url, dest=self.__run) drake.ShellCommand( sources=[self.__run], targets=self.headers + self.libraries + self.others, command=['bash', str(self.__run), '--target', str(self.base_path)])
def execute(self): # Cleanup effective = set() for path, dirs, files in os.walk(str(self.__path)): path = drake.Path(path) for f in chain(files, dirs): effective.add(path / f) expected = set( chain(*(parents(n.path()) for n in installed_files(self.__docker_file.adds)))) for g in rootify(p.without_prefix(self.__path) for p in (effective - expected) if p is not self.__docker_file.path()): g = self.__path / g self.output('Cleanup %s' % g) g = str(g) if os.path.isdir(g): shutil.rmtree(str(g)) else: os.remove(g) tag = ':'.join((self.__image.repository, self.__image.tag)) self.cmd('Docker build image %s' % tag, ['docker', 'build', '--force-rm', '--tag', tag, self.__path, ], throw = True) return True
def __init__(self, version, base_url = None, platform = "linux", dest = drake.Path("imgui"), expected_headers = None): super().__init__("imgui") self.__base_url = base_url or "https://github.com/ocornut/imgui/archive" self.__version = version self.__platform = "linux" self.__tar = drake.Node(dest / "v{version}.tar.gz".format(version = self.__version)) self.__path = dest / "imgui-{version}".format(version = self.__version) self.__include_path = self.__path self.__source_path = self.__path self.__library_path = self.__path self.__cmake_lists = drake.Node(self.__path / "CMakeLists.txt") self.__makefile = drake.Node(self.__path / "Makefile") drake.HTTPDownload(url = self.url, dest = self.__tar) drake.Extractor(tarball = self.__tar, targets = map(lambda f: str(f.name_absolute())[len(str(dest)) + 1:], self.headers + self.sources)) for index, cpp in enumerate(self.sources): drake.ShellCommand( sources = [cpp], targets = [self.libraries[index]], command = [ 'g++', '-shared', '-fPIC', str(cpp.path().basename()), '-o', str(self.libraries[index].path().basename()) ], cwd = self.__path)
def __find_lib(self, lib, cxx_toolkit, static): suffixes = ['', '-mt'] # Suffixes if static: suffixes.append('-mt-s') suffixes.append('-s') if cxx_toolkit.os == drake.os.windows: suffixes = list( map(lambda x: x + str(self.version.major), suffixes)) if isinstance(cxx_toolkit, drake.cxx.VisualToolkit): suffix = '-vc%s0-mt-%s_%s' % ( cxx_toolkit.version, self.version.major, self.version.minor) suffixes = [suffix] + suffixes mgw = '-mgw-mt-%s_%s' % (self.version.major, self.version.minor) suffixes += [mgw] # Variants variants = [''] if isinstance(lib, str): lib = (lib, ) tests = [] for lib, suffix, variant in itertools.product(lib, suffixes, variants): libname = '%s%s%s' % (lib, variant, suffix) if static: filename = cxx_toolkit.libname_static(self.__cfg, libname) tests.append(filename) else: prefix = '' if cxx_toolkit.os == drake.os.windows else 'lib' filename = cxx_toolkit.libname_dyn(libname, self.__cfg, prefix) # Test .so.$major first as it is the SONAME. tests.append( drake.Path('%s.%s' % (filename, self.__version.major))) tests.append(drake.Path('%s.%s' % (filename, self.__version))) tests.append( drake.Path('%s.%s.%s' % (filename, self.__version.major, self.__version.minor))) tests.append(filename) search_path = [ self.__prefix / lib / p for lib in ['lib', 'lib64'] for p in ['.', 'qt5'] ] prefix, lib = self._search_many_one(tests, search_path) if static: return drake.cxx.StaticLib(prefix / lib) else: return drake.cxx.DynLib(prefix / lib)
def __init__(self, path=None): if isinstance(path, self.__class__): self.__path = drake.Path(path.__path) self.__version = drake.Version(path.__version) else: if path is None: self.__path = drake.Path(self.__class__.name) else: self.__path = drake.Path(path) try: output = self._get_version() except Exception as e: raise Exception('Unable to find %s' % self.path) from e try: self.__version = self._parse_version(output) except Exception as e: raise Exception('Unable to parse %s version from %r' % \ (self.__class.name, output)) from e
def __init__(self, path=None): if path is None: path = drake.Path('valgrind') elif isinstance(path, Valgrind): self.__path = drake.Path(path.__path) self.__version = drake.Version(path.__version) return self.__path = drake.Path(path) try: output = subprocess.check_output([str(self.path), '--version']) except Exception as e: raise Exception('Unable to find %s' % self.path) from e output = output.decode() prefix = 'valgrind-' if not output.startswith(prefix): raise Exception('Unable to parse valgrind version: %s' % output) output = output[len(prefix):] self.__version = drake.Version(output)
def __init__(self, name, config, source_path, source, sources, flex_sdk): source_path = drake.Path(source_path) self.__config = config self.__source = source self.__source_path = source_path self.__sources = sources self.__sdk = flex_sdk drake.Node.__init__(self, name) ApplicationBuilder(sources, self, config, source, source_path, flex_sdk)
def __init__(self, magick_config=None, prefix=None): """Build a Convert object. magick_config -- Path to the Magick-config program. prefix -- Prefix where the suite is installed. If neither magick_config nor prefix is provided, /usr/bin/Magick-config and /usr are used respectively. If magick_config is provided, it is used to determine the Image magick suite configuration. Otherwise, or if Magick-config failed to provide the configuration (i.e., the binary does not actually exist or doesn't work), prefix is used (i.e., binaries are searched in prefix/bin, etc). Otherwise, or if the prefix isn't valid (i.e., a beacon file, prefix/bin/convert, isn't found), configuration fails and an exception is thrown. """ # Default configuration. if magick_config is None and prefix is None: magick_config = '/usr/bin/Magick-config' prefix = '/usr' # Prepare arguments if magick_config is not None: magick_config = drake.Path(magick_config) if prefix is not None: prefix = drake.Path(prefix) self.__bin = None # Try with Magick-config. if magick_config is not None: try: cmd = [str(magick_config), '--exec-prefix'] self.__bin = drake.Path(drake.cmd_output(cmd).strip()) / 'bin' except: pass # Try with the prefix. if self.__bin is None and prefix is not None: self.__bin = prefix / 'bin' # Check validity if not self.convert().exists(): raise Exception('%s does not exist' % self.convert())
def __init__(self, basename, attributes, sources, path, destination='.', preload=None, cleanup_source_directory=True): path = drake.Path(path) self.__destination = drake.Path(destination) basename = drake.Path(basename) self.__target = drake.node(self.__destination / basename) self.__destination = drake.path_build(self.__destination) self.__path = drake.path_build(path) self.__preload = preload self.__attrs = attributes self.__control = drake.node(path / 'DEBIAN/control') if preload is not None: sources += [preload] self.__cleanup_source_directory = cleanup_source_directory super().__init__(sources, [self.__control, self.__target])
def moc_file(qt, linker, source): for i in linker.config.system_include_path: if source.name_relative.dirname() == i: return None path = drake.Path(source.name()).with_extension('moc.cc') src = drake.node(path) if src.builder is None: Moc(linker.toolkit.qt, source, src) res = drake.cxx.Object(src, linker.toolkit, linker.config) qt._Qt__moc_cache[source] = res qt._Qt__moc_files.add(res) return res
def __init__(self, source, target_extension, imagemagick=ImageMagick()): """Create a ConvertBuilder. source -- The source node. target_extension -- File extension to convert to. """ path = drake.Path(source.name()) path.extension = target_extension self.__imagemagick = imagemagick self.__source = source self.__target = drake.node(path) drake.Builder.__init__(self, [self.__source], [self.__target])
def __init__(self, prefix=None, version=drake.Version()): if prefix is None: paths = [drake.Path('/usr'), drake.Path('/usr/local')] else: paths = [drake.Path(prefix)] self.__prefix = self._search('bin/urbi', paths) v = drake.cmd_output([ str(self.urbi()), '--quiet', '--expression', 'System.version;shutdown;' ]) v = v.decode('utf-8').split(' ')[1].strip().split('"')[1].split('.') v = drake.Version(*map(int, v)) if v not in version: raise Exception( 'Urbi SDK version (%s) does not match the requested version (%s).' % (v, version)) self.__version = v self.__config = drake.cxx.Config() self.__config.add_system_include_path(self.__prefix / 'include') self.__config.lib_path(self.__prefix / 'lib') self.__boost = drake.cxx.boost.Boost(prefix=self.__prefix)
def __init__(self, toolkit, srcs, dsts, vars, targets=None, path_to_cmake_source=None): ''' `srcs`: what we depend upon. `dsts`: what will be built. `vars`: dict variables passed to cmake via `-D`. `targets`: list of Makefile targets. `path_to_cmake_source`: path to the directory containing the CMakeFile. ''' self.__toolkit = toolkit self.__vars = vars self.__prefix = drake.Drake.current.prefix self.__path_to_cmake_source = \ drake.Path(path_to_cmake_source) if path_to_cmake_source \ else drake.path_source() / self.__prefix self.__env = dict(os.environ) self.__env.update({ 'CC': ' '.join(toolkit.command_c), 'CXX': ' '.join(toolkit.command_cxx), }) self.__cmake_cache = drake.node('CMakeCache.txt') self.__targets = targets # cmake 3 compat self.__vars.update({'CMAKE_SYSTEM_PROCESSOR': 'x86_64'}) if self.toolkit.os is drake.os.windows: self.__vars.update({ 'CMAKE_ASM_NASM_COMPILER': self.toolkit.cxx[0:-3] + 'as', 'CMAKE_RC_COMPILER': self.toolkit.cxx[0:-3] + 'windres', 'CMAKE_SYSTEM_NAME': 'Windows', }) dsts = list(dsts) dsts.append(self.__cmake_cache) # Call __init__ last, make __cmake_cache is declared a dsts, so # that it has a build-tree path, not a source-tree one. super().__init__(srcs=srcs, dsts=dsts)
def __init__(self, cxx_toolkit=None, prefix=None, version=Version(), version_effective=None, prefer_shared=True): """Find and create a configuration for Boost. prefix -- Where to find Boost, should contain include/boost/version.hpp among others. /usr and /usr/local are searched by default. If relative, it is rooted in the source tree. version -- Requested version. prefer_shared -- Check dynamic libraries first. """ # Fix arguments cxx_toolkit = cxx_toolkit or drake.cxx.Toolkit() self.__cxx_toolkit = cxx_toolkit self.__prefer_shared = prefer_shared # Compute the search path. if prefix is None: test = [ path.dirname() for path in cxx_toolkit.include_path if path.basename() == 'include' ] else: test = [Path(prefix)] token = drake.Path('boost/version.hpp') include_subdirs = {drake.Path('include')} for prefix in test: for subdir in include_subdirs: if not (prefix / subdir).exists(): continue include_subdirs = include_subdirs.union( (subdir / p for p in (prefix / subdir).list() if p.startswith('boost-'))) tokens = map(lambda p: p / token, include_subdirs) prefixes = self._search_many_all(list(tokens), test) miss = [] if version_effective is not None: assert prefix is not None # Try every search path for path, include_subdir in prefixes: path = drake.path_build(path) include_subdir = include_subdir.without_suffix(token) # Create basic configuration for version checking. cfg = Config() cfg.add_system_include_path( path.without_prefix(drake.path_build()) / include_subdir) self.__lib_path = path / 'lib' cfg.lib_path(path.without_prefix(drake.path_build()) / 'lib') # Check the version. if version_effective is None: version_eff = cxx_toolkit.preprocess( '#include <boost/version.hpp>\nBOOST_VERSION', config=cfg) version_eff = int(version_eff.split('\n')[-2].strip()) version_eff = Version(version_eff // 100000, version_eff // 100 % 1000, version_eff % 100) else: version_eff = version_effective if version_eff not in version: miss.append(version_eff) continue # Fill configuration self.__prefix = path self.__cfg = cfg for prop in self.__libraries: setattr(self, '_Boost__config_%s_dynamic' % prop, None) setattr(self, '_Boost__config_%s_static' % prop, None) setattr(self, '_Boost__config_%s_dynamic_header' % prop, None) setattr(self, '_Boost__config_%s_static_header' % prop, None) setattr(self, '_Boost__%s_dynamic' % prop, None) setattr(self, '_Boost__%s_static' % prop, None) self.__version = version_eff return raise Exception('no matching boost for the requested version ' '(%s) in %s. Found versions: %s.' % \ (version, self._format_search([path for path, include_subdir in prefixes]), ', '.join(map(str, miss))))
def add_external_library_path(self, path): path = drake.Path(path) self.__external_library_path.append(path)
def __init__(self, cxx_toolkit=None, prefix=None, version=drake.Version(), version_effective=None, prefer_shared=True, rcc=None, qmake=None, uic=None, moc=None): """Find and create a configuration for Qt. prefix -- Where to find Qt, should contain include/Qt/qglobal.h among others. /usr and /usr/local are searched by default. If relative, it is rooted in the source tree. version -- Requested version. prefer_shared -- Check dynamic libraries first. """ self.__rcc = rcc self.__qmake = qmake self.__uic = uic self.__moc = moc self.__moc_cache = {} self.__dependencies = {} self.__moc_files = set() cxx_toolkit = cxx_toolkit or drake.cxx.Toolkit() self.__cxx_toolkit = cxx_toolkit self.__prefer_shared = prefer_shared include_subdirs = set( drake.Path(p) for p in ['include', 'include/qt5']) if prefix is None: test = [ path.dirname() for path in cxx_toolkit.include_path if path.basename() in include_subdirs ] else: test = [drake.Path(prefix)] for i in range(len(test)): if not test[i].absolute(): test[i] = drake.path_source() / test[i] token = drake.Path('QtCore/qglobal.h') tokens = list(map(lambda p: p / token, include_subdirs)) prefixes = self._search_many_all(tokens, test) miss = [] # Try every search path for path, include_subdir in prefixes: include_subdir = include_subdir.without_suffix(token) # Create basic configuration for version checking. cfg = drake.cxx.Config() cfg.pic = True if not path.absolute(): path = path.without_prefix(drake.path_build()) cfg.add_system_include_path(path / include_subdir) if version_effective is None: try: version_eff = cxx_toolkit.preprocess( '#include <QtCore/qglobal.h>\nQT_VERSION', config=cfg).split('\n')[-2].strip() version_eff = eval(version_eff, {"__builtins__": None}, {}) version_eff = drake.Version( version_eff >> 16, (version_eff >> 8) % 256, version_eff % 256, ) # If the token doesn't exists, ignore. except Exception as e: continue else: version_eff = version_effective if version_eff not in version: miss.append(version_eff) continue # Fill configuration self.__prefix = path self.__cfg = cfg for prop in self.__libraries: setattr(self, '_Qt__config_%s_dynamic' % prop, None) setattr(self, '_Qt__config_%s_static' % prop, None) setattr(self, '_Qt__config_%s_dynamic_header' % prop, None) setattr(self, '_Qt__config_%s_static_header' % prop, None) setattr(self, '_Qt__%s_dynamic' % prop, None) setattr(self, '_Qt__%s_static' % prop, None) self.__version = version_eff Qt.__include_dir = path / include_subdir return raise Exception( 'no matching Qt ({}) in {}. Found versions: {}.'.format( pretty_listing(version, any=True), pretty_listing([p for p, _ in prefixes], quantifier=True), pretty_listing(miss)))
def __init__(self, name, repository, tag): path = drake.Drake.current.prefix / name path = drake.Path(path._Path__path, False, True) super().__init__(path) self.__repository = repository self.__tag = tag
def add(self, nodes, path): if isinstance(nodes, collections.Iterable): for node in nodes: self.add(node, path) else: self.__adds.setdefault(drake.Path(path), []).append(nodes)