mikefourie-zz / MSBuildExtensionPack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Update Framework.NuGet.Packager to Enhance PopulateFolder() Method to Support Architecture & Platform

indomitableMan opened this issue · comments

The PopulateFolder() method in packager.cs currently only supports the use of the <Framework> attribute, however NuGet packages can also support multiple processor architectures (e.g. 'x86' and 'x64') and platforms (e.g.'win81').

So if a user were to specify:

<LibraryFiles Include="..\dir\myLibrary.dll">
<Architecture>x86</Architecture>
<Framework>net40</Framework>
<Platform>win</Platform>
</LibraryFiles>

The PopulateFolder() method would test for the presence of the <Architecture> and <Platform> tags before testing for the presence of the <Framework> tag, and if found, would populate the folders like this: .\runtimes\{platform}-{architecture}\lib\{framework}

For example:
.\runtimes
____\win-x86
________\lib
____________\net40
________________\myLibrary.dll
____________\net45
________________\myLibrary.dll

____ \win-x64
________\lib
____________\net40
________________\myLibrary.dll
____________\net45
________________\myLibrary.dll

More information on this syntax is here: Supporting multiple .NET framework versions

A modified foreach loop similar to this would work:

        foreach (var item in items)
        {
            var architecture = item.GetMetadata("architecture");
            var framework = item.GetMetadata("framework");
            var platform = item.GetMetadata("platform");
            if (!string.IsNullOrWhiteSpace(platform))
            {
                if (!string.IsNullOrWhiteSpace(architecture))
                {
                    runtime = Path.Combine(libDirectory.FullName, "runtime");
                    if (!Directory.Exists(runtime))
                    {
                        Directory.CreateDirectory(runtime);
                    }
                    platformWithArch = string.Concat(platform, "-", architecture);
                    fullPlatformAndArch = path.Combine(runtime, fullPlatformAndArch);
                    if (!Directory.Exists(fullPlatformAndArch))
                    {
                        Directory.CreateDirectory(fullPlatformAndArch);
                    }
                    if (!string.IsNullOrWhiteSpace(framework))
                    {
                        framework = Path.Combine(fullPlatformAndArch, framework);
                        if (!Directory.Exists(framework))
                        {
                            Directory.CreateDirectory(framework);
                        }

                        File.Copy(item.ItemSpec, Path.Combine(framework, Path.GetFileName(item.ItemSpec)));
                    }
                    else
                    {
                        File.Copy(item.ItemSpec, Path.Combine(fullPlatformAndArch, Path.GetFileName(item.ItemSpec)));
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(framework))
            {
                framework = Path.Combine(libDirectory.FullName, framework);
                if (!Directory.Exists(framework))
                {
                    Directory.CreateDirectory(framework);
                }

                File.Copy(item.ItemSpec, Path.Combine(framework, Path.GetFileName(item.ItemSpec)));
            }
            else
            {
                File.Copy(item.ItemSpec, Path.Combine(libDirectory.FullName, Path.GetFileName(item.ItemSpec)));
            }
        }

Hi, please submit a pull request.

Is it really a good idea to package development dependency for every possible target platform?
I've repackaged NuGet package as neutral (removed net35 folders and moved content of net40 folders one level up). Such package can now be used on any project, native and .NET. At least in Visual Studio 2015.

Why does NuGet package contain binaries for .NET 3.5? Is it to support some older version of Visual Studio? In such case it may be better to provide separate NuGet packages.