#include "ClCompiler.h" #include "CCSource.h" #include "Component.h" #include "Executable.h" #include "FileSystemUtilities.h" #include "MakeDependencyFile.h" #include "Project.h" #include #include #include /* CLCOMPILATION */ class ClCompilation : public LineProcessController, public LoudMouth { public: ClCompilation(const std::string& CompilerPath, CCSource& aSource); virtual void finished(int ret); virtual void standardOutputByLine(const std::string& aString); virtual void standardErrorByLine(const std::string& aString); virtual void failed(); private: CCSource& theSource; bool MayIgnoreNextEmpty; std::string DepList; }; ClCompilation::ClCompilation(const std::string& CompilerPath, CCSource& aSource) : theSource(aSource), MayIgnoreNextEmpty(false) { createDirectoryForFile(theSource.objectName()); createDirectoryForFile(theSource.dependencyName()); std::vector Args; if (theSource.configuration().includeDebugInformation()) Args.push_back("/Zi"); Args.push_back("/showIncludes"); Args.push_back("/EHs"); Args.push_back("/c"); for (unsigned int i=0; i Args; Args.push_back("/Out:\""+theExecutable.executableName()+"\""); for (unsigned int i=0; iobjectName()); for (unsigned int i=0; i(),StdOut,StdErr); if (ret) StdErr = ""; std::string::size_type idx = StdErr.find("Compiler Version"); if (idx == std::string::npos) StdErr = "Compiler Version 00", idx = 0; StdErr = StdErr.substr(idx+16,3); if (StdErr == " 16") Type = "msvc2010"; else if (StdErr == " 15") Type = "msvc2008"; else if (StdErr == " 14") Type = "msvc2005"; } } std::string ClToolChain::staticLibraryName(const std::string& Stem) const { return Stem+".lib"; } bool ClToolChain::isValid() const { return (CompilerPath.length() != 0) || (LinkerPath.length() != 0); } std::string ClToolChain::type() const { return Type; } void ClToolChain::initResultNames(CCSource& theSource) const { theSource.setObjectName(pathAppend( theSource.configuration().buildDir(), theSource.name()+".obj")); theSource.setDependencyName(pathAppend( theSource.configuration().buildDir(), theSource.name()+".d")); } ProcessController* ClToolChain::createCompilation(CCSource& aSource) { MakeDependencyFile mf(aSource.dependencyName()); if (!mf.upToDate()) return new ClCompilation(CompilerPath, aSource); else { aSource.compilationFinished(true); return 0; } } void ClToolChain::initResultNames(Executable& theExec) const { theExec.setExecutableName(pathAppend( theExec.configuration().buildDir(), theExec.name()+".exe")); } ProcessController* ClToolChain::createLinking(Executable& aExec) { for (unsigned int i=0; iobjectName(),aExec.executableName())) return new ClLinkage(LinkerPath, aExec); return 0; } void ClToolChain::storeToCache() const { SystemConfiguration& Cache(Project::it().systemConfiguration()); std::string Prefix("toolchain."+name()+"."); Cache.configureComment("Microsoft Visual C/C++ compiler"); Cache.configureKey(isValid(),"toolchain."+name()+".type",type()); if (CompilerPath.length() != 0) Project::it().systemConfiguration().configureKey(true,Prefix+"cc_compiler",CompilerPath); else Project::it().systemConfiguration().configureKey(false,Prefix+"cc_compiler", ""); if (LinkerPath.length() != 0) Project::it().systemConfiguration().configureKey(true,Prefix+"cc_linker",LinkerPath); else Project::it().systemConfiguration().configureKey(false,Prefix+"cc_linker", ""); } SharedPtr ClToolChain::discover(const std::string& Name) { std::string ExecutableCompiler = findExecutableInPath("cl.exe"); std::string ExecutableLinker = findExecutableInPath("link.exe"); SharedPtr Result(new ClToolChain(Name,ExecutableCompiler,ExecutableLinker)); if (Result->type() == Name) return Result; return new ClToolChain(Name,"",""); } SharedPtr ClToolChain::createFromCache(const VariablePtr& Item, const std::string& Name) { std::string ExecutableCompiler(stringValue(childOrVoid(Item,"cc_compiler"))); if (ExecutableCompiler.length() == 0) std::cerr << "warning : toolchain does not contain a compiler" << std::endl; std::string ExecutableLinker(stringValue(childOrVoid(Item,"cc_linker"))); if (ExecutableLinker.length() == 0) std::cerr << "warning : toolchain does not contain a linker" << std::endl; if ( (ExecutableLinker.length() != 0) || (ExecutableCompiler.length() != 0) ) return SharedPtr(new ClToolChain(Name,ExecutableCompiler,ExecutableLinker)); return SharedPtr(); }