summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/core/slang-cpp-compiler.cpp48
-rw-r--r--source/core/slang-cpp-compiler.h18
-rw-r--r--source/core/slang-platform.cpp22
-rw-r--r--source/core/slang-platform.h3
-rw-r--r--tests/cpp-compiler/c-compile-shared-library.c25
-rw-r--r--tests/cpp-compiler/c-compile.c (renamed from tests/cross-compile/c-compile.c)2
-rw-r--r--tests/cpp-compiler/c-compile.c.expected (renamed from tests/cross-compile/c-compile.c.expected)0
-rw-r--r--tests/cpp-compiler/cpp-compile-shared-library.cpp23
-rw-r--r--tests/cpp-compiler/cpp-compile.cpp9
-rw-r--r--tests/cpp-compiler/cpp-compile.cpp.expected6
-rw-r--r--tools/slang-test/slang-test-main.cpp98
11 files changed, 229 insertions, 25 deletions
diff --git a/source/core/slang-cpp-compiler.cpp b/source/core/slang-cpp-compiler.cpp
index 4bcdd068c..18cb9cdae 100644
--- a/source/core/slang-cpp-compiler.cpp
+++ b/source/core/slang-cpp-compiler.cpp
@@ -33,7 +33,15 @@ SlangResult GenericCPPCompiler::compile(const CompileOptions& options, ExecuteRe
}
#endif
- return ProcessUtil::execute(cmdLine, outResult);
+ SlangResult res = ProcessUtil::execute(cmdLine, outResult);
+
+#if 0
+ {
+ printf("stdout=\"%s\"\nstderr=\"%s\"\nret=%d\n", outResult.standardOutput.getBuffer(), outResult.standardError.getBuffer(), int(outResult.resultCode));
+ }
+#endif
+
+ return res;
}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CPPCompilerUtil !!!!!!!!!!!!!!!!!!!!!!*/
@@ -153,6 +161,16 @@ SlangResult CPPCompilerUtil::calcGCCFamilyVersion(const String& exeName, CPPComp
// Display full path of source files in diagnostics
cmdLine.addArg("/FC");
+ if (options.flags & CompileOptions::Flag::EnableExceptionHandling)
+ {
+ if (options.sourceType == SourceType::CPP)
+ {
+ // https://docs.microsoft.com/en-us/cpp/build/reference/eh-exception-handling-model?view=vs-2019
+ // Assumes c functions cannot throw
+ cmdLine.addArg("/EHsc");
+ }
+ }
+
switch (options.optimizationLevel)
{
case OptimizationLevel::Debug:
@@ -277,28 +295,12 @@ SlangResult CPPCompilerUtil::calcGCCFamilyVersion(const String& exeName, CPPComp
{
case TargetType::SharedLibrary:
{
+ // Shared library
+ cmdLine.addArg("-shared");
// Position independent
cmdLine.addArg("-fPIC");
- String sharedLibraryPath;
-
- // Work out the shared library name
- {
- String moduleDir = Path::getParentDirectory(options.modulePath);
- String moduleFilename = Path::getFileName(options.modulePath);
-
- StringBuilder sharedLibraryFilename;
- SharedLibrary::appendPlatformFileName(moduleFilename.getUnownedSlice(), sharedLibraryFilename);
-
- if (moduleDir.getLength() > 0)
- {
- sharedLibraryPath = Path::combine(moduleDir, sharedLibraryFilename);
- }
- else
- {
- sharedLibraryPath = sharedLibraryFilename;
- }
- }
+ String sharedLibraryPath = SharedLibrary::calcPlatformPath(options.modulePath.getUnownedSlice());
cmdLine.addArg("-o");
cmdLine.addArg(sharedLibraryPath);
@@ -366,6 +368,12 @@ SlangResult CPPCompilerUtil::calcGCCFamilyVersion(const String& exeName, CPPComp
cmdLine.addArg("-F");
cmdLine.addArg(libPath);
}
+
+ if (options.sourceType == SourceType::CPP)
+ {
+ // Make STD libs available
+ cmdLine.addArg("-lstdc++");
+ }
}
static CPPCompiler::Desc _calcCompiledWithDesc()
diff --git a/source/core/slang-cpp-compiler.h b/source/core/slang-cpp-compiler.h
index 82930afd6..83c18bca2 100644
--- a/source/core/slang-cpp-compiler.h
+++ b/source/core/slang-cpp-compiler.h
@@ -23,6 +23,11 @@ public:
GHS,
CountOf,
};
+ enum class SourceType
+ {
+ C, ///< C source
+ CPP, ///< C++ source
+ };
struct Desc
{
@@ -70,9 +75,21 @@ public:
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
@@ -162,6 +179,7 @@ struct CPPCompilerUtil
typedef CPPCompiler::OptimizationLevel OptimizationLevel;
typedef CPPCompiler::TargetType TargetType;
typedef CPPCompiler::DebugInfoType DebugInfoType;
+ typedef CPPCompiler::SourceType SourceType;
enum class MatchType
{
diff --git a/source/core/slang-platform.cpp b/source/core/slang-platform.cpp
index 1cb2bc56e..82f914f7d 100644
--- a/source/core/slang-platform.cpp
+++ b/source/core/slang-platform.cpp
@@ -2,6 +2,7 @@
#include "slang-platform.h"
#include "slang-common.h"
+#include "slang-io.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@@ -25,6 +26,25 @@ namespace Slang
return loadWithPlatformFilename(builder.begin(), handleOut);
}
+/* static */String SharedLibrary::calcPlatformPath(const UnownedStringSlice& path)
+{
+ // Work out the shared library name
+ String parent = Path::getParentDirectory(path);
+ String filename = Path::getFileName(path);
+
+ StringBuilder builder;
+ SharedLibrary::appendPlatformFileName(filename.getUnownedSlice(), builder);
+
+ if (parent.getLength() > 0)
+ {
+ return Path::combine(parent, builder);
+ }
+ else
+ {
+ return builder;
+ }
+}
+
#ifdef _WIN32
// Make sure SlangResult match for common standard window HRESULT
@@ -105,8 +125,8 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst)
{
- // Windows doesn't need the extension or any prefix to work
dst.Append(name);
+ dst.Append(".dll");
}
#else // _WIN32
diff --git a/source/core/slang-platform.h b/source/core/slang-platform.h
index e33c5599d..31552e42b 100644
--- a/source/core/slang-platform.h
+++ b/source/core/slang-platform.h
@@ -42,6 +42,9 @@ namespace Slang
/// The input name should be unadorned with any 'lib' prefix or extension
static void appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst);
+ /// Calculate the shared library
+ static String calcPlatformPath(const UnownedStringSlice& path);
+
private:
/// Not constructible!
SharedLibrary();
diff --git a/tests/cpp-compiler/c-compile-shared-library.c b/tests/cpp-compiler/c-compile-shared-library.c
new file mode 100644
index 000000000..8b6be6115
--- /dev/null
+++ b/tests/cpp-compiler/c-compile-shared-library.c
@@ -0,0 +1,25 @@
+//TEST(smoke):CPP_COMPILER_SHARED_LIBRARY:
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(_MSC_VER)
+# define DLL_EXPORT __declspec(dllexport)
+#else
+//# define DLL_EXPORT
+# define DLL_EXPORT __attribute__ ((dllexport)) __attribute__((__visibility__("default")))
+#endif
+
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C
+#endif
+
+EXTERN_C DLL_EXPORT int test(int intValue, const char* textValue, char* outTextValue)
+{
+ strcpy(outTextValue, textValue);
+ return intValue;
+}
+
diff --git a/tests/cross-compile/c-compile.c b/tests/cpp-compiler/c-compile.c
index 2151f7474..75fdbdaa4 100644
--- a/tests/cross-compile/c-compile.c
+++ b/tests/cpp-compiler/c-compile.c
@@ -1,4 +1,4 @@
-//TEST(smoke):EXECUTE_C:
+//TEST(smoke):CPP_COMPILER_EXECUTE:
#include <stdlib.h>
#include <stdio.h>
diff --git a/tests/cross-compile/c-compile.c.expected b/tests/cpp-compiler/c-compile.c.expected
index 0e042b53b..0e042b53b 100644
--- a/tests/cross-compile/c-compile.c.expected
+++ b/tests/cpp-compiler/c-compile.c.expected
diff --git a/tests/cpp-compiler/cpp-compile-shared-library.cpp b/tests/cpp-compiler/cpp-compile-shared-library.cpp
new file mode 100644
index 000000000..8b70f258d
--- /dev/null
+++ b/tests/cpp-compiler/cpp-compile-shared-library.cpp
@@ -0,0 +1,23 @@
+//TEST(smoke):CPP_COMPILER_SHARED_LIBRARY:
+
+//#include <slang.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iostream>
+using namespace std;
+
+#if defined(_MSC_VER)
+# define DLL_EXPORT __declspec(dllexport)
+#else
+# define DLL_EXPORT __attribute__((__visibility__("default")))
+#endif
+
+extern "C" DLL_EXPORT int test(int intValue, const char* textValue, char* outTextValue)
+{
+ strcpy(outTextValue, textValue);
+ return intValue;
+}
+
diff --git a/tests/cpp-compiler/cpp-compile.cpp b/tests/cpp-compiler/cpp-compile.cpp
new file mode 100644
index 000000000..c3141a876
--- /dev/null
+++ b/tests/cpp-compiler/cpp-compile.cpp
@@ -0,0 +1,9 @@
+//TEST(smoke):CPP_COMPILER_EXECUTE:
+#include <iostream>
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "Hello World!" << endl;
+ return 0;
+}
diff --git a/tests/cpp-compiler/cpp-compile.cpp.expected b/tests/cpp-compiler/cpp-compile.cpp.expected
new file mode 100644
index 000000000..0e042b53b
--- /dev/null
+++ b/tests/cpp-compiler/cpp-compile.cpp.expected
@@ -0,0 +1,6 @@
+result code = 0
+standard error = {
+}
+standard output = {
+Hello World!
+}
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index 0777c31f2..e792abe72 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -1086,7 +1086,7 @@ String getExpectedOutput(String const& outputStem)
return expectedOutput;
}
-static TestResult runExecuteC(TestContext* context, TestInput& input)
+static TestResult runCPPCompilerExecute(TestContext* context, TestInput& input)
{
CPPCompilerSet* compilerSet = context->getCPPCompilerSet();
CPPCompiler* compiler = compilerSet ? compilerSet->getDefaultCompiler() : nullptr;
@@ -1111,7 +1111,7 @@ static TestResult runExecuteC(TestContext* context, TestInput& input)
// Make the module name the same as the source file
String directory = Path::getParentDirectory(input.outputStem);
String moduleName = Path::getFileNameWithoutExt(filePath);
-
+ String ext = Path::getFileExt(filePath);
String modulePath = Path::combine(directory, moduleName);
// Remove the binary..
@@ -1125,6 +1125,8 @@ static TestResult runExecuteC(TestContext* context, TestInput& input)
// Set up the compilation options
CPPCompiler::CompileOptions options;
+ options.sourceType = (ext == "c") ? CPPCompiler::SourceType::C : CPPCompiler::SourceType::CPP;
+
// Compile this source
options.sourceFiles.add(filePath);
options.modulePath = modulePath;
@@ -1177,6 +1179,95 @@ static TestResult runExecuteC(TestContext* context, TestInput& input)
return TestResult::Pass;
}
+static TestResult runCPPCompilerSharedLibrary(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())
+ {
+ return TestResult::Pass;
+ }
+
+ auto filePath = input.filePath;
+ auto outputStem = input.outputStem;
+
+ String actualOutputPath = outputStem + ".actual";
+ File::remove(actualOutputPath);
+
+ // Make the module name the same as the source file
+ String directory = Path::getParentDirectory(input.outputStem);
+ String moduleName = Path::getFileNameWithoutExt(filePath);
+ String ext = Path::getFileExt(filePath);
+
+ String modulePath = Path::combine(directory, moduleName);
+
+ // Remove the binary..
+ String sharedLibraryPath = SharedLibrary::calcPlatformPath(modulePath.getUnownedSlice());
+ File::remove(sharedLibraryPath);
+
+ // Set up the compilation options
+ CPPCompiler::CompileOptions options;
+
+ options.sourceType = (ext == "c") ? CPPCompiler::SourceType::C : CPPCompiler::SourceType::CPP;
+
+ // Build a shared library
+ options.targetType = CPPCompiler::TargetType::SharedLibrary;
+
+ // Compile this source
+ options.sourceFiles.add(filePath);
+ options.modulePath = modulePath;
+
+ options.includePaths.add(".");
+
+ ExecuteResult exeRes;
+
+ if (SLANG_FAILED(compiler->compile(options, exeRes)))
+ {
+ return TestResult::Fail;
+ }
+
+ SharedLibrary::Handle handle;
+ if (SLANG_FAILED(SharedLibrary::loadWithPlatformFilename(sharedLibraryPath.getBuffer(), handle)))
+ {
+ return TestResult::Fail;
+ }
+
+ const int inValue = 10;
+ const char inBuffer[] = "Hello World!";
+
+ char buffer[128] = "";
+ int value = 0;
+
+ typedef int (*TestFunc)(int intValue, const char* textValue, char* outTextValue);
+
+ // We could capture output if we passed in a ISlangWriter - but for that to work we'd need a
+ TestFunc testFunc = (TestFunc)SharedLibrary::findFuncByName(handle, "test");
+ if (testFunc)
+ {
+ value = testFunc(inValue, inBuffer, buffer);
+ }
+ else
+ {
+ printf("Unable to access 'test' function\n");
+ }
+
+ SharedLibrary::unload(handle);
+
+ if (!(inValue == value && strcmp(inBuffer, buffer) == 0))
+ {
+ return TestResult::Fail;
+ }
+
+ return TestResult::Pass;
+}
+
TestResult runCrossCompilerTest(TestContext* context, TestInput& input)
{
// need to execute the stand-alone Slang compiler on the file
@@ -1983,7 +2074,8 @@ static const TestCommandInfo s_testCommandInfos[] =
{ "COMPARE_RENDER_COMPUTE", &runSlangRenderComputeComparisonTest},
{ "COMPARE_GLSL", &runGLSLComparisonTest},
{ "CROSS_COMPILE", &runCrossCompilerTest},
- { "EXECUTE_C", &runExecuteC},
+ { "CPP_COMPILER_EXECUTE", &runCPPCompilerExecute},
+ { "CPP_COMPILER_SHARED_LIBRARY", &runCPPCompilerSharedLibrary},
};
TestResult runTest(