Skip to content

Commit 749634a

Browse files
authored
Slang -> C++ -> SharedLibrary -> Test (shader-slang#999)
* WIP: Adding support for C/C++ compilation to slang API. * Removed BackEndType in test harness -> use SlangPassThrough to identify backends Only require stage for targets that require it. Detection of all different backends. * Windows/Unix create temporary filename. * WIP: Output CPU binaries. * Added a pass-through c/c++ test. * Compile C++/C and store in temporary file. * Read the binary back into memory. * Set debug info and optimization flags for C/C++. Make the CPPCompiler debug/optimization levels match slangs. * Handling of include paths and math precision. * Dumping c++/c source and exe/shared library. * Put hex dump into own util. * End to end pass through c compilation test. * WIP: Simple execute test working on Linux/Unix. * Fix typo on linux. * WIP: To compile slang to cpp shared library. Report backend compiler errors. * Compiles slang -> cpp and loads as shared library. * Fix problem on c-cross-compile test because prelude is now included with <> quotes. * Run slang generated cpp code - using hard coded data. * Added cpp-execute-simple, and test output. * Fix warning that broke win32 build. * Fix compilation problem on osx.
1 parent f52f5cd commit 749634a

36 files changed

+1786
-210
lines changed

slang.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ extern "C"
514514
SLANG_DXIL_ASM,
515515
SLANG_C_SOURCE, ///< The C language
516516
SLANG_CPP_SOURCE, ///< The C++ language
517+
SLANG_EXECUTABLE, ///< Executable (for hosting CPU/OS)
518+
SLANG_SHARED_LIBRARY, ///< A shared library/Dll (for hosting CPU/OS)
517519
};
518520

519521
/* A "container format" describes the way that the outputs
@@ -537,6 +539,11 @@ extern "C"
537539
SLANG_PASS_THROUGH_FXC,
538540
SLANG_PASS_THROUGH_DXC,
539541
SLANG_PASS_THROUGH_GLSLANG,
542+
SLANG_PASS_THROUGH_CLANG, ///< Clang C/C++ compiler
543+
SLANG_PASS_THROUGH_VISUAL_STUDIO, ///< Visual studio C/C++ compiler
544+
SLANG_PASS_THROUGH_GCC, ///< GCC C/C++ compiler
545+
SLANG_PASS_THROUGH_GENERIC_C_CPP, ///< Generic C or C++ compiler, which is decided by the source type
546+
SLANG_PASS_THROUGH_COUNT_OF,
540547
};
541548

542549
/*!
@@ -601,6 +608,8 @@ extern "C"
601608
SLANG_SOURCE_LANGUAGE_SLANG,
602609
SLANG_SOURCE_LANGUAGE_HLSL,
603610
SLANG_SOURCE_LANGUAGE_GLSL,
611+
SLANG_SOURCE_LANGUAGE_C,
612+
SLANG_SOURCE_LANGUAGE_CPP,
604613
};
605614

606615
typedef unsigned int SlangProfileID;
@@ -859,7 +868,7 @@ extern "C"
859868

860869
typedef void(*SlangFuncPtr)(void);
861870

862-
/** An interface that can be used to encapsulate access to a shared library. An implementaion
871+
/** An interface that can be used to encapsulate access to a shared library. An implementation
863872
does not have to implement the library as a shared library.
864873
*/
865874
struct ISlangSharedLibrary: public ISlangUnknown

source/core/core.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
<ClInclude Include="slang-free-list.h" />
183183
<ClInclude Include="slang-gcc-compiler-util.h" />
184184
<ClInclude Include="slang-hash.h" />
185+
<ClInclude Include="slang-hex-dump-util.h" />
185186
<ClInclude Include="slang-io.h" />
186187
<ClInclude Include="slang-list.h" />
187188
<ClInclude Include="slang-math.h" />
@@ -213,6 +214,7 @@
213214
<ClCompile Include="slang-cpp-compiler.cpp" />
214215
<ClCompile Include="slang-free-list.cpp" />
215216
<ClCompile Include="slang-gcc-compiler-util.cpp" />
217+
<ClCompile Include="slang-hex-dump-util.cpp" />
216218
<ClCompile Include="slang-io.cpp" />
217219
<ClCompile Include="slang-memory-arena.cpp" />
218220
<ClCompile Include="slang-object-scope-manager.cpp" />

source/core/core.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
<ClInclude Include="slang-hash.h">
4646
<Filter>Header Files</Filter>
4747
</ClInclude>
48+
<ClInclude Include="slang-hex-dump-util.h">
49+
<Filter>Header Files</Filter>
50+
</ClInclude>
4851
<ClInclude Include="slang-io.h">
4952
<Filter>Header Files</Filter>
5053
</ClInclude>
@@ -134,6 +137,9 @@
134137
<ClCompile Include="slang-gcc-compiler-util.cpp">
135138
<Filter>Source Files</Filter>
136139
</ClCompile>
140+
<ClCompile Include="slang-hex-dump-util.cpp">
141+
<Filter>Source Files</Filter>
142+
</ClCompile>
137143
<ClCompile Include="slang-io.cpp">
138144
<Filter>Source Files</Filter>
139145
</ClCompile>

source/core/slang-cpp-compiler.cpp

+45-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@
1919
namespace Slang
2020
{
2121

22+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompiler::Desc !!!!!!!!!!!!!!!!!!!!!!*/
23+
24+
void CPPCompiler::Desc::appendAsText(StringBuilder& out) const
25+
{
26+
out << getCompilerTypeAsText(type);
27+
out << " ";
28+
out << majorVersion;
29+
out << ".";
30+
out << minorVersion;
31+
}
32+
2233
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompiler::OutputMessage !!!!!!!!!!!!!!!!!!!!!!*/
2334

2435
/* static */UnownedStringSlice CPPCompiler::OutputMessage::getTypeText(OutputMessage::Type type)
@@ -33,6 +44,21 @@ namespace Slang
3344
}
3445
}
3546

47+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompiler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
48+
49+
/* static */UnownedStringSlice CPPCompiler::getCompilerTypeAsText(CompilerType type)
50+
{
51+
switch (type)
52+
{
53+
default:
54+
case CompilerType::Unknown: return UnownedStringSlice::fromLiteral("Unknown");
55+
case CompilerType::VisualStudio:return UnownedStringSlice::fromLiteral("Visual Studio");
56+
case CompilerType::GCC: return UnownedStringSlice::fromLiteral("GCC");
57+
case CompilerType::Clang: return UnownedStringSlice::fromLiteral("Clang");
58+
case CompilerType::SNC: return UnownedStringSlice::fromLiteral("SNC");
59+
case CompilerType::GHS: return UnownedStringSlice::fromLiteral("GHS");
60+
}
61+
}
3662

3763
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompiler::Output !!!!!!!!!!!!!!!!!!!!!!*/
3864

@@ -167,6 +193,11 @@ SlangResult GenericCPPCompiler::compile(const CompileOptions& options, Output& o
167193
return m_parseOutputFunc(exeRes, outOutput);
168194
}
169195

196+
SlangResult GenericCPPCompiler::calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath)
197+
{
198+
return m_calcModuleFilePathFunc(options, outPath);
199+
}
200+
170201
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompilerUtil !!!!!!!!!!!!!!!!!!!!!!*/
171202

172203
static CPPCompiler::Desc _calcCompiledWithDesc()
@@ -308,7 +339,7 @@ static void _addGCCFamilyCompiler(const String& exeName, CPPCompilerSet* compile
308339
CPPCompiler::Desc desc;
309340
if (SLANG_SUCCEEDED(GCCCompilerUtil::calcVersion(exeName, desc)))
310341
{
311-
RefPtr<CPPCompiler> compiler(new GenericCPPCompiler(desc, exeName, &GCCCompilerUtil::calcArgs, &GCCCompilerUtil::parseOutput));
342+
RefPtr<CPPCompiler> compiler(new GenericCPPCompiler(desc, exeName, &GCCCompilerUtil::calcArgs, &GCCCompilerUtil::parseOutput, GCCCompilerUtil::calcModuleFilePath));
312343
compilerSet->addCompiler(compiler);
313344
}
314345
}
@@ -377,6 +408,19 @@ void CPPCompilerSet::getCompilers(List<CPPCompiler*>& outCompilers) const
377408
outCompilers.addRange((CPPCompiler*const*)m_compilers.begin(), m_compilers.getCount());
378409
}
379410

411+
bool CPPCompilerSet::hasCompiler(CPPCompiler::CompilerType compilerType) const
412+
{
413+
for (CPPCompiler* compiler : m_compilers)
414+
{
415+
const auto& desc = compiler->getDesc();
416+
if (desc.type == compilerType)
417+
{
418+
return true;
419+
}
420+
}
421+
return false;
422+
}
423+
380424
void CPPCompilerSet::addCompiler(CPPCompiler* compiler)
381425
{
382426
const Index index = _findIndex(compiler->getDesc());

source/core/slang-cpp-compiler.h

+41-12
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class CPPCompiler: public RefObject
4040
/// Get the version as a value
4141
Int getVersionValue() const { return majorVersion * 100 + minorVersion; }
4242

43+
void appendAsText(StringBuilder& out) const;
44+
4345
/// Ctor
4446
Desc(CompilerType inType = CompilerType::Unknown, Int inMajorVersion = 0, Int inMinorVersion = 0):type(inType), majorVersion(inMajorVersion), minorVersion(inMinorVersion) {}
4547

@@ -50,16 +52,26 @@ class CPPCompiler: public RefObject
5052

5153
enum class OptimizationLevel
5254
{
53-
Normal, ///< Normal optimization
54-
Debug, ///< General has no optimizations
55+
None, ///< Don't optimize at all.
56+
Default, ///< Default optimization level: balance code quality and compilation time.
57+
High, ///< Optimize aggressively.
58+
Maximal, ///< Include optimizations that may take a very long time, or may involve severe space-vs-speed tradeoffs
5559
};
5660

57-
enum DebugInfoType
61+
enum class DebugInfoType
62+
{
63+
None, ///< Don't emit debug information at all.
64+
Minimal, ///< Emit as little debug information as possible, while still supporting stack traces.
65+
Standard, ///< Emit whatever is the standard level of debug information for each target.
66+
Maximal, ///< Emit as much debug information as possible for each target.
67+
};
68+
enum class FloatingPointMode
5869
{
59-
None, ///< Binary has no debug information
60-
Maximum, ///< Has maximum debug information
61-
Normal, ///< Has normal debug information
70+
Default,
71+
Fast,
72+
Precise,
6273
};
74+
6375
enum TargetType
6476
{
6577
Executable, ///< Produce an executable
@@ -84,10 +96,11 @@ class CPPCompiler: public RefObject
8496
};
8597
};
8698

87-
OptimizationLevel optimizationLevel = OptimizationLevel::Debug;
88-
DebugInfoType debugInfoType = DebugInfoType::Normal;
99+
OptimizationLevel optimizationLevel = OptimizationLevel::Default;
100+
DebugInfoType debugInfoType = DebugInfoType::Standard;
89101
TargetType targetType = TargetType::Executable;
90102
SourceType sourceType = SourceType::CPP;
103+
FloatingPointMode floatingPointMode = FloatingPointMode::Default;
91104

92105
Flags flags = Flag::EnableExceptionHandling;
93106

@@ -163,6 +176,11 @@ class CPPCompiler: public RefObject
163176
const Desc& getDesc() const { return m_desc; }
164177
/// Compile using the specified options. The result is in resOut
165178
virtual SlangResult compile(const CompileOptions& options, Output& outOutput) = 0;
179+
/// Given the compilation options and the module name, determines the actual file name used for output
180+
virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) = 0;
181+
182+
/// Return the compiler type as name
183+
static UnownedStringSlice getCompilerTypeAsText(CompilerType type);
166184

167185
protected:
168186

@@ -180,26 +198,31 @@ class GenericCPPCompiler : public CPPCompiler
180198

181199
typedef void(*CalcArgsFunc)(const CPPCompiler::CompileOptions& options, CommandLine& cmdLine);
182200
typedef SlangResult(*ParseOutputFunc)(const ExecuteResult& exeResult, Output& output);
201+
typedef SlangResult(*CalcModuleFilePathFunc)(const CPPCompiler::CompileOptions& options, StringBuilder& outPath);
183202

184203
virtual SlangResult compile(const CompileOptions& options, Output& outOutput) SLANG_OVERRIDE;
204+
virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) SLANG_OVERRIDE;
185205

186-
GenericCPPCompiler(const Desc& desc, const String& exeName, CalcArgsFunc calcArgsFunc, ParseOutputFunc parseOutputFunc) :
206+
GenericCPPCompiler(const Desc& desc, const String& exeName, CalcArgsFunc calcArgsFunc, ParseOutputFunc parseOutputFunc, CalcModuleFilePathFunc calcModuleFilePathFunc) :
187207
Super(desc),
188208
m_calcArgsFunc(calcArgsFunc),
189-
m_parseOutputFunc(parseOutputFunc)
209+
m_parseOutputFunc(parseOutputFunc),
210+
m_calcModuleFilePathFunc(calcModuleFilePathFunc)
190211
{
191212
m_cmdLine.setExecutableFilename(exeName);
192213
}
193214

194-
GenericCPPCompiler(const Desc& desc, const CommandLine& cmdLine, CalcArgsFunc calcArgsFunc, ParseOutputFunc parseOutputFunc) :
215+
GenericCPPCompiler(const Desc& desc, const CommandLine& cmdLine, CalcArgsFunc calcArgsFunc, ParseOutputFunc parseOutputFunc, CalcModuleFilePathFunc calcModuleFilePathFunc) :
195216
Super(desc),
196217
m_cmdLine(cmdLine),
197218
m_calcArgsFunc(calcArgsFunc),
198-
m_parseOutputFunc(parseOutputFunc)
219+
m_parseOutputFunc(parseOutputFunc),
220+
m_calcModuleFilePathFunc(calcModuleFilePathFunc)
199221
{}
200222

201223
CalcArgsFunc m_calcArgsFunc;
202224
ParseOutputFunc m_parseOutputFunc;
225+
CalcModuleFilePathFunc m_calcModuleFilePathFunc;
203226
CommandLine m_cmdLine;
204227
};
205228

@@ -225,6 +248,9 @@ class CPPCompilerSet : public RefObject
225248
/// Set the default compiler
226249
void setDefaultCompiler(CPPCompiler* compiler) { m_defaultCompiler = compiler; }
227250

251+
/// True if has a compiler of the specified type
252+
bool hasCompiler(CPPCompiler::CompilerType compilerType) const;
253+
228254
protected:
229255

230256
Index _findIndex(const CPPCompiler::Desc& desc) const;
@@ -263,6 +289,9 @@ struct CPPCompilerUtil
263289

264290
/// Given a set, registers compilers found through standard means and determines a reasonable default compiler if possible
265291
static SlangResult initializeSet(CPPCompilerSet* set);
292+
293+
294+
266295
};
267296

268297

source/core/slang-gcc-compiler-util.cpp

+63-14
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,34 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
335335
return SLANG_OK;
336336
}
337337

338+
/* static */ SlangResult GCCCompilerUtil::calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath)
339+
{
340+
outPath.Clear();
341+
342+
switch (options.targetType)
343+
{
344+
case TargetType::SharedLibrary:
345+
{
346+
outPath << SharedLibrary::calcPlatformPath(options.modulePath.getUnownedSlice());
347+
return SLANG_OK;
348+
}
349+
case TargetType::Executable:
350+
{
351+
outPath << options.modulePath;
352+
outPath << ProcessUtil::getExecutableSuffix();
353+
return SLANG_OK;
354+
}
355+
case TargetType::Object:
356+
{
357+
// Will be .o for typical gcc targets
358+
outPath << options.modulePath << ".o";
359+
return SLANG_OK;
360+
}
361+
}
362+
363+
return SLANG_FAIL;
364+
}
365+
338366
/* static */void GCCCompilerUtil::calcArgs(const CompileOptions& options, CommandLine& cmdLine)
339367
{
340368
cmdLine.addArg("-fvisibility=hidden");
@@ -349,17 +377,27 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
349377

350378
switch (options.optimizationLevel)
351379
{
352-
case OptimizationLevel::Debug:
380+
case OptimizationLevel::None:
353381
{
354382
// No optimization
355383
cmdLine.addArg("-O0");
356384
break;
357385
}
358-
case OptimizationLevel::Normal:
386+
case OptimizationLevel::Default:
359387
{
360388
cmdLine.addArg("-Os");
361389
break;
362390
}
391+
case OptimizationLevel::High:
392+
{
393+
cmdLine.addArg("-O2");
394+
break;
395+
}
396+
case OptimizationLevel::Maximal:
397+
{
398+
cmdLine.addArg("-O4");
399+
break;
400+
}
363401
default: break;
364402
}
365403

@@ -368,6 +406,29 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
368406
cmdLine.addArg("-g");
369407
}
370408

409+
switch (options.floatingPointMode)
410+
{
411+
case FloatingPointMode::Default: break;
412+
case FloatingPointMode::Precise:
413+
{
414+
//cmdLine.addArg("-fno-unsafe-math-optimizations");
415+
break;
416+
}
417+
case FloatingPointMode::Fast:
418+
{
419+
// We could enable SSE with -mfpmath=sse
420+
// But that would only make sense on a x64/x86 type processor and only if that feature is present (it is on all x64)
421+
cmdLine.addArg("-ffast-math");
422+
break;
423+
}
424+
}
425+
426+
StringBuilder moduleFilePath;
427+
calcModuleFilePath(options, moduleFilePath);
428+
429+
cmdLine.addArg("-o");
430+
cmdLine.addArg(moduleFilePath);
431+
371432
switch (options.targetType)
372433
{
373434
case TargetType::SharedLibrary:
@@ -376,22 +437,10 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
376437
cmdLine.addArg("-shared");
377438
// Position independent
378439
cmdLine.addArg("-fPIC");
379-
380-
String sharedLibraryPath = SharedLibrary::calcPlatformPath(options.modulePath.getUnownedSlice());
381-
382-
cmdLine.addArg("-o");
383-
cmdLine.addArg(sharedLibraryPath);
384440
break;
385441
}
386442
case TargetType::Executable:
387443
{
388-
cmdLine.addArg("-o");
389-
390-
StringBuilder builder;
391-
builder << options.modulePath;
392-
builder << ProcessUtil::getExecutableSuffix();
393-
394-
cmdLine.addArg(options.modulePath);
395444
break;
396445
}
397446
case TargetType::Object:

0 commit comments

Comments
 (0)