Browse Source

Python compiler now generates executables that can be run from any directory.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@5385 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Matt Ward 16 years ago
parent
commit
f72bee85ec
  1. 49
      src/AddIns/BackendBindings/Python/Python.Build.Tasks/Project/Src/PythonCompiler.cs

49
src/AddIns/BackendBindings/Python/Python.Build.Tasks/Project/Src/PythonCompiler.cs

@ -133,7 +133,7 @@ namespace ICSharpCode.Python.Build.Tasks
/// Generates an executable from the already compiled dll. /// Generates an executable from the already compiled dll.
/// </summary> /// </summary>
void GenerateExecutable(string outputAssemblyDll) void GenerateExecutable(string outputAssemblyDll)
{ {
string outputAssemblyFileNameWithoutExtension = Path.GetFileNameWithoutExtension(outputAssembly); string outputAssemblyFileNameWithoutExtension = Path.GetFileNameWithoutExtension(outputAssembly);
AssemblyName assemblyName = new AssemblyName(outputAssemblyFileNameWithoutExtension); AssemblyName assemblyName = new AssemblyName(outputAssemblyFileNameWithoutExtension);
AssemblyBuilder assemblyBuilder = PythonOps.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); AssemblyBuilder assemblyBuilder = PythonOps.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
@ -141,14 +141,45 @@ namespace ICSharpCode.Python.Build.Tasks
TypeBuilder typeBuilder = moduleBuilder.DefineType("PythonMain", TypeAttributes.Public); TypeBuilder typeBuilder = moduleBuilder.DefineType("PythonMain", TypeAttributes.Public);
MethodBuilder mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[0]); MethodBuilder mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[0]);
// Mark main method as STA. MarkMainMethodAsSTA(mainMethod);
mainMethod.SetCustomAttribute(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new byte[0]); GenerateMainMethodBody(mainMethod, outputAssemblyDll);
// Add resources.
AddResources(moduleBuilder);
// Create executable.
typeBuilder.CreateType();
assemblyBuilder.SetEntryPoint(mainMethod, targetKind);
assemblyBuilder.Save(assemblyName.Name + ".exe", executableKind, machine);
}
void MarkMainMethodAsSTA(MethodBuilder mainMethod)
{
mainMethod.SetCustomAttribute(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new byte[0]);
}
void GenerateMainMethodBody(MethodBuilder mainMethod, string outputAssemblyDll)
{
ILGenerator generator = mainMethod.GetILGenerator(); ILGenerator generator = mainMethod.GetILGenerator();
LocalBuilder exeAssemblyLocalVariable = generator.DeclareLocal(typeof(Assembly));
LocalBuilder directoryLocalVariable = generator.DeclareLocal(typeof(string));
LocalBuilder fileNameLocalVariable = generator.DeclareLocal(typeof(string));
generator.EmitCall(OpCodes.Call, typeof(Assembly).GetMethod("GetExecutingAssembly", new Type[0], new ParameterModifier[0]), null);
generator.Emit(OpCodes.Stloc_0);
generator.Emit(OpCodes.Ldloc_0);
generator.EmitCall(OpCodes.Callvirt, typeof(Assembly).GetMethod("get_Location"), null);
generator.EmitCall(OpCodes.Call, typeof(Path).GetMethod("GetDirectoryName", new Type[] {typeof(String)}, new ParameterModifier[0]), null);
generator.Emit(OpCodes.Stloc_1);
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldstr, Path.GetFileName(outputAssemblyDll)); generator.Emit(OpCodes.Ldstr, Path.GetFileName(outputAssemblyDll));
generator.EmitCall(OpCodes.Call, typeof(Path).GetMethod("GetFullPath", new Type[] {typeof(String)}, new ParameterModifier[0]), null); generator.EmitCall(OpCodes.Call, typeof(Path).GetMethod("Combine", new Type[] {typeof(String), typeof(String)}, new ParameterModifier[0]), null);
generator.EmitCall(OpCodes.Call, typeof(Assembly).GetMethod("LoadFile", new Type[] {typeof(String)}, new ParameterModifier[0]), null); generator.Emit(OpCodes.Stloc_2);
generator.Emit(OpCodes.Ldloc_2);
generator.EmitCall(OpCodes.Call, typeof(Assembly).GetMethod("LoadFile", new Type[] {typeof(String)}, new ParameterModifier[0]), null);
generator.Emit(OpCodes.Ldstr, Path.GetFileNameWithoutExtension(mainFile)); generator.Emit(OpCodes.Ldstr, Path.GetFileNameWithoutExtension(mainFile));
// Add referenced assemblies. // Add referenced assemblies.
@ -156,14 +187,6 @@ namespace ICSharpCode.Python.Build.Tasks
generator.EmitCall(OpCodes.Call, typeof(PythonOps).GetMethod("InitializeModule"), new Type[0]); generator.EmitCall(OpCodes.Call, typeof(PythonOps).GetMethod("InitializeModule"), new Type[0]);
generator.Emit(OpCodes.Ret); generator.Emit(OpCodes.Ret);
// Add resources.
AddResources(moduleBuilder);
// Create executable.
typeBuilder.CreateType();
assemblyBuilder.SetEntryPoint(mainMethod, targetKind);
assemblyBuilder.Save(assemblyName.Name + ".exe", executableKind, machine);
} }
/// <summary> /// <summary>

Loading…
Cancel
Save