Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToni Solarin-Sodara <toni.edward@outlook.com>2018-03-07 18:09:22 +0300
committerJan Kotas <jkotas@microsoft.com>2018-03-07 18:09:22 +0300
commit998d168987688abbd14810ee757a8320219e9af8 (patch)
tree2c535d8b8b11133dc05035b932dd4832616703c8
parente7cbc86bf9db0ba4fa547a1ec58ccc2073bbd8a1 (diff)
Add tests for building native shared and static libraries (#5443)
* add preliminary Library test project (#4985) * update library test and make it pass on Windows (#4985) * rename Library test project to SharedLibrary (#4985) * update sharedlib test, make it pass on darwin (#4985) * update msbuild tag names (#4985) * move native runner rsp file to native intermediate output path (#4985) * add test for static library, make it pass on unix (#4985) * update static library test, make it pass on Windows * skip shared library test for linux (#4985) * fix StaticLibrary linux build (#4985) * update unix linker args when building StaticLibrary native binary (#4985) * add copyright headers to all newly added source files (#4985) * fix multimodule build errors for native library builds (#4985) * add comment explaining owning module of native library startup method (#4985) * set owning module of native library startup method to gen'd module (#4985) * remove unneeded System.Linq import (#4985)
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/NativeLibraryInitializerRootProvider.cs4
-rw-r--r--src/ILCompiler/src/Program.cs47
-rw-r--r--tests/src/Simple/SharedLibrary/NativeCallable.cs14
-rw-r--r--tests/src/Simple/SharedLibrary/SharedLibrary.cmd12
-rw-r--r--tests/src/Simple/SharedLibrary/SharedLibrary.cpp66
-rw-r--r--tests/src/Simple/SharedLibrary/SharedLibrary.cs37
-rw-r--r--tests/src/Simple/SharedLibrary/SharedLibrary.csproj35
-rwxr-xr-xtests/src/Simple/SharedLibrary/SharedLibrary.sh9
-rw-r--r--tests/src/Simple/SharedLibrary/no_cpp1
-rw-r--r--tests/src/Simple/SharedLibrary/no_linux1
-rw-r--r--tests/src/Simple/StaticLibrary/NativeCallable.cs14
-rw-r--r--tests/src/Simple/StaticLibrary/StaticLibrary.cmd12
-rw-r--r--tests/src/Simple/StaticLibrary/StaticLibrary.cpp23
-rw-r--r--tests/src/Simple/StaticLibrary/StaticLibrary.cs30
-rw-r--r--tests/src/Simple/StaticLibrary/StaticLibrary.csproj52
-rwxr-xr-xtests/src/Simple/StaticLibrary/StaticLibrary.sh9
-rw-r--r--tests/src/Simple/StaticLibrary/no_cpp1
17 files changed, 342 insertions, 25 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/NativeLibraryInitializerRootProvider.cs b/src/ILCompiler.Compiler/src/Compiler/NativeLibraryInitializerRootProvider.cs
index d7460d45a..7f1e67700 100644
--- a/src/ILCompiler.Compiler/src/Compiler/NativeLibraryInitializerRootProvider.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/NativeLibraryInitializerRootProvider.cs
@@ -20,10 +20,10 @@ namespace ILCompiler
/// </summary>
public const string ManagedEntryPointMethodName = "__managed__Startup";
- private EcmaModule _module;
+ private ModuleDesc _module;
private IList<MethodDesc> _libraryInitializers;
- public NativeLibraryInitializerRootProvider(EcmaModule module, IList<MethodDesc> libraryInitializers)
+ public NativeLibraryInitializerRootProvider(ModuleDesc module, IList<MethodDesc> libraryInitializers)
{
_module = module;
_libraryInitializers = libraryInitializers;
diff --git a/src/ILCompiler/src/Program.cs b/src/ILCompiler/src/Program.cs
index b86796ad6..e980088c8 100644
--- a/src/ILCompiler/src/Program.cs
+++ b/src/ILCompiler/src/Program.cs
@@ -88,20 +88,20 @@ namespace ILCompiler
switch (RuntimeInformation.ProcessArchitecture)
{
- case Architecture.X86:
- _targetArchitecture = TargetArchitecture.X86;
- break;
- case Architecture.X64:
- _targetArchitecture = TargetArchitecture.X64;
- break;
- case Architecture.Arm:
- _targetArchitecture = TargetArchitecture.ARM;
- break;
- case Architecture.Arm64:
- _targetArchitecture = TargetArchitecture.ARM64;
- break;
- default:
- throw new NotImplementedException();
+ case Architecture.X86:
+ _targetArchitecture = TargetArchitecture.X86;
+ break;
+ case Architecture.X64:
+ _targetArchitecture = TargetArchitecture.X64;
+ break;
+ case Architecture.Arm:
+ _targetArchitecture = TargetArchitecture.ARM;
+ break;
+ case Architecture.Arm64:
+ _targetArchitecture = TargetArchitecture.ARM64;
+ break;
+ default:
+ throw new NotImplementedException();
}
// Workaround for https://github.com/dotnet/corefx/issues/25267
@@ -190,7 +190,7 @@ namespace ILCompiler
Help(syntax.GetHelpText());
return 1;
}
-
+
if (_outputFilePath == null)
throw new CommandLineException("Output filename must be specified (/out <file>)");
@@ -242,7 +242,7 @@ namespace ILCompiler
SharedGenericsMode.CanonicalReferenceTypes : SharedGenericsMode.Disabled;
// TODO: compiler switch for SIMD support?
- var simdVectorLength = (_isCppCodegen || _isWasmCodegen) ? SimdVectorLength.None : SimdVectorLength.Vector128Bit;
+ var simdVectorLength = (_isCppCodegen || _isWasmCodegen) ? SimdVectorLength.None : SimdVectorLength.Vector128Bit;
var targetDetails = new TargetDetails(_targetArchitecture, _targetOS, TargetAbi.CoreRT, simdVectorLength);
var typeSystemContext = new CompilerTypeSystemContext(targetDetails, genericsMode);
@@ -316,12 +316,6 @@ namespace ILCompiler
new LibraryInitializers(typeSystemContext, _isCppCodegen);
compilationRoots.Add(new MainMethodRootProvider(entrypointModule, libraryInitializers.LibraryInitializerMethods));
}
- else if (_nativeLib)
- {
- EcmaModule module = (EcmaModule)typeSystemContext.SystemModule;
- LibraryInitializers libraryInitializers = new LibraryInitializers(typeSystemContext, _isCppCodegen);
- compilationRoots.Add(new NativeLibraryInitializerRootProvider(module, libraryInitializers.LibraryInitializerMethods));
- }
if (_multiFile)
{
@@ -347,10 +341,17 @@ namespace ILCompiler
throw new Exception("No entrypoint module");
compilationRoots.Add(new ExportedMethodsRootProvider((EcmaModule)typeSystemContext.SystemModule));
-
compilationGroup = new SingleFileCompilationModuleGroup(typeSystemContext);
}
+ if (_nativeLib)
+ {
+ // Set owning module of generated native library startup method to compiler generated module,
+ // to ensure the startup method is included in the object file during multimodule mode build
+ LibraryInitializers libraryInitializers = new LibraryInitializers(typeSystemContext, _isCppCodegen);
+ compilationRoots.Add(new NativeLibraryInitializerRootProvider(compilationGroup.GeneratedAssembly, libraryInitializers.LibraryInitializerMethods));
+ }
+
if (_rdXmlFilePaths.Count > 0)
Console.WriteLine("Warning: RD.XML processing will change before release (https://github.com/dotnet/corert/issues/5001)");
foreach (var rdXmlFilePath in _rdXmlFilePaths)
diff --git a/tests/src/Simple/SharedLibrary/NativeCallable.cs b/tests/src/Simple/SharedLibrary/NativeCallable.cs
new file mode 100644
index 000000000..4a080bfcf
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/NativeCallable.cs
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.InteropServices
+{
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class NativeCallableAttribute : Attribute
+ {
+ public string EntryPoint;
+ public CallingConvention CallingConvention;
+ public NativeCallableAttribute() { }
+ }
+} \ No newline at end of file
diff --git a/tests/src/Simple/SharedLibrary/SharedLibrary.cmd b/tests/src/Simple/SharedLibrary/SharedLibrary.cmd
new file mode 100644
index 000000000..2167b8ecf
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/SharedLibrary.cmd
@@ -0,0 +1,12 @@
+@echo off
+setlocal
+"%1\%2"
+set ErrorCode=%ERRORLEVEL%
+IF "%ErrorCode%"=="100" (
+ echo %~n0: pass
+ EXIT /b 0
+) ELSE (
+ echo %~n0: fail - %ErrorCode%
+ EXIT /b 1
+)
+endlocal
diff --git a/tests/src/Simple/SharedLibrary/SharedLibrary.cpp b/tests/src/Simple/SharedLibrary/SharedLibrary.cpp
new file mode 100644
index 000000000..f61053689
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/SharedLibrary.cpp
@@ -0,0 +1,66 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifdef _WIN32
+#include "windows.h"
+#else
+#include "dlfcn.h"
+#endif
+#include "stdio.h"
+#include "string.h"
+
+#ifndef _WIN32
+#define __stdcall
+#endif
+
+// typedef for shared lib exported methods
+typedef int(__stdcall *f_ReturnsPrimitiveInt)();
+typedef bool(__stdcall *f_ReturnsPrimitiveBool)();
+typedef char(__stdcall *f_ReturnsPrimitiveChar)();
+typedef void(__stdcall *f_EnsureManagedClassLoaders)();
+
+#ifdef _WIN32
+int main()
+#else
+int main(int argc, char* argv[])
+#endif
+{
+#ifdef _WIN32
+ HINSTANCE handle = LoadLibrary("SharedLibrary.dll");
+#elif __APPLE__
+ void *handle = dlopen(strcat(argv[0], ".dylib"), RTLD_LAZY);
+#else
+ void *handle = dlopen(strcat(argv[0], ".so"), RTLD_LAZY);
+#endif
+
+ if (!handle)
+ return 1;
+
+#ifdef _WIN32
+ f_ReturnsPrimitiveInt returnsPrimitiveInt = (f_ReturnsPrimitiveInt)GetProcAddress(handle, "ReturnsPrimitiveInt");
+ f_ReturnsPrimitiveBool returnsPrimitiveBool = (f_ReturnsPrimitiveBool)GetProcAddress(handle, "ReturnsPrimitiveBool");
+ f_ReturnsPrimitiveChar returnsPrimitiveChar = (f_ReturnsPrimitiveChar)GetProcAddress(handle, "ReturnsPrimitiveChar");
+ f_EnsureManagedClassLoaders ensureManagedClassLoaders = (f_EnsureManagedClassLoaders)GetProcAddress(handle, "EnsureManagedClassLoaders");
+#else
+ f_ReturnsPrimitiveInt returnsPrimitiveInt = (f_ReturnsPrimitiveInt)dlsym(handle, "ReturnsPrimitiveInt");
+ f_ReturnsPrimitiveBool returnsPrimitiveBool = (f_ReturnsPrimitiveBool)dlsym(handle, "ReturnsPrimitiveBool");
+ f_ReturnsPrimitiveChar returnsPrimitiveChar = (f_ReturnsPrimitiveChar)dlsym(handle, "ReturnsPrimitiveChar");
+ f_EnsureManagedClassLoaders ensureManagedClassLoaders = (f_EnsureManagedClassLoaders)dlsym(handle, "EnsureManagedClassLoaders");
+#endif
+
+ if (returnsPrimitiveInt() != 10)
+ return 1;
+
+ if (!returnsPrimitiveBool())
+ return 1;
+
+ if (returnsPrimitiveChar() != 'a')
+ return 1;
+
+ // As long as no unmanaged exception is thrown
+ // managed class loaders were initialized successfully
+ ensureManagedClassLoaders();
+
+ return 100;
+}
diff --git a/tests/src/Simple/SharedLibrary/SharedLibrary.cs b/tests/src/Simple/SharedLibrary/SharedLibrary.cs
new file mode 100644
index 000000000..78fd2c9a1
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/SharedLibrary.cs
@@ -0,0 +1,37 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace SharedLibrary
+{
+ public class ClassLibrary
+ {
+ [NativeCallable(EntryPoint = "ReturnsPrimitiveInt", CallingConvention = CallingConvention.StdCall)]
+ public static int ReturnsPrimitiveInt()
+ {
+ return 10;
+ }
+
+ [NativeCallable(EntryPoint = "ReturnsPrimitiveBool", CallingConvention = CallingConvention.StdCall)]
+ public static bool ReturnsPrimitiveBool()
+ {
+ return true;
+ }
+
+ [NativeCallable(EntryPoint = "ReturnsPrimitiveChar", CallingConvention = CallingConvention.StdCall)]
+ public static char ReturnsPrimitiveChar()
+ {
+ return 'a';
+ }
+
+ [NativeCallable(EntryPoint = "EnsureManagedClassLoaders", CallingConvention = CallingConvention.StdCall)]
+ public static void EnsureManagedClassLoaders()
+ {
+ Random random = new Random();
+ random.Next();
+ }
+ }
+}
diff --git a/tests/src/Simple/SharedLibrary/SharedLibrary.csproj b/tests/src/Simple/SharedLibrary/SharedLibrary.csproj
new file mode 100644
index 000000000..5bfa784b9
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/SharedLibrary.csproj
@@ -0,0 +1,35 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <NativeLib>Shared</NativeLib>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ </ItemGroup>
+
+ <Target Name="NativeRunnerCompile" AfterTargets="LinkNative">
+ <PropertyGroup>
+ <NativeRunnerBinary>$(NativeOutputPath)SharedLibrary</NativeRunnerBinary>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CppCompile Include="SharedLibrary.cpp" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <NativeRunnerCompilerArg Include="@(CppCompile)" />
+ <NativeRunnerCompilerArg Include="-o $(NativeRunnerBinary)" Condition="'$(OS)' != 'Windows_NT'" />
+ <NativeRunnerCompilerArg Include="/Fo$(NativeRunnerBinary)" Condition="'$(OS)' == 'Windows_NT'" />
+ <NativeRunnerCompilerArg Include="/Fe$(NativeRunnerBinary)" Condition="'$(OS)' == 'Windows_NT'" />
+ </ItemGroup>
+
+ <Exec Command="$(CppCompiler) @(NativeRunnerCompilerArg, ' ')" Condition="'$(OS)' != 'Windows_NT'" />
+ <WriteLinesToFile File="$(NativeIntermediateOutputPath)SharedLibrary.cl.rsp" Lines="@(NativeRunnerCompilerArg)" Overwrite="true" Condition="'$(OS)' == 'Windows_NT'"/>
+ <Exec Command="$(CppCompiler) @&quot;$(NativeIntermediateOutputPath)SharedLibrary.cl.rsp&quot;" Condition="'$(OS)' == 'Windows_NT'" />
+ </Target>
+
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
+
+</Project>
diff --git a/tests/src/Simple/SharedLibrary/SharedLibrary.sh b/tests/src/Simple/SharedLibrary/SharedLibrary.sh
new file mode 100755
index 000000000..6640f629f
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/SharedLibrary.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+$1/$2
+if [ $? == 100 ]; then
+ echo pass
+ exit 0
+else
+ echo fail
+ exit 1
+fi
diff --git a/tests/src/Simple/SharedLibrary/no_cpp b/tests/src/Simple/SharedLibrary/no_cpp
new file mode 100644
index 000000000..639bcaf8b
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/no_cpp
@@ -0,0 +1 @@
+Skip this test for cpp codegen mode
diff --git a/tests/src/Simple/SharedLibrary/no_linux b/tests/src/Simple/SharedLibrary/no_linux
new file mode 100644
index 000000000..872fb9d56
--- /dev/null
+++ b/tests/src/Simple/SharedLibrary/no_linux
@@ -0,0 +1 @@
+Skip this test for linux
diff --git a/tests/src/Simple/StaticLibrary/NativeCallable.cs b/tests/src/Simple/StaticLibrary/NativeCallable.cs
new file mode 100644
index 000000000..a96a6c793
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/NativeCallable.cs
@@ -0,0 +1,14 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.InteropServices
+{
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class NativeCallableAttribute : Attribute
+ {
+ public string EntryPoint;
+ public CallingConvention CallingConvention;
+ public NativeCallableAttribute() { }
+ }
+}
diff --git a/tests/src/Simple/StaticLibrary/StaticLibrary.cmd b/tests/src/Simple/StaticLibrary/StaticLibrary.cmd
new file mode 100644
index 000000000..2167b8ecf
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/StaticLibrary.cmd
@@ -0,0 +1,12 @@
+@echo off
+setlocal
+"%1\%2"
+set ErrorCode=%ERRORLEVEL%
+IF "%ErrorCode%"=="100" (
+ echo %~n0: pass
+ EXIT /b 0
+) ELSE (
+ echo %~n0: fail - %ErrorCode%
+ EXIT /b 1
+)
+endlocal
diff --git a/tests/src/Simple/StaticLibrary/StaticLibrary.cpp b/tests/src/Simple/StaticLibrary/StaticLibrary.cpp
new file mode 100644
index 000000000..25674cf25
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/StaticLibrary.cpp
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "stdio.h"
+
+extern "C" int Add(int a, int b);
+extern "C" int Subtract(int a, int b);
+extern "C" bool Not(bool b);
+
+int main()
+{
+ if (Add(2, 3) != 5)
+ return 1;
+
+ if (Subtract(3, 1) != 2)
+ return 1;
+
+ if (!Not(false))
+ return 1;
+
+ return 100;
+}
diff --git a/tests/src/Simple/StaticLibrary/StaticLibrary.cs b/tests/src/Simple/StaticLibrary/StaticLibrary.cs
new file mode 100644
index 000000000..3e7f6e78c
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/StaticLibrary.cs
@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace StaticLibrary
+{
+ public class ClassLibrary
+ {
+ [NativeCallable(EntryPoint = "Add", CallingConvention = CallingConvention.StdCall)]
+ public static int Add(int a, int b)
+ {
+ return a + b;
+ }
+
+ [NativeCallable(EntryPoint = "Subtract", CallingConvention = CallingConvention.StdCall)]
+ public static int Subtract(int a, int b)
+ {
+ return a - b;
+ }
+
+ [NativeCallable(EntryPoint = "Not", CallingConvention = CallingConvention.StdCall)]
+ public static bool Not(bool b)
+ {
+ return !b;
+ }
+ }
+}
diff --git a/tests/src/Simple/StaticLibrary/StaticLibrary.csproj b/tests/src/Simple/StaticLibrary/StaticLibrary.csproj
new file mode 100644
index 000000000..feaf7f37f
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/StaticLibrary.csproj
@@ -0,0 +1,52 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup>
+ <OutputType>Library</OutputType>
+ <NativeLib>Static</NativeLib>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ </ItemGroup>
+
+ <Target Name="NativeRunnerCompile" AfterTargets="LinkNative">
+ <PropertyGroup>
+ <NativeRunnerBinary>$(NativeOutputPath)StaticLibrary</NativeRunnerBinary>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CppCompile Include="StaticLibrary.cpp" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <NativeRunnerCompilerArg Include="@(CppCompile)" />
+ <NativeRunnerCompilerArg Include="-o $(NativeRunnerBinary)" Condition="'$(OS)' != 'Windows_NT'" />
+ <NativeRunnerCompilerArg Include="/Fo$(NativeRunnerBinary)" Condition="'$(OS)' == 'Windows_NT'" />
+ <NativeRunnerCompilerArg Include="/Fe$(NativeRunnerBinary)" Condition="'$(OS)' == 'Windows_NT'" />
+ <NativeRunnerCompilerArg Include="$(NativeBinary)" Condition="'$(OS)' == 'Windows_NT'" />
+ <NativeRunnerCompilerArg Include="@(NativeLibrary)" Condition="'$(OS)' == 'Windows_NT'" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <NativeRunnerLinkerArg Include="@(NativeLibrary)" />
+ <NativeRunnerLinkerArg Include="-g" />
+ <NativeRunnerLinkerArg Include="-Wl,-rpath,'$ORIGIN'" />
+ <NativeRunnerLinkerArg Include="-pthread" />
+ <NativeRunnerLinkerArg Include="-lstdc++" />
+ <NativeRunnerLinkerArg Include="-ldl" />
+ <NativeRunnerLinkerArg Include="-lm" />
+ <NativeRunnerLinkerArg Include="-lcurl" />
+ <NativeRunnerLinkerArg Include="-lz" />
+ <NativeRunnerLinkerArg Include="-luuid" Condition="'$(TargetOS)' != 'OSX'" />
+ <NativeRunnerLinkerArg Include="-lrt" Condition="'$(TargetOS)' != 'OSX'" />
+ <NativeRunnerLinkerArg Include="-licucore" Condition="'$(TargetOS)' == 'OSX'" />
+ </ItemGroup>
+
+ <Exec Command="$(CppCompiler) @(NativeRunnerCompilerArg, ' ') $(NativeBinary) @(NativeRunnerLinkerArg, ' ')" Condition="'$(OS)' != 'Windows_NT'" />
+ <WriteLinesToFile File="$(NativeIntermediateOutputPath)SharedLibrary.cl.rsp" Lines="@(NativeRunnerCompilerArg)" Overwrite="true" Condition="'$(OS)' == 'Windows_NT'"/>
+ <Exec Command="$(CppCompiler) @&quot;$(NativeIntermediateOutputPath)SharedLibrary.cl.rsp&quot;" Condition="'$(OS)' == 'Windows_NT'" />
+ </Target>
+
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
+
+</Project>
diff --git a/tests/src/Simple/StaticLibrary/StaticLibrary.sh b/tests/src/Simple/StaticLibrary/StaticLibrary.sh
new file mode 100755
index 000000000..6640f629f
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/StaticLibrary.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+$1/$2
+if [ $? == 100 ]; then
+ echo pass
+ exit 0
+else
+ echo fail
+ exit 1
+fi
diff --git a/tests/src/Simple/StaticLibrary/no_cpp b/tests/src/Simple/StaticLibrary/no_cpp
new file mode 100644
index 000000000..639bcaf8b
--- /dev/null
+++ b/tests/src/Simple/StaticLibrary/no_cpp
@@ -0,0 +1 @@
+Skip this test for cpp codegen mode