diff --git a/Compiler/Compiler.cs b/Compiler/Compiler.cs
index dd8abb723..91927b978 100644
--- a/Compiler/Compiler.cs
+++ b/Compiler/Compiler.cs
@@ -1937,6 +1937,12 @@ namespace PascalABCCompiler
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x64;
else if (plt.Equals("anycpu"))
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.AnyCPU;
+ else if (plt.Equals("dotnet5win"))
+ cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnet5win;
+ else if (plt.Equals("dotnet5linux"))
+ cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnet5linux;
+ else if (plt.Equals("dotnet5macos"))
+ cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnet5macos;
}
if (this.compilerOptions.Only32Bit)
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x86;
@@ -2955,6 +2961,11 @@ namespace PascalABCCompiler
directives = (Unit.SemanticTree as TreeRealization.common_unit_node).compiler_directives;
else
directives = ConvertDirectives(Unit.SyntaxTree);
+ foreach (TreeRealization.compiler_directive cd in directives)
+ {
+ if (cd.name.ToLower() == TreeConverter.compiler_string_consts.compiler_directive_platformtarget && !string.IsNullOrEmpty(cd.directive) && cd.directive.IndexOf("dotnet5") != -1)
+ CompilerOptions.UseDllForSystemUnits = false;
+ }
if (CompilerOptions.UseDllForSystemUnits)
{
directives.Add(new TreeRealization.compiler_directive("reference", "%GAC%\\PABCRtl.dll", null));
@@ -2976,6 +2987,7 @@ namespace PascalABCCompiler
directives.Add(new TreeRealization.compiler_directive("reference", "%GAC%\\HelixToolkit.dll", null));
}
}
+
}
foreach (TreeRealization.compiler_directive cd in directives)
{
diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs
index ef4d85c67..e2a87287f 100644
--- a/NETGenerator/NETGenerator.cs
+++ b/NETGenerator/NETGenerator.cs
@@ -14,6 +14,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Remoting;
using System.Security;
using System.Runtime.Versioning;
+using System.Text;
namespace PascalABCCompiler.NETGenerator
{
@@ -36,7 +37,7 @@ namespace PascalABCCompiler.NETGenerator
//compiler options class
public class CompilerOptions
{
- public enum PlatformTarget { x64, x86, AnyCPU };
+ public enum PlatformTarget { x64, x86, AnyCPU, dotnet5win, dotnet5linux, dotnet5macos };
public TargetType target = TargetType.Exe;
public DebugAttributes dbg_attrs = DebugAttributes.Release;
@@ -447,6 +448,72 @@ namespace PascalABCCompiler.NETGenerator
name.EndsWith(PascalABCCompiler.TreeConverter.compiler_string_consts.ImplementationSectionNamespaceName));
}
+ bool IsDotnet5()
+ {
+ return comp_opt.platformtarget == CompilerOptions.PlatformTarget.dotnet5win || comp_opt.platformtarget == CompilerOptions.PlatformTarget.dotnet5linux || comp_opt.platformtarget == CompilerOptions.PlatformTarget.dotnet5linux;
+ }
+
+ private void BuildDotnet5(string orig_dir, string dir, string publish_dir)
+ {
+ if (Directory.Exists(publish_dir))
+ Directory.Delete(publish_dir, true);
+ Directory.CreateDirectory(publish_dir);
+ StringBuilder sb = new StringBuilder();
+ string framework = "net5.0";
+ if (comp_opt.target == TargetType.WinExe)
+ {
+ framework = "net5.0-windows";
+ sb.AppendLine("");
+ sb.AppendLine("WinExe"+framework+ "true");
+ sb.AppendLine("" + Path.Combine(dir, an.Name) + ".dll" + "");
+ sb.AppendLine("");
+ }
+ else
+ {
+ sb.AppendLine("");
+ sb.AppendLine("Exe"+framework+ "");
+ sb.AppendLine("" + Path.Combine(dir, an.Name) + ".dll" + "");
+ sb.AppendLine("");
+ }
+
+ string csproj = Path.Combine(dir, Path.GetFileNameWithoutExtension(an.Name) + ".csproj");
+ File.WriteAllText(csproj, sb.ToString());
+ sb = new StringBuilder();
+ sb.AppendLine("using System;");
+ sb.AppendLine("namespace StartApp");
+ sb.AppendLine("{");
+ sb.AppendLine("class StartProgram");
+ sb.AppendLine("{");
+ sb.AppendLine("static void Main(string[] args)");
+ sb.AppendLine("{");
+ sb.AppendLine(entry_meth.DeclaringType.FullName+"."+entry_meth.Name+"();");
+ sb.AppendLine("}");
+ sb.AppendLine("}");
+ sb.AppendLine("}");
+ File.WriteAllText(Path.Combine(dir, "Program.cs"), sb.ToString());
+ System.Diagnostics.Process p = new System.Diagnostics.Process();
+ p.StartInfo = new System.Diagnostics.ProcessStartInfo();
+ p.StartInfo.FileName = "dotnet";
+ string runtime = "win-x64";
+ if (comp_opt.platformtarget == CompilerOptions.PlatformTarget.dotnet5linux)
+ runtime = "linux-x64";
+ else if (comp_opt.platformtarget == CompilerOptions.PlatformTarget.dotnet5macos)
+ runtime = "osx.10.11-x64";
+ string conf = "Debug";
+ if (comp_opt.dbg_attrs == DebugAttributes.Release)
+ conf = "Release";
+ p.StartInfo.CreateNoWindow = true;
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.Arguments = "publish -f "+framework+" --runtime "+runtime+" -c "+conf+ " --self-contained false " + csproj;
+ p.Start();
+ p.WaitForExit();
+ var files = Directory.GetFiles(Path.Combine(dir, "bin" + Path.DirectorySeparatorChar + conf + Path.DirectorySeparatorChar + framework + Path.DirectorySeparatorChar + runtime + Path.DirectorySeparatorChar + "publish"));
+ foreach (var file in files)
+ File.Copy(file, Path.Combine(publish_dir, Path.GetFileName(file)));
+ foreach (var file in files)
+ File.Copy(file, Path.Combine(orig_dir, Path.GetFileName(file)), true);
+ }
+
//Метод, переводящий семантическое дерево в сборку .NET
public void ConvertFromTree(SemanticTree.IProgramNode p, string TargetFileName, string SourceFileName, CompilerOptions options, string[] ResourceFiles)
{
@@ -459,6 +526,8 @@ namespace PascalABCCompiler.NETGenerator
an = new AssemblyName(); //создаем имя сборки
an.Version = new Version("1.0.0.0");
string dir = Directory.GetCurrentDirectory();
+ string orig_dir = null;
+ string dotnet_publish_dir = null;
string source_name = fname;//p.Location.document.file_name;
int pos = source_name.LastIndexOf(Path.DirectorySeparatorChar);
if (pos != -1) //если имя файла указано с путем, то выделяем
@@ -485,6 +554,18 @@ namespace PascalABCCompiler.NETGenerator
an.SetPublicKey(publicKey);
publicKeyStream.Close();
}
+ if (IsDotnet5())
+ {
+ orig_dir = dir;
+ dir = Path.Combine(dir, an.Name + "_dotnet5");
+ if (!Directory.Exists(dir))
+ Directory.CreateDirectory(dir);
+ dotnet_publish_dir = Path.Combine(dir, "publish");
+ dir = Path.Combine(dir, "tmp");
+ if (!Directory.Exists(dir))
+ Directory.CreateDirectory(dir);
+ }
+
if (RunOnly)
ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, dir);//определяем сборку
else
@@ -528,7 +609,7 @@ namespace PascalABCCompiler.NETGenerator
mb = ab.DefineDynamicModule(name, save_debug_info);
else
{
- if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
+ if (!IsDotnet5() && (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe))
mb = ab.DefineDynamicModule(name + ".exe", an.Name + ".exe", save_debug_info); //определяем модуль (save_debug_info - флаг включать отладочную информацию)
else
mb = ab.DefineDynamicModule(name + ".dll", an.Name + ".dll", save_debug_info);
@@ -981,12 +1062,16 @@ namespace PascalABCCompiler.NETGenerator
{
if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
{
- if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
+ if (IsDotnet5())
+ ab.Save(an.Name + ".dll");
+ else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
ab.Save(an.Name + ".exe", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
//else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64)
// ab.Save(an.Name + ".exe", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64);
else ab.Save(an.Name + ".exe");
//сохраняем сборку
+ if (IsDotnet5())
+ BuildDotnet5(orig_dir, dir, dotnet_publish_dir);
}
else
{
diff --git a/bin/Lib/__RedirectIOMode.pas b/bin/Lib/__RedirectIOMode.pas
index e3abb0ee7..c502eb024 100644
--- a/bin/Lib/__RedirectIOMode.pas
+++ b/bin/Lib/__RedirectIOMode.pas
@@ -116,6 +116,10 @@ end;
var __initialized := false;
+procedure AddThreadExceptionHandler;
+begin
+ System.Windows.Forms.Application.ThreadException += Application_ThreadException;
+end;
procedure __InitModule;
begin
try
@@ -127,7 +131,10 @@ begin
if IOStandardSystem(CurrentIOSystem).GetType = typeof(IOStandardSystem) then // SSM 30.04.06 - не менять! Влияет на PT4!
CurrentIOSystem := new __ReadSignalOISystem;
AppDomain.CurrentDomain.UnhandledException += DbgExceptionHandler;
- System.Windows.Forms.Application.ThreadException += Application_ThreadException;
+ try
+ AddThreadExceptionHandler;
+ except
+ end;
if not IsConsoleApplication then
begin
WriteToProcessErrorStream(string.Format(CodePageCommandTemplate, 65001)); // IB 5.08.08