Showing posts with label mono. Show all posts
Showing posts with label mono. Show all posts

Saturday, December 09, 2017

Announcing AltCover

Now I have time to myself, and the season doesn't lend itself to outdoor activities, I can start dusting off my various coding projects and devoting the time and energy to those that I used to expend for pay.

First off the block is AltCover, an alternative code coverage tool for .net and Mono.

This is a project I started back in the dark days in the spring of 2010, when changes in the profiling API of the new CLR 4.0 release meant that the old freeware NCover 1.5.x series no longer functioned. For some considerable while, the only FOSS alternative that worked with the new CLR (by instrumenting the code under test before execution, rather than on-the-fly) seemed to be an initial proof-of-concept on CodeProject.

At that point, I'd been looking for something non-trivial to work on that would provide the opportunity to use F# to build up my fluency in the language; and so the obvious thing to to was to re-implement from scratch and extend to cover such gaps as I found in its functionality when trying to use it as a near drop-in replacement for the now non-functional NCover version.

After some considerable interval and a failed dalliance with PartCover, including my first contribution to a real FOSS tool, but never a resolution to one real sticking problem, where it looked like JITting across assembly boundaries was causing executed lines to not appear in the coverage, I shelved my work in favour of the off-the-shelf OpenCover, where I could intermittently contribute enhancements to cover personal pain points.

Why have I dusted it off again now?

Well, for much the same reasons as before; a non-trivial project that does answer some pain-points (Mono and probably the new dotnet core amongst them) that OpenCover's necessarily intimate relationship with the runtime makes difficult. And it provides a reason to play with new toys that have grown up over the last few years, like Fake for builds, and the generous provision of CI tools to FOSS projects so people can take builds rather than having to roll their own.

Monday, July 02, 2012

Strong-naming assemblies using Mono.Cecil

As the Microsoft FxCop libraries are inherently 32-bit (including native code as they do), developing code using them on a 64-bit platform throws up places where the modes get mixed, and an assembly that is generally AnyCPU ends up needing to load an x86 library and barfs. No real problem here, use corflags assembly /32BIT+ /Force, where you need the /Force for a strong-named assembly. And then if later you need that one strong-named... There is the standard technique of ILDasm/ILAsm to rebuild the assembly with strong-naming (as documented e.g. here), but you still end up with the corflags yellow warning in the MSBuild output about breaking the original strong-naming if you need that too.

But when the code I was working on also uses Mono.Cecil to do stuff, it was easier to silently do the whole lot in one script:

Yes, you can do that in PowerShell too, just with more fussing about the path to the Cecil assemblies because of the schizophrenic current directory model it has. And because the rest of the code in this particular project is F#, keeping the build scripts in the same language is just natural.


Saturday, February 19, 2011

Mono 2.10, XBuild, F# -- first attempts

Following the announcement that F# and the Iron languages are being bundled with Mono 2.10 for Mac and Linux, I thought it worth taking the system for a spin on Windows as well. This is a record of my experiments, and are nowhere near a complete HOW-TO as yet (they more closely resemble a HOW NOT TO at the moment).

The easy bit is as per Zor's blog, here --

  • copy C:\program files\MSBuild\FSharp to C:\Program Files\Mono-2.10\lib\mono\xbuild
  • Get the mono strong-name key https://github.com/mono/mono/blob/master/mcs/class/mono.snk
  • Now this is voodoo -- without going & 'C:\Program Files\Mono-2.10\bin\sn.bat' -R .\FSharp.Core.dll .\mono.snk on a copy of the F# runtime, the GACing step fails : yet the operation doesn't actually change the embedded key (going as far as ILDasm/ILAsm seems a bit extreme!)
  • As administrator, & 'C:\Program Files\Mono-2.10\bin\mono.exe' 'C:\Program Files\Mono-2.10\lib\mono\2.0\gacutil.exe' -i '.\FSharp.Core.dll', and then copy the original Fsharp.core.sigdata and .optdata alongside
  • in C:\Program Files\Mono-2.10\lib\mono\3.5\Microsoft.Common.targets undo the commenting out of _ComputeNonExistentFileProperty
  • In the copy of the Microsoft.Sharp.targets file, comment out the <ItemGroup Remove="..."> clauses after Fsc task in the CoreCompile target, and the two in CreateManifestResourceNames (might there be a CreateItem equivalent? Haven't tried yet).

At this point, pure F# projects for VS2008 will build happily, so long as you don't have any fancy modern task attributes in BeforeBuild or AfterBuild (e.g. Error executing task Copy: Task does not have property "OverwriteReadOnlyFiles" defined if you try to use that).

Where I have yet to manage to persuade the build process to work is for projects with embedded resources (such as Glade XML definitions for a UI). These yield up

        Target CopyNonResxEmbeddedResources:
C:\PROGRA~1\Mono-2.10\lib\mono\3.5\Microsoft.Common.targets: error : 
You must specify DestinationFolder or DestinationFiles attribute.
        Task "Copy" execution -- FAILED

which may possibly relate to some of the <ItemGroup Remove="..."> operations not being carried out. Certainly, some more MSBuild hackery will be required to track down what is going on and make sure that both sides of the copy operation match up -- so that either the source is empty, and no copy is attempted, or so that the destination doesn't end up null.

Support for VS2010 projects isn't there yet -- after sn -R (with equally little effect on the strong-name given by sn -Tp) and GACing the 4.0 version of FSharp.Core.dll, trying to build a VS2010 project yields up the cryptic message, sometimes as an error, sometimes as a warning, that "Operation is not valid due to the current state of the object" -- even with /verbosity:diagnostic turned on no more detail is divulged. And having the 4.0 version GAC'd interferes with the 2.0 version in the GAC -- the later version is selected by preference and then fails for being incompatible with the 2.0-level mscorlib when building a vanilla VS2008 project with just a simple reference (without explicit version information like <Reference Include="FSharp.Core" />) to the F# runtime.

Thursday, February 10, 2011

Cecil.Decompiler and F#

In this new post-Reflector age, I thought I'd have a look-see how the main competition worked on F#. So I whipped up a simple driver for Cecil.Decompiler:

and tried it on an assembly of some fairly simple F# -- a few extension methods for Option

and we get things like

This is better than Reflector was when I first tried it about 18 months ago -- F#'s cluster of branch instructions

caused the old Reflector to just crash.

F#'s habit of lacing in temporaries did flummox the decompilation a bit:

compared with the current Reflector's take of

MonoDevelop 2.4.2.'s Assembly Browser gets it a bit better than the raw decompiler, though it still has the same 'C'-style if in there:

Amusingly, I was able to get the decompilation to throw by feeding the little driver program into itself -- the DumpAssembly method would not turn back into C#! MonoDevelop silently refused to load the contents of the whole assembly.

Sunday, February 06, 2011

Getting the baked-in .pdb location from an assembly with Mono.Cecil 0.9.4

Because it isn't always as simple as

as is done in Mono.Cecil.Pdb.PdbHelper, if assemblies and symbols have been moved to separate locations during a build.

The tools are there -- we just need to get the debug data from the PE image if it's present, skip the first 24 bytes, and interpret the rest as a string. Alas, all the are annoyingly just slightly encapsulated from us. But never mind! Reflection gets us there without having to negotiate a patch or make a fork:

Friday, August 31, 2007

Mono 1.2.5 is out.

So, the necessary changes to support the DLR at all are in place.

Alas, it still has some limitations -- (bug 82650)

fails in the import statement with

Traceback (most recent call last):
  File __main__, line unknown, in Initialize
  File WinUI, line unknown, in Initialize
TypeError: Argument cannot be null.
Parameter name: type

which is not quite "at the first hurdle", but does make it useful to keep the WinForms import in a single file, so if I need to explicitly enumerate, I only have to do it once.

A pity that Python isn't quite as malleable as Ruby so far as stringname-to-symbol matching goes. The next best thing, this

doesn't fare any better. *sigh*

Monday, July 30, 2007

IronPython/IPCE : Simpler method to get logical drives

The previous enumeration approach allowed you to, as well as getting the drive letters through the "Name" property, also access associated "DriveType" and "MediaType" properties -- effectively between them giving the index of the related Shell32.dll icon. That information, however, seems to be less than useful in the .Net framework without manually unpicking the PE format for the icons. So, you might as well go the direct route like--

giving

System.String[]('C:\\', 'D:\\', 'E:\\', 'F:\\', 'G:\\', 'H:\\', 'I:\\', 'J:\\',
'K:\\', 'L:\\', 'N:\\')

which adds the trailing back-slash; and also has the advantage of working in Mono 1.2.4 with IPCE-r6.

Fortunately Fuzzyman's generate.py to do on-the-fly compilation of C# works there too, so I can still get the icons on that platform. Once I've worked around another quirk, that is -- Mono/IPCE is much more rigorous about the .Net types -- I had to explicitly create an Image, rather than use an Icon with implicit toBitmap() conversion in a call to Graphics.DrawImage

Friday, June 29, 2007

Links for 29-Jun

Haskell-based web store -- e-commerce and functional programming do mix

CarbonPython -- build .Net consumable DLLs from RPython

Moonlight Desklets -- cool stuff

Distributed programming IDE for .Net -- gives the ability to program multiple remote computers (i.e. servers) from within one IDE instance