summaryrefslogtreecommitdiffstats
path: root/source/core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-06-14 10:02:04 -0400
committerGitHub <noreply@github.com>2019-06-14 10:02:04 -0400
commit7461e95210e7420d0ddf681279813f394a6fd0d8 (patch)
treea1a80a802ce1c107a691d2b0e395c4ce97f46136 /source/core
parent202f993e2ced2b2a3445b54a740e47d6d8091297 (diff)
Abstract CPPCompiler (#983)
* Work in progress to be able to invoke VS from within code. * First pass at windows version of refactor of OSProcessSpawner * Closer to getting VS path lookup working. * Make OSString assignable/ctor able * Work out program files directory directly, so don't have to expand %%. * WIP: Improve handling of process spawning. * Add support for splitting input by line. * * Correctly locates visual studio install * Added functionality to invoke vs via cmd * Add option to execute the command line. * Handle in ProcessUtil for windows -> WinHandle. * Rename files slang-win-visual-studio-util.cpp/.h and slang-process-util.h * First pass at unix/linux version of ProcessUtil. * Fix reading Visual Studio path from the registry. * Get compiling on linux with. * Fix vcvarsall.bat name * Use ProcessUtil to execute external code. * Remove OSProcessSpawner. * Remove includes for "os.h" where no longer needed. * Fix tabbing issue in premake5.lua Remove test code from slang-test-main.cpp * Fix premake4.lua tabbing issue. * Small fixes to slang-process-util.h Init ExecuteResult on Win execute. * Improve comments. * Fix bug in StringUtil::calcLines - with oddly terminated source input being able to read past end. Make slang-generate use StringUtil over it's own impl. * Fix off by one bug in working out Visual Studio version. * Fix bug in calculating Visual Studio Version * Fix compilation on linux with string parameter being passed to messageFormat. * Remove erroneous use of kOSError codes - use Result. * First effort to generate standard compiler options. * Initial efforts in compiling source code in test framework for VisualStudio. * Testing compiling c code on VisualStudio on Windows. * Fix warning on linux. * Fix clang on linux warning (and therefore failing) returning a StringBuilder as String. * Disable return-std-move on clang. * CommandLine arguments are now tagged if they are escaped or not. That it is the clients responsibility to escape command lines that cannot be automatically escaped. * Add checks on unix/linux that command line args are all unescaped. * WIP getting runtime GCC to work. * First pass compiler working on unix-like targets. * Added File::remove function. * Enable c-compile.c test on 'smoke'. * WIP abstracting the CPP compiler concept. * CPPCompilerSet and CPPCompilerUtil working on windows. Problem on unix. * Used stdError for parsing of invoke of compiler to figure out verison. * Removed some code that was no longer needed from slang-cpp-compiler.cpp
Diffstat (limited to 'source/core')
-rw-r--r--source/core/core.vcxproj1
-rw-r--r--source/core/core.vcxproj.filters3
-rw-r--r--source/core/slang-cpp-compiler.cpp340
-rw-r--r--source/core/slang-cpp-compiler.h146
-rw-r--r--source/core/unix/slang-unix-cpp-compiler-util.cpp8
-rw-r--r--source/core/unix/slang-unix-cpp-compiler-util.h2
-rw-r--r--source/core/windows/slang-win-visual-studio-util.cpp52
-rw-r--r--source/core/windows/slang-win-visual-studio-util.h15
8 files changed, 541 insertions, 26 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj
index a855630c2..177cd2011 100644
--- a/source/core/core.vcxproj
+++ b/source/core/core.vcxproj
@@ -208,6 +208,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="slang-byte-encode-util.cpp" />
+ <ClCompile Include="slang-cpp-compiler.cpp" />
<ClCompile Include="slang-free-list.cpp" />
<ClCompile Include="slang-io.cpp" />
<ClCompile Include="slang-memory-arena.cpp" />
diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters
index df83072f8..8d7add8ea 100644
--- a/source/core/core.vcxproj.filters
+++ b/source/core/core.vcxproj.filters
@@ -119,6 +119,9 @@
<ClCompile Include="slang-byte-encode-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="slang-cpp-compiler.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="slang-free-list.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/source/core/slang-cpp-compiler.cpp b/source/core/slang-cpp-compiler.cpp
new file mode 100644
index 000000000..ef679d780
--- /dev/null
+++ b/source/core/slang-cpp-compiler.cpp
@@ -0,0 +1,340 @@
+// slang-cpp-compiler.cpp
+#include "slang-cpp-compiler.h"
+
+#include "slang-common.h"
+#include "../../slang-com-helper.h"
+#include "slang-string-util.h"
+
+#if SLANG_VC
+# include "windows/slang-win-visual-studio-util.h"
+#else
+# include "unix/slang-unix-cpp-compiler-util.h"
+#endif
+
+namespace Slang
+{
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! GenericCPPCompiler !!!!!!!!!!!!!!!!!!!!!!*/
+
+SlangResult GenericCPPCompiler::compile(const CompileOptions& options, ExecuteResult& outResult)
+{
+ CommandLine cmdLine;
+
+ // Calculate the command line options
+ m_func(options, cmdLine);
+
+ // Set the executable
+ cmdLine.setExecutableFilename(m_exeName);
+
+#if 0
+ // Test
+ {
+ String line = ProcessUtil::getCommandLineString(cmdLine);
+ printf("%s", line.getBuffer());
+ }
+#endif
+
+ return ProcessUtil::execute(cmdLine, outResult);
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompilerUtil !!!!!!!!!!!!!!!!!!!!!!*/
+
+static bool _isDigit(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+static bool _isWhiteSpace(char c)
+{
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+}
+
+/* static */SlangResult CPPCompilerUtil::parseGccFamilyVersion(const UnownedStringSlice& text, const UnownedStringSlice& versionPrefix, CPPCompiler::Desc& outDesc)
+{
+ List<UnownedStringSlice> lines;
+ StringUtil::calcLines(text, lines);
+
+ for (auto line : lines)
+ {
+ if (String(line).startsWith(versionPrefix))
+ {
+ UnownedStringSlice versionSlice(line.begin() + versionPrefix.size(), line.end());
+
+ List<Int> digits;
+
+ const char* cur = versionSlice.begin();
+ const char* end = versionSlice.end();
+
+ // Consume white space
+ while (cur < end && _isWhiteSpace(*cur)) cur++;
+
+ // Version is in format 0.0.0
+ while (true)
+ {
+ Int value = 0;
+ const char* start = cur;
+ while (cur < end && _isDigit(*cur))
+ {
+ value = value * 10 + (*cur - '0');
+ cur++;
+ }
+
+ if (cur <= start)
+ {
+ break;
+ }
+
+ digits.add(value);
+
+ if (cur < end && *cur == '.')
+ {
+ cur++;
+ }
+ }
+
+ if (digits.getCount() < 2)
+ {
+ return SLANG_FAIL;
+ }
+
+ outDesc.majorVersion = digits[0];
+ outDesc.minorVersion = digits[1];
+
+ return SLANG_OK;
+ }
+ }
+
+ return SLANG_FAIL;
+}
+
+SlangResult CPPCompilerUtil::calcGccFamilyVersion(const String& exeName, const UnownedStringSlice& versionPrefix, CPPCompiler::Desc& outDesc)
+{
+ CommandLine cmdLine;
+ cmdLine.setExecutableFilename(exeName);
+ cmdLine.addArg("-v");
+
+ ExecuteResult exeRes;
+ SLANG_RETURN_ON_FAIL(ProcessUtil::execute(cmdLine, exeRes));
+ return parseGccFamilyVersion(exeRes.standardError.getUnownedSlice(), versionPrefix, outDesc);
+}
+
+static CPPCompiler::Desc _calcCompiledWithDesc()
+{
+ CPPCompiler::Desc desc = {};
+
+#if SLANG_VC
+ desc = WinVisualStudioUtil::getDesc(WinVisualStudioUtil::getCompiledVersion());
+#elif SLANG_CLANG
+ desc.type = CPPCompiler::Type::Clang;
+#elif SLANG_SNC
+ desc.type = CPPCompiler::Type::SNC;
+#elif SLANG_GHS
+ desc.type = CPPCompiler::Type::GHS;
+#elif SLANG_GCC
+ desc.type = CPPCompiler::Type::GCC;
+#else
+ desc.type = CPPCompiler::Type::Unknown;
+#endif
+
+ return desc;
+}
+
+const CPPCompiler::Desc& CPPCompilerUtil::getCompiledWithDesc()
+{
+ static CPPCompiler::Desc s_desc = _calcCompiledWithDesc();
+ return s_desc;
+}
+
+/* static */CPPCompiler* CPPCompilerUtil::findCompiler(const CPPCompilerSet* set, MatchType matchType, const CPPCompiler::Desc& desc)
+{
+ List<CPPCompiler*> compilers;
+ set->getCompilers(compilers);
+ return findCompiler(compilers, matchType, desc);
+}
+
+/* static */CPPCompiler* CPPCompilerUtil::findCompiler(const List<CPPCompiler*>& compilers, MatchType matchType, const CPPCompiler::Desc& desc)
+{
+ Int bestIndex = -1;
+
+ const CPPCompiler::Type type = desc.type;
+
+ Int maxVersionValue = 0;
+ Int minVersionDiff = 0x7fffffff;
+
+ const auto descVersionValue = desc.getVersionValue();
+
+ for (Index i = 0; i < compilers.getCount(); ++i)
+ {
+ CPPCompiler* compiler = compilers[i];
+ auto compilerDesc = compiler->getDesc();
+
+ if (type == compilerDesc.type)
+ {
+ const Int versionValue = compilerDesc.getVersionValue();
+ switch (matchType)
+ {
+ case MatchType::MinGreaterEqual:
+ {
+ auto diff = descVersionValue - versionValue;
+ if (diff >= 0 && diff < minVersionDiff)
+ {
+ bestIndex = i;
+ minVersionDiff = diff;
+ }
+ break;
+ }
+ case MatchType::MinAbsolute:
+ {
+ auto diff = descVersionValue - versionValue;
+ diff = (diff >= 0) ? diff : -diff;
+ if (diff < minVersionDiff)
+ {
+ bestIndex = i;
+ minVersionDiff = diff;
+ }
+ break;
+ }
+ case MatchType::Newest:
+ {
+ if (versionValue > maxVersionValue)
+ {
+ maxVersionValue = versionValue;
+ bestIndex = i;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return (bestIndex >= 0) ? compilers[bestIndex] : nullptr;
+}
+
+/* static */CPPCompiler* CPPCompilerUtil::findClosestCompiler(const List<CPPCompiler*>& compilers, const CPPCompiler::Desc& desc)
+{
+ CPPCompiler* compiler;
+
+ compiler = findCompiler(compilers, MatchType::MinGreaterEqual, desc);
+ if (compiler)
+ {
+ return compiler;
+ }
+ compiler = findCompiler(compilers, MatchType::MinAbsolute, desc);
+ if (compiler)
+ {
+ return compiler;
+ }
+
+ // If we are gcc, we can try clang and vice versa
+ if (desc.type == CPPCompiler::Type::GCC || desc.type == CPPCompiler::Type::Clang)
+ {
+ CPPCompiler::Desc compatible = desc;
+ compatible.type = (compatible.type == CPPCompiler::Type::Clang) ? CPPCompiler::Type::GCC : CPPCompiler::Type::Clang;
+
+ compiler = findCompiler(compilers, MatchType::MinGreaterEqual, compatible);
+ if (compiler)
+ {
+ return compiler;
+ }
+ compiler = findCompiler(compilers, MatchType::MinAbsolute, compatible);
+ if (compiler)
+ {
+ return compiler;
+ }
+ }
+
+ return nullptr;
+}
+
+/* static */CPPCompiler* CPPCompilerUtil::findClosestCompiler(const CPPCompilerSet* set, const CPPCompiler::Desc& desc)
+{
+ CPPCompiler* compiler = set->getCompiler(desc);
+ if (compiler)
+ {
+ return compiler;
+ }
+ List<CPPCompiler*> compilers;
+ set->getCompilers(compilers);
+ return findClosestCompiler(compilers, desc);
+}
+
+
+/* static */SlangResult CPPCompilerUtil::initializeSet(CPPCompilerSet* set)
+{
+#if SLANG_WINDOWS_FAMILY
+ WinVisualStudioUtil::find(set);
+#else
+ {
+ CPPCompiler::Desc desc(CPPCompiler::Type::Clang);
+ if (SLANG_SUCCEEDED(calcGccFamilyVersion("clang", UnownedStringSlice::fromLiteral("clang version"), desc)))
+ {
+ RefPtr<CPPCompiler> compiler(new GenericCPPCompiler(desc, "clang", &UnixCPPCompilerUtil::calcArgs));
+ set->addCompiler(compiler);
+ }
+ }
+ {
+ CPPCompiler::Desc desc(CPPCompiler::Type::GCC);
+ if (SLANG_SUCCEEDED(calcGccFamilyVersion("g++", UnownedStringSlice::fromLiteral("gcc version"), desc)))
+ {
+ RefPtr<CPPCompiler> compiler(new GenericCPPCompiler(desc, "g++", &UnixCPPCompilerUtil::calcArgs));
+ set->addCompiler(compiler);
+ }
+ }
+#endif
+
+ // Set the default to the compiler closest to how this source was compiled
+ set->setDefaultCompiler(findClosestCompiler(set, getCompiledWithDesc()));
+ return SLANG_OK;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompilerFactory !!!!!!!!!!!!!!!!!!!!!!*/
+
+
+void CPPCompilerSet::getCompilerDescs(List<CPPCompiler::Desc>& outCompilerDescs) const
+{
+ outCompilerDescs.clear();
+ for (CPPCompiler* compiler : m_compilers)
+ {
+ outCompilerDescs.add(compiler->getDesc());
+ }
+}
+
+Index CPPCompilerSet::_findIndex(const CPPCompiler::Desc& desc) const
+{
+ const Index count = m_compilers.getCount();
+ for (Index i = 0; i < count; ++i)
+ {
+ if (m_compilers[i]->getDesc() == desc)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+CPPCompiler* CPPCompilerSet::getCompiler(const CPPCompiler::Desc& compilerDesc) const
+{
+ const Index index = _findIndex(compilerDesc);
+ return index >= 0 ? m_compilers[index] : nullptr;
+}
+
+void CPPCompilerSet::getCompilers(List<CPPCompiler*>& outCompilers) const
+{
+ outCompilers.clear();
+ outCompilers.addRange((CPPCompiler*const*)m_compilers.begin(), m_compilers.getCount());
+}
+
+void CPPCompilerSet::addCompiler(CPPCompiler* compiler)
+{
+ const Index index = _findIndex(compiler->getDesc());
+ if (index >= 0)
+ {
+ m_compilers[index] = compiler;
+ }
+ else
+ {
+ m_compilers.add(compiler);
+ }
+}
+
+}
diff --git a/source/core/slang-cpp-compiler.h b/source/core/slang-cpp-compiler.h
index 644d3d85b..8794463d1 100644
--- a/source/core/slang-cpp-compiler.h
+++ b/source/core/slang-cpp-compiler.h
@@ -4,29 +4,45 @@
#include "slang-common.h"
#include "slang-string.h"
+#include "slang-process-util.h"
+
namespace Slang
{
-class CPPCompiler
+class CPPCompiler: public RefObject
{
public:
+ typedef RefObject Super;
enum class Type
{
+ Unknown,
VisualStudio,
GCC,
Clang,
+ SNC,
+ GHS,
+ CountOf,
};
- struct Version
+ struct Desc
{
- Type type; ///< The compiler type
- Int major; ///< The major version number
- Int minor; ///< The minor version number
+ typedef Desc ThisType;
+
+ UInt GetHashCode() const { return combineHash(int(type), combineHash(int(majorVersion), int(minorVersion))); }
+ bool operator==(const ThisType& rhs) const { return type == rhs.type && majorVersion == rhs.majorVersion && minorVersion == rhs.minorVersion; }
+ bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
+ /// Get the version as a value
+ Int getVersionValue() const { return majorVersion * 100 + minorVersion; }
+
+ /// Ctor
+ Desc(Type inType = Type::Unknown, Int inMajorVersion = 0, Int inMinorVersion = 0):type(inType), majorVersion(inMajorVersion), minorVersion(inMinorVersion) {}
+
+ Type type; ///< The type of the compiler
+ Int majorVersion; ///< Major version (interpretation is type specific)
+ Int minorVersion; ///< Minor version
};
-};
-struct CPPCompileOptions
-{
enum class OptimizationLevel
{
Normal, ///< Normal optimization
@@ -52,20 +68,118 @@ struct CPPCompileOptions
String value;
};
- OptimizationLevel optimizationLevel = OptimizationLevel::Debug;
- DebugInfoType debugInfoType = DebugInfoType::Normal;
- TargetType targetType = TargetType::Executable;
+ struct CompileOptions
+ {
+ OptimizationLevel optimizationLevel = OptimizationLevel::Debug;
+ DebugInfoType debugInfoType = DebugInfoType::Normal;
+ TargetType targetType = TargetType::Executable;
+
+ String modulePath; ///< The path/name of the output module. Should not have the extension, as that will be added for each of the target types
+
+ List<Define> defines;
+
+ List<String> sourceFiles;
+
+ List<String> includePaths;
+ List<String> libraryPaths;
+ };
+
+ /// Get the desc of this compiler
+ const Desc& getDesc() const { return m_desc; }
+ /// Compile using the specified options. The result is in resOut
+ virtual SlangResult compile(const CompileOptions& options, ExecuteResult& outResult) = 0;
- String modulePath; ///< The path/name of the output module. Should not have the extension, as that will be added for each of the target types
+protected:
- List<Define> defines;
+ CPPCompiler(const Desc& desc) :
+ m_desc(desc)
+ {}
- List<String> sourceFiles;
+ Desc m_desc;
+};
- List<String> includePaths;
- List<String> libraryPaths;
+class GenericCPPCompiler : public CPPCompiler
+{
+public:
+ typedef CPPCompiler Super;
+
+ typedef void(*CalcArgsFunc)(const CPPCompiler::CompileOptions& options, CommandLine& cmdLine);
+
+ virtual SlangResult compile(const CompileOptions& options, ExecuteResult& outResult) SLANG_OVERRIDE;
+
+ GenericCPPCompiler(const Desc& desc, const String& exeName, CalcArgsFunc func) :
+ Super(desc),
+ m_exeName(exeName),
+ m_func(func)
+ {}
+
+ CalcArgsFunc m_func;
+ String m_exeName;
};
+class CPPCompilerSet : public RefObject
+{
+public:
+ typedef RefObject Super;
+
+
+ /// Find all the available compilers
+ void getCompilerDescs(List<CPPCompiler::Desc>& outCompilerDescs) const;
+ /// Returns list of all compilers
+ void getCompilers(List<CPPCompiler*>& outCompilers) const;
+
+ /// Get a compiler
+ CPPCompiler* getCompiler(const CPPCompiler::Desc& compilerDesc) const;
+
+ /// Will replace if there is one with same desc
+ void addCompiler(CPPCompiler* compiler);
+
+ /// Get a default compiler
+ CPPCompiler* getDefaultCompiler() const { return m_defaultCompiler; }
+ /// Set the default compiler
+ void setDefaultCompiler(CPPCompiler* compiler) { m_defaultCompiler = compiler; }
+
+protected:
+
+ Index _findIndex(const CPPCompiler::Desc& desc) const;
+
+ RefPtr<CPPCompiler> m_defaultCompiler;
+ // This could be a dictionary/map - but doing a linear search is going to be fine and it makes
+ // somethings easier.
+ List<RefPtr<CPPCompiler>> m_compilers;
+};
+
+struct CPPCompilerUtil
+{
+ enum class MatchType
+ {
+ MinGreaterEqual,
+ MinAbsolute,
+ Newest,
+ };
+
+ /// Extracts version number into desc from text (assumes gcc/slang type layout with a line with version starting with versionPrefix)
+ static SlangResult parseGccFamilyVersion(const UnownedStringSlice& text, const UnownedStringSlice& versionPrefix, CPPCompiler::Desc& outDesc);
+
+ /// Runs the exeName, and extracts the version info into outDesc
+ static SlangResult calcGccFamilyVersion(const String& exeName, const UnownedStringSlice& versionPrefix, CPPCompiler::Desc& outDesc);
+
+ /// Find a compiler
+ static CPPCompiler* findCompiler(const CPPCompilerSet* set, MatchType matchType, const CPPCompiler::Desc& desc);
+ static CPPCompiler* findCompiler(const List<CPPCompiler*>& compilers, MatchType matchType, const CPPCompiler::Desc& desc);
+
+ /// Find the compiler closest to the desc
+ static CPPCompiler* findClosestCompiler(const List<CPPCompiler*>& compilers, const CPPCompiler::Desc& desc);
+ static CPPCompiler* findClosestCompiler(const CPPCompilerSet* set, const CPPCompiler::Desc& desc);
+
+ /// Get the information on the compiler used to compile this source
+ static const CPPCompiler::Desc& getCompiledWithDesc();
+
+ /// Given a set, registers compilers found through standard means and determines a reasonable default compiler if possible
+ static SlangResult initializeSet(CPPCompilerSet* set);
+};
+
+
}
#endif
diff --git a/source/core/unix/slang-unix-cpp-compiler-util.cpp b/source/core/unix/slang-unix-cpp-compiler-util.cpp
index a5459b665..9217c6d52 100644
--- a/source/core/unix/slang-unix-cpp-compiler-util.cpp
+++ b/source/core/unix/slang-unix-cpp-compiler-util.cpp
@@ -14,11 +14,11 @@
namespace Slang {
-/* static */void UnixCPPCompilerUtil::calcArgs(const CPPCompileOptions& options, CommandLine& cmdLine)
+/* static */void UnixCPPCompilerUtil::calcArgs(const CPPCompiler::CompileOptions& options, CommandLine& cmdLine)
{
- typedef CPPCompileOptions::OptimizationLevel OptimizationLevel;
- typedef CPPCompileOptions::TargetType TargetType;
- typedef CPPCompileOptions::DebugInfoType DebugInfoType;
+ typedef CPPCompiler::OptimizationLevel OptimizationLevel;
+ typedef CPPCompiler::TargetType TargetType;
+ typedef CPPCompiler::DebugInfoType DebugInfoType;
cmdLine.addArg("-fvisibility=hidden");
// Use shared libraries
diff --git a/source/core/unix/slang-unix-cpp-compiler-util.h b/source/core/unix/slang-unix-cpp-compiler-util.h
index 03c1b5e2e..42886e5eb 100644
--- a/source/core/unix/slang-unix-cpp-compiler-util.h
+++ b/source/core/unix/slang-unix-cpp-compiler-util.h
@@ -16,7 +16,7 @@ struct UnixCPPCompilerUtil
static SlangResult executeCompiler(const CommandLine& commandLine, ExecuteResult& outResult);
/// Calculate the command line args
- static void calcArgs(const CPPCompileOptions& options, CommandLine& cmdLine);
+ static void calcArgs(const CPPCompiler::CompileOptions& options, CommandLine& cmdLine);
};
} // namespace Slang
diff --git a/source/core/windows/slang-win-visual-studio-util.cpp b/source/core/windows/slang-win-visual-studio-util.cpp
index b7de7607c..2fdf7e400 100644
--- a/source/core/windows/slang-win-visual-studio-util.cpp
+++ b/source/core/windows/slang-win-visual-studio-util.cpp
@@ -40,9 +40,33 @@ struct VersionInfo
const char* name; ///< The name of the registry key
};
+
+
+class WinVisualStudioCompiler : public CPPCompiler
+{
+public:
+ typedef CPPCompiler Super;
+
+ Result WinVisualStudioCompiler::compile(const CompileOptions& options, ExecuteResult& outRes) SLANG_OVERRIDE
+ {
+ CommandLine cmdLine;
+ WinVisualStudioUtil::calcArgs(options, cmdLine);
+ return WinVisualStudioUtil::executeCompiler(m_versionPath, cmdLine, outRes);
+ }
+ /// Ctor
+ WinVisualStudioCompiler(const Desc& desc, const WinVisualStudioUtil::VersionPath& versionPath) :
+ Super(desc),
+ m_versionPath(versionPath)
+ {
+ }
+
+ WinVisualStudioUtil::VersionPath m_versionPath;
+};
+
} // anonymous
+
static SlangResult _readRegistryKey(const char* path, const char* keyName, String& outString)
{
// https://docs.microsoft.com/en-us/windows/desktop/api/winreg/nf-winreg-regopenkeyexa
@@ -277,6 +301,26 @@ static SlangResult _find(int versionIndex, WinVisualStudioUtil::VersionPath& out
return SLANG_FAIL;
}
+/* static */SlangResult WinVisualStudioUtil::find(CPPCompilerSet* set)
+{
+ const int versionCount = SLANG_COUNT_OF(s_versionInfos);
+
+ for (int i = versionCount - 1; i >= 0; --i)
+ {
+ const auto& versionInfo = s_versionInfos[i];
+ auto desc = getDesc(versionInfo.version);
+
+ VersionPath versionPath;
+ if (!set->getCompiler(desc) && SLANG_SUCCEEDED(_find(i, versionPath)))
+ {
+ RefPtr<WinVisualStudioCompiler> compiler = new WinVisualStudioCompiler(desc, versionPath);
+ set->addCompiler(compiler);
+ }
+ }
+
+ return SLANG_OK;
+}
+
/* static */SlangResult WinVisualStudioUtil::executeCompiler(const VersionPath& versionPath, const CommandLine& commandLine, ExecuteResult& outResult)
{
// To invoke cl we need to run the suitable vcvars. In order to run this we have to have MS CommandLine.
@@ -336,11 +380,11 @@ static SlangResult _find(int versionIndex, WinVisualStudioUtil::VersionPath& out
}
}
-/* static */void WinVisualStudioUtil::calcArgs(const CPPCompileOptions& options, CommandLine& cmdLine)
+/* static */void WinVisualStudioUtil::calcArgs(const CPPCompiler::CompileOptions& options, CommandLine& cmdLine)
{
- typedef CPPCompileOptions::OptimizationLevel OptimizationLevel;
- typedef CPPCompileOptions::TargetType TargetType;
- typedef CPPCompileOptions::DebugInfoType DebugInfoType;
+ typedef CPPCompiler::OptimizationLevel OptimizationLevel;
+ typedef CPPCompiler::TargetType TargetType;
+ typedef CPPCompiler::DebugInfoType DebugInfoType;
// https://docs.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-alphabetically?view=vs-2019
diff --git a/source/core/windows/slang-win-visual-studio-util.h b/source/core/windows/slang-win-visual-studio-util.h
index e8afbf418..b7e1c8a85 100644
--- a/source/core/windows/slang-win-visual-studio-util.h
+++ b/source/core/windows/slang-win-visual-studio-util.h
@@ -30,6 +30,9 @@ struct WinVisualStudioUtil
/// Given a version find it's path
static SlangResult find(Version version, VersionPath& outPath);
+ /// Find and add to the set (if not already there)
+ static SlangResult find(CPPCompilerSet* set);
+
/// Run visual studio on specified path with the parameters specified on the command line. Output placed in outResult.
static SlangResult executeCompiler(const VersionPath& versionPath, const CommandLine& commandLine, ExecuteResult& outResult);
@@ -46,7 +49,17 @@ struct WinVisualStudioUtil
static void append(Version version, StringBuilder& outBuilder);
/// Calculate the command line args
- static void calcArgs(const CPPCompileOptions& options, CommandLine& cmdLine);
+ static void calcArgs(const CPPCompiler::CompileOptions& options, CommandLine& cmdLine);
+
+ /// Get version as desc
+ static CPPCompiler::Desc getDesc(Version version)
+ {
+ CPPCompiler::Desc desc;
+ desc.type = CPPCompiler::Type::VisualStudio;
+ desc.majorVersion = Int(version) / 10;
+ desc.minorVersion = Int(version) % 10;
+ return desc;
+ }
};