1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
#ifndef SLANG_CPP_COMPILER_H
#define SLANG_CPP_COMPILER_H
#include "slang-common.h"
#include "slang-string.h"
#include "slang-process-util.h"
namespace Slang
{
class CPPCompiler: public RefObject
{
public:
typedef RefObject Super;
enum class Type
{
Unknown,
VisualStudio,
GCC,
Clang,
SNC,
GHS,
CountOf,
};
enum class SourceType
{
C, ///< C source
CPP, ///< C++ source
};
struct Desc
{
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
};
enum class OptimizationLevel
{
Normal, ///< Normal optimization
Debug, ///< General has no optimizations
};
enum DebugInfoType
{
None, ///< Binary has no debug information
Maximum, ///< Has maximum debug information
Normal, ///< Has normal debug information
};
enum TargetType
{
Executable, ///< Produce an executable
SharedLibrary, ///< Produce a shared library object/dll
Object, ///< Produce an object file
};
struct Define
{
String nameWithSig; ///< If macro takes parameters include in brackets
String value;
};
struct CompileOptions
{
typedef uint32_t Flags;
struct Flag
{
enum Enum : Flags
{
EnableExceptionHandling = 0x01,
};
};
OptimizationLevel optimizationLevel = OptimizationLevel::Debug;
DebugInfoType debugInfoType = DebugInfoType::Normal;
TargetType targetType = TargetType::Executable;
SourceType sourceType = SourceType::CPP;
Flags flags = Flag::EnableExceptionHandling;
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;
protected:
CPPCompiler(const Desc& desc) :
m_desc(desc)
{}
Desc m_desc;
};
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_func(func)
{
m_cmdLine.setExecutableFilename(exeName);
}
GenericCPPCompiler(const Desc& desc, const CommandLine& cmdLine, CalcArgsFunc func) :
Super(desc),
m_cmdLine(cmdLine),
m_func(func)
{}
CalcArgsFunc m_func;
CommandLine m_cmdLine;
};
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
{
typedef CPPCompiler::CompileOptions CompileOptions;
typedef CPPCompiler::OptimizationLevel OptimizationLevel;
typedef CPPCompiler::TargetType TargetType;
typedef CPPCompiler::DebugInfoType DebugInfoType;
typedef CPPCompiler::SourceType SourceType;
enum class MatchType
{
MinGreaterEqual,
MinAbsolute,
Newest,
};
/// Extracts version number into desc from text (assumes gcc/clang -v layout with a line with version)
static SlangResult parseGCCFamilyVersion(const UnownedStringSlice& text, const UnownedStringSlice& prefix, CPPCompiler::Desc& outDesc);
/// Runs the exeName, and extracts the version info into outDesc
static SlangResult calcGCCFamilyVersion(const String& exeName, CPPCompiler::Desc& outDesc);
/// Calculate gcc family compilers (including clang) cmdLine arguments from options
static void calcGCCFamilyArgs(const CompileOptions& options, CommandLine& cmdLine);
/// Calculate Visual Studio family compilers cmdLine arguments from options
static void calcVisualStudioArgs(const CompileOptions& options, CommandLine& cmdLine);
/// 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
|