/*************************************************************************** * Copyright (C) 2005-2007 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "tool_group.h" #include "devices/list/device_list.h" #include "devices/base/device_group.h" #include "devices/base/generic_memory.h" #include "common/global/process.h" #include "tools/list/compile_config.h" #include "tools/list/compile_process.h" #include "libgui/project.h" //----------------------------------------------------------------------------- const char *Tool::Group::CUSTOM_NAME = "custom"; Tool::Group::Group() : _sourceGenerator(0), _checkDevicesError(true) {} void Tool::Group::init() { delete _sourceGenerator; _sourceGenerator = sourceGeneratorFactory(); FOR_EACH(Category, i) { delete _bases[i].base; _bases[i] = baseFactory(i); if (_bases[i].base) { _bases[i].base->_category = i; _bases[i].base->_group = this; } } ::Group::Base::init(); _version = getToolchainVersion(); } Compile::Process *Tool::Group::createCompileProcess(const Compile::Data &data, Compile::Manager *manager) const { Compile::Process *p = processFactory(data); if (p) p->init(data, manager); return p; } Compile::Config *Tool::Group::createConfig(::Project *project) const { Compile::Config *c = configFactory(project); if (c) c->_group = this; return c; } PURL::Directory Tool::Group::autodetectDirectory(Compile::DirectoryType, const PURL::Directory &, bool) const { return PURL::Directory(); } TQString Tool::Group::defaultLinkerScriptFilename(Compile::LinkType type, const TQString &device) const { TQString basename = device.lower(); if ( type==Compile::Icd2Linking ) basename += 'i'; return basename + '.' + PURL::extension(PURL::Lkr); } bool Tool::Group::hasCustomLinkerScript(const ::Project *project) const { return ( project && !project->customLinkerScript().isEmpty() ); } PURL::Url Tool::Group::linkerScript(const ::Project *project, Compile::LinkType type) const { if ( hasCustomLinkerScript(project) ) return project->customLinkerScript(); TQString filename = defaultLinkerScriptFilename(type, Compile::Config::device(project)); return PURL::Url(Compile::Config::directory(*this, Compile::DirectoryType::LinkerScript), filename); } ::Process::LineOutput *Tool::Group::checkDevicesProcess(uint i, const PURL::Directory &dir, bool withWine) const { ::Process::LineOutput *process = new ::Process::LineOutput; Tool::Category cat = checkDevicesCategory(); TQString exec = base(cat)->baseExecutable(withWine, Compile::Config::outputExecutableType(*this)); process->setup(dir.path() + exec, checkDevicesOptions(i), withWine); return process; } bool Tool::Group::checkExecutable(Tool::Category category, TQStringList &lines) { PURL::Directory dir = Compile::Config::directory(*this, Compile::DirectoryType::Executable); bool withWine = Compile::Config::withWine(*this); Tool::OutputExecutableType outputType = Compile::Config::outputExecutableType(*this); ::Process::LineOutput * process = _bases[category].base->checkExecutableProcess(dir, withWine, outputType); ::Process::State state = ::Process::runSynchronously(*process, ::Process::Start, 10000); if ( state!=::Process::Exited ) return false; lines = process->sout() + process->serr(); return _bases[category].base->checkExecutableResult(withWine, lines); } void Tool::Group::initSupported() { _checkDevicesError = false; Tool::Category cat = checkDevicesCategory(); TQValueList list; if ( cat==Tool::Category::Nb_Types ) list = getSupportedDevices(TQString()); else { PURL::Directory dir = Compile::Config::directory(*this, Compile::DirectoryType::Executable); for (uint i=0; isout() + process->serr(); list += getSupportedDevices(lines.join("\n")); } else _checkDevicesError = true; delete process; } } TQValueList::const_iterator it; for (it=list.begin(); it!=list.end(); ++it) addDevice((*it)->name(), *it, ::Group::Support::Tested); } bool Tool::Group::check(const TQString &device, Log::Generic *log) const { const_cast(this)->checkInitSupported(); if ( hasCheckDevicesError() ) return (log ? log->askContinue(i18n("There were errors detecting supported devices for the selected toolchain (%1). Please check the toolchain configuration. Continue anyway?").tqarg(label())) : false); if ( !device.isEmpty() && device!=Device::AUTO_DATA.name && !isSupported(device) ) return (log ? log->askContinue(i18n("The selected toolchain (%1) does not support device %2. Continue anyway?").tqarg(label()).tqarg(device)) : false); return true; } bool Tool::Group::needs(bool withProject, Tool::Category category) const { if ( _bases[category].base==0 ) return false; if ( withProject && _bases[category].type==StandaloneOnly ) return false; if ( !withProject && _bases[category].type==ProjectOnly ) return false; return true; }