directive platformtarget native (.NET 7.0 required)

This commit is contained in:
Ivan Bondarev 2022-11-17 20:53:12 +01:00
parent 75237b4c36
commit 482579fedb
2 changed files with 104 additions and 3 deletions

View file

@ -1955,6 +1955,15 @@ namespace PascalABCCompiler
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnet5linux;
else if (plt.Equals("dotnet5macos"))
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnet5macos;
else if (plt.Equals("native"))
{
if (Environment.OSVersion.Platform == PlatformID.Unix)
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnetlinuxnative;
else if (Environment.OSVersion.Platform == PlatformID.MacOSX)
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnetmacosnative;
else
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.dotnetwinnative;
}
}
if (this.compilerOptions.Only32Bit)
cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x86;

View file

@ -37,7 +37,7 @@ namespace PascalABCCompiler.NETGenerator
//compiler options class
public class CompilerOptions
{
public enum PlatformTarget { x64, x86, AnyCPU, dotnet5win, dotnet5linux, dotnet5macos };
public enum PlatformTarget { x64, x86, AnyCPU, dotnet5win, dotnet5linux, dotnet5macos, dotnetwinnative, dotnetlinuxnative, dotnetmacosnative };
public TargetType target = TargetType.Exe;
public DebugAttributes dbg_attrs = DebugAttributes.Release;
@ -467,6 +467,17 @@ namespace PascalABCCompiler.NETGenerator
CompilerOptions.PlatformTarget.dotnet5macos; // PVS 01/2022
}
bool IsDotnetNative()
{
return
comp_opt.platformtarget ==
CompilerOptions.PlatformTarget.dotnetwinnative ||
comp_opt.platformtarget ==
CompilerOptions.PlatformTarget.dotnetlinuxnative ||
comp_opt.platformtarget ==
CompilerOptions.PlatformTarget.dotnetmacosnative; // PVS 01/2022
}
private void BuildDotnet5(string orig_dir, string dir, string publish_dir)
{
if (Directory.Exists(publish_dir))
@ -528,6 +539,74 @@ namespace PascalABCCompiler.NETGenerator
File.Copy(file, Path.Combine(orig_dir, Path.GetFileName(file)), true);
}
private void BuildDotnetNative(string orig_dir, string dir, string publish_dir, string SourceFileName)
{
if (Directory.Exists(publish_dir))
Directory.Delete(publish_dir, true);
Directory.CreateDirectory(publish_dir);
StringBuilder sb = new StringBuilder();
string framework = "net7.0";
if (comp_opt.target == TargetType.WinExe)
{
framework = "net7.0-windows";
sb.AppendLine("<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">");
sb.AppendLine("<PropertyGroup><PublishAot>true</PublishAot><PublishTrimmed>false</PublishTrimmed><OutputType>WinExe</OutputType><TargetFramework>" + framework + "</TargetFramework><UseWindowsForms>true</UseWindowsForms></PropertyGroup>");
sb.AppendLine("<ItemGroup><Reference Include = \"" + an.Name + "\"><HintPath>" + Path.Combine(dir, an.Name) + ".dll" + "</HintPath></Reference></ItemGroup>");
sb.AppendLine("</Project>");
}
else
{
sb.AppendLine("<Project Sdk=\"Microsoft.NET.Sdk\">");
sb.AppendLine("<PropertyGroup><PublishAot>true</PublishAot><PublishTrimmed>true</PublishTrimmed><OutputType>Exe</OutputType><TargetFramework>" + framework + "</TargetFramework></PropertyGroup>");
sb.AppendLine("<ItemGroup><Reference Include = \"" + an.Name + "\"><HintPath>" + Path.Combine(dir, an.Name) + ".dll" + "</HintPath></Reference></ItemGroup>");
sb.AppendLine("</Project>");
}
string csproj = Path.Combine(dir, Path.GetFileNameWithoutExtension(an.Name)+"___native" + ".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.dotnetlinuxnative)
runtime = "linux-x64";
else if (comp_opt.platformtarget == CompilerOptions.PlatformTarget.dotnetmacosnative)
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 true " + csproj;
p.Start();
p.WaitForExit();
try
{
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).Replace("___native", "")), true);
}
catch (Exception ex)
{
throw new TreeConverter.SaveAssemblyError(ex.Message, new TreeRealization.location(0, 0, 0, 0, new TreeRealization.document(SourceFileName)));
}
}
//Метод, переводящий семантическое дерево в сборку .NET
public void ConvertFromTree(SemanticTree.IProgramNode p, string TargetFileName, string SourceFileName, CompilerOptions options, string[] ResourceFiles)
{
@ -579,6 +658,17 @@ namespace PascalABCCompiler.NETGenerator
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
else if (IsDotnetNative())
{
orig_dir = dir;
dir = Path.Combine(dir, an.Name + "_dotnetnative");
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);//определяем сборку
@ -626,7 +716,7 @@ namespace PascalABCCompiler.NETGenerator
mb = ab.DefineDynamicModule(name, save_debug_info);
else
{
if (!IsDotnet5() && (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe))
if (!IsDotnet5() && !IsDotnetNative() && (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);
@ -1084,7 +1174,7 @@ namespace PascalABCCompiler.NETGenerator
{
if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
{
if (IsDotnet5())
if (IsDotnet5() || IsDotnetNative())
ab.Save(an.Name + ".dll");
else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
ab.Save(an.Name + ".exe", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
@ -1094,6 +1184,8 @@ namespace PascalABCCompiler.NETGenerator
//сохраняем сборку
if (IsDotnet5())
BuildDotnet5(orig_dir, dir, dotnet_publish_dir);
else if (IsDotnetNative())
BuildDotnetNative(orig_dir, dir, dotnet_publish_dir, SourceFileName);
}
else
{