pretzel
pretzel copied to clipboard
Pretzel on Mono
While a Windows dev myself, I'm a cheap bastard and having a Linux host is the way to go for me. I currently use DigitalOcean, with Jekyll building on git commit/push.
I thought I'd start a bit of a discussion and discovery to whats needed to get Pretzel working on mono.
So far, to get it building
-
Mono doesn't have nuget support? Or nuget is built to a not nuget profile, I'm not sure, removing the nuget task from the csproj makes it build as all the references were there as I'd previously built on .NET. Apparently nuget does have mono support, so perhaps the nuget.exe in the repo is out of date?
-
It doesn't have to be removed, but the ILMerging does not work. This can be left to 'error' out or removed from the csproj. IL-Repack ~~or Fody.Costura~~ might be options.
-
~~Because the ILMerging doesn't work, the MEF stuff doesn't work. Specifically,
var first = new AssemblyCatalog(Assembly.GetExecutingAssembly());
would need to be changed to~~AggregateCatalog first = new AggregateCatalog(); first.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly())); first.Catalogs.Add(new AssemblyCatalog(Assembly.GetAssembly(typeof (SanityCheck))));
~~Ideally some sort of ILMerging that works with mono would be best~~ Fixed
Todo
- [x] Confirm working on *Nix
- [ ] ILMerging/equiv for single exe
- [x] Nuget all the things.
- [x] fixing paths -
baking
(and thus serving up viataste
) fail pretty epically
Its actually NuGet.Targets
, in this case, that was the issue. LogStandardErrorAsError
was throwing an error, removed that from the Exec statements in NuGet.Targets, and it works again.
Trying to find the root cause, but mono doesn't seem to be picking up @(MainAssembly)
, which makes ILRepack fail. Edit: MainAssembly
is a MSBuild property. Maybe xbuild doesn't have it.
This means instead of
/out:bin\Debug\Pretzel.exe "obj\x86\Debug\Pretzel.exe" <list of assemblies to merge>
It gets
/out: "obj\x86\Debug\Pretzel.exe" <list of assemblies to merge>
Changing it from @(MainAssembly)
to $(OutputPath)$(AssemblyName).$(OutputType)
with ILRepack is not overly elegant, but works with both mono and .net
There is/will be issues with various file system access where slashes are involve. ie fileSystem.File.WriteAllText(Path.Combine(directory, @"_layouts\layout.cshtml"), Properties.RazorWiki.Layout);
uses the 'wrong way' slash for *nix.
It should be something like (Path.Combine(directory, "_layouts", "layout.cshtml")
. This is going to be more of an issue with creating new site/templates/etc than general operation, I think.
Build issues on linux:
- case sensitivity in various paths relating to nuget. ie, needs to be NuGet.exe
- Permission errors on restoring, +777 (I know this is bad?) to the whole source folder let me restore files
- Resources (ResX) work funny and are currently failing
As of fb35bacee31d82cdb3361193639e3d47323b81d4 it compiles and embeds on Ubuntu, but it does not work as it cannot find NDesk (Could not load file or assembly 'NDesk.Options ...'
Nice work and writeup @vikingcode!
Alright, there is an issue with embedding via IL-Repack, which I'm trying to figure out. It has nothing to do with NDesk - if I drop NDesks file in, it'll then move onto another DLL, and so on and so forth until they're all present.
Based on the filesize alone, Pretzel.exe does contain everything, but it's not finding it properly.
Without VS for Linux, it's much harder to debug this, but paths are wonky which in turn is causing most of the issues once its actually running (if I disable the embedding/use the MEF work around).
Pretzel looks fairly different from when I last contributed to it in any sort of significant way so it's taking me awhile to figure out where this could be coming from. I suspect most, if not all, file operations will need to be rejiggered because of paths. However, I should point out that its _rendering HTML fine out of the box_.
I suspect most, if not all, file operations will need to be rejiggered because of paths.
That wouldn't surprise me either :cry:
Excellent work! :smiley:
So this is where my branch is up to:
It works on mono/ubuntu, including taste (web server) given the following constraints
- MonoDevelop hates me and only half works
- CHMOD +777 for nuget folder at a minimum
- May need sudo to get around file permissions when generating the site
- Can't get it do properly ILMerge/ILRepack, which requires the modified code in program.cs in the first post
The last point is probably the one main issue with getting it merged in/before I send a pull request. Alternatively we could possibly do some shenanigans where it tests whether its a single exe (Windows) or multiple (Linux) yet still works. While a single exe is preferable, working at all on Linux is kinda better than nothing.
The changes to nuget (ie, dropping Targets) made this much easier. The problem I have now is basically mono itself, be it on Windows or Linux.
I can embed all the assemblies into Pretzel.exe like we are now using xbuild or msbuild, and on .NET it'll run fine (no matter what compiles it), but on the mono runtime it can't "unpack" the assemblies for lack of a better word. It simply can't find the other assemblies.
I get errors like
Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'NDesk.Options, Version=0.2.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
File name: 'NDesk.Options, Version=0.2.1.0, Culture=neutral, PublicKeyToken=null
[ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly 'NDesk.Options, Version=0.2.1.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
File name: 'NDesk.Options, Version=0.2.1.0, Culture=neutral, PublicKeyToken=null
MonoDevelop crashes when I attach a debugger on Ubuntu, and Xamarin Studio can't even clean the directory, let alone compile (!), so I'm not able to get any further with debugging it. Building via CLI is the only way to go.
Any suggestions?
Taking a quick look with dotPeek to the assemly compiled from your branch and the official branch it can be confirmed, that mono may indeed be right: the assemby is not merged properly, or at least not the same way as in the official one.
Also note: commenting a reference to LockFile in the Pretzel.Tests csproj file was needed to be able to build your branch. Please confirm by trying to build a clean checkout.
Also note: imho you misused Path.AltDirectorySeparatorChar in your changes, if mono honours the msdn docs. I have commented it on the changeset in your branch. Please consider reviewing those parts.
edit: It will have to do something with Costura, but that is all i cound find out now...
assemby is not merged properly, or at least not the same way as in the official one.
Thats pretty much what I've been saying for the last few posts. The same code compiles on xbuild and msbuild, but on xbuild it doesn't embed or extract the other assemblies properly. Doesn't matter if its Windows or Linux, xbuild (mono) is the one causing problems, so I largely gave up on it as I don't know enough about IL merging on mono to figure it out.
Also note: commenting a reference to LockFile in the Pretzel.Tests csproj file was needed to be able to build your branch. Please confirm by trying to build a clean checkout.
Given LockFiles an exe, I have pretty much no confidence of getting that to work on linux. Tests are irrelevant until the above point is addressed - one issue at a time.
LockFiles doesn't work on Linux but have been ditched so it's not a problem.