summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--tools/slang-test/slang-test-main.cpp35
-rw-r--r--tools/slang-test/test-context.cpp10
-rw-r--r--tools/slang-test/test-context.h6
11 files changed, 567 insertions, 51 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;
+ }
};
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index b93833f89..fdd5cd13d 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -1094,6 +1094,14 @@ String getExpectedOutput(String const& outputStem)
static TestResult runExecuteC(TestContext* context, TestInput& input)
{
+ CPPCompilerSet* compilerSet = context->getCPPCompilerSet();
+ CPPCompiler* compiler = compilerSet ? compilerSet->getDefaultCompiler() : nullptr;
+
+ if (!compiler)
+ {
+ return TestResult::Ignored;
+ }
+
// If we are just collecting requirements, say it passed
if (context->isCollectingRequirements())
{
@@ -1112,7 +1120,7 @@ static TestResult runExecuteC(TestContext* context, TestInput& input)
String modulePath = Path::combine(directory, moduleName);
- CPPCompileOptions options;
+ CPPCompiler::CompileOptions options;
// Compile this source
options.sourceFiles.add(filePath);
@@ -1120,33 +1128,10 @@ static TestResult runExecuteC(TestContext* context, TestInput& input)
ExecuteResult exeRes;
-#ifdef _WIN32
- // Find
- List<WinVisualStudioUtil::VersionPath> versionPaths;
- WinVisualStudioUtil::find(versionPaths);
-
- // Didn't find the visual studio compiler
- if (versionPaths.getCount() <= 0)
- {
- return TestResult::Ignored;
- }
-
- CommandLine cmdLine;
- WinVisualStudioUtil::calcArgs(options, cmdLine);
-
- if (SLANG_FAILED(WinVisualStudioUtil::executeCompiler(versionPaths[0], cmdLine, exeRes)))
- {
- return TestResult::Fail;
- }
-#else
- CommandLine cmdLine;
- UnixCPPCompilerUtil::calcArgs(options, cmdLine);
-
- if (SLANG_FAILED(UnixCPPCompilerUtil::executeCompiler(cmdLine, exeRes)))
+ if (SLANG_FAILED(compiler->compile(options, exeRes)))
{
return TestResult::Fail;
}
-#endif
// Execute the binary and see what we get
{
diff --git a/tools/slang-test/test-context.cpp b/tools/slang-test/test-context.cpp
index 0b17b3672..90052c4c4 100644
--- a/tools/slang-test/test-context.cpp
+++ b/tools/slang-test/test-context.cpp
@@ -90,3 +90,13 @@ void TestContext::setInnerMainFunc(const String& name, InnerMainFunc func)
m_sharedLibTools.Add(name, tool);
}
}
+
+CPPCompilerSet* TestContext::getCPPCompilerSet()
+{
+ if (!cppCompilerSet)
+ {
+ cppCompilerSet = new CPPCompilerSet;
+ CPPCompilerUtil::initializeSet(cppCompilerSet);
+ }
+ return cppCompilerSet;
+}
diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h
index afc5bb427..895cb9c06 100644
--- a/tools/slang-test/test-context.h
+++ b/tools/slang-test/test-context.h
@@ -9,6 +9,7 @@
#include "../../source/core/slang-dictionary.h"
#include "../../source/core/slang-test-tool-util.h"
#include "../../source/core/slang-render-api-util.h"
+#include "../../source/core/slang-cpp-compiler.h"
#include "options.h"
@@ -95,6 +96,9 @@ class TestContext
/// If set, then tests are executed
bool isExecuting() const { return testRequirements == nullptr; }
+ /// Get compiler factory
+ Slang::CPPCompilerSet* getCPPCompilerSet();
+
/// Ctor
TestContext();
/// Dtor
@@ -111,6 +115,8 @@ class TestContext
Slang::RenderApiFlags availableRenderApiFlags = 0;
bool isAvailableRenderApiFlagsValid = false;
+ Slang::RefPtr<Slang::CPPCompilerSet> cppCompilerSet;
+
protected:
struct SharedLibraryTool
{