Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I create or upload a 32-bit and 64-bit NuGet package?

I have an x86 and x64 version of a binary that I want to upload to NuGet. What's the recommendation or required method for creating/uploading that package? I can't find much to base my decision on. I see two methods...

  1. Upload them both in the same package
    • Which one should I install by default?
    • Is there a way to test the processor architecture of the project to make the decision?
  2. Upload two separate packages

Bonus question: What if I'm using something like Chocolatey, which wraps up NuGet with package manager semantics? I might need/want the x86 and x64 packages installed on my system.

like image 787
Anthony Mastrean Avatar asked Oct 14 '11 15:10

Anthony Mastrean


People also ask

Where do I put Nuspec files?

When the question is: Where do i put the nuspec within the package? the answer is: In the root folder of the package: Otherwise the answer is already answered by the other answer.


2 Answers

We've been discussing a similar issue on the Chocolatey Google Group. There aren't any semantics built into NuGet. The requirement wouldn't be, what processor architecture are you running on. It would have to be what processor architecture is your project targeting. And then that complicates things... you'd have to understand AnyCPU as well.

I think for now, I'm going to upload two packages. I can always published a combined one when I fix up an install.ps1 that can handle querying the project target.

mypackage.x86 mypackage.x64 
like image 97
Anthony Mastrean Avatar answered Sep 28 '22 07:09

Anthony Mastrean


You can add x64 and x86 support to a project by using conditional references. It would appear that for now Nuget does not like having two references with the same name. So we need to add in the second reference manually and then make the references conditional.

Save x64 assemblies in a folder called x64 & x86 assemblies in a folder called x86 They must both have the same assembly name. Then update the allowedReferences array with the names of all assemblies to add.

Use the following scripts.

Install.ps1

$allowedReferences = @("Noesis.Javascript")  # Full assembly name is required Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'  $projectCollection = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection  $allProjects = $projectCollection.GetLoadedProjects($project.Object.Project.FullName).GetEnumerator();  if($allProjects.MoveNext()) {     $currentProject = $allProjects.Current      foreach($Reference in $currentProject.GetItems('Reference') | ? {$allowedReferences -contains $_.Xml.Include })     {         $hintPath = $Reference.GetMetadataValue("HintPath")          write-host "Matched againt $hintPath"          #If it is x64 specific add condition (Include 'Any Cpu' as x64)         if ($hintPath -match '.*\\(amd64|x64)\\.*\.dll$')         {             $Reference.Xml.Condition = "'TargetPlatform' != 'x86'"              $condition = $Reference.Xml.Condition             write-host "hintPath = $hintPath"             write-host "condition = $condition"              #Visual Studio doesnt allow the same reference twice (so try add friends)             $matchingReferences = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -match ".*\\(x86)\\.*\.dll$")}              if (($matchingReferences | Measure-Object).Count -eq 0)             {                 $x86 = $hintPath -replace '(.*\\)(amd64|x64)(\\.*\.dll)$', '$1x86$3'                 $x86Path = Join-Path $installPath $x86                  if (Test-Path $x86Path) {                     #Add                      write-host "Adding reference to $x86"                      $metaData = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"                     $metaData.Add("HintPath", $x86)                     $currentProject.AddItem('Reference', $Reference.Xml.Include, $metaData)                      $newReference = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -eq $x86)} | Select-Object -First 1                      $newReference.Xml.Condition = "'TargetPlatform' == 'x86'"                            }             }         }          #If it is x86 specific add condition          if ($hintPath -match '.*\\x86\\.*\.dll$')         {             $Reference.Xml.Condition = "'TargetPlatform' == 'x86'"              $condition = $Reference.Xml.Condition             write-host "hintPath = $hintPath"             write-host "condition = $condition"              #Visual Studio doesnt allow the same reference twice (so try add friends)             $matchingReferences = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -match ".*\\(amd64|x64)\\.*\.dll$")}              if (($matchingReferences | Measure-Object).Count -eq 0)             {                 $x64 = $hintPath -replace '(.*\\)(x86)(\\.*\.dll)$', '$1x64$3'                 $x64Path = Join-Path $installPath $x64                  if (Test-Path $x64Path) {                     #Add                      write-host "Adding reference to $x64"                      $metaData = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"                     $metaData.Add("HintPath", $x64)                     $currentProject.AddItem('Reference', $Reference.Xml.Include, $metaData)                      $newReference = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -eq $x64)} | Select-Object -First 1                      $newReference.Xml.Condition = "'TargetPlatform' != 'x86'"                            } else {                     $amd64 = $hintPath -replace '(.*\\)(x86)(\\.*\.dll)$', '$1amd64$3'                     $amd64Path = Join-Path $installPath $amd64                      if (Test-Path $amd64Path) {                         #Add                          write-host "Adding reference to $amd64"                          $metaData = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"                         $metaData.Add("HintPath", $amd64)                         $currentProject.AddItem('Reference', $Reference.Xml.Include, $metaData)                          $newReference = $currentProject.GetItems('Reference') | ? {($_.Xml.Include -eq $Reference.Xml.Include) -and ($_.GetMetadataValue("HintPath") -eq $amd64)} | Select-Object -First 1                          $newReference.Xml.Condition = "'TargetPlatform' != 'x86'"                                }                                }                            }                    }     } } 

Uninstall.ps1

$allowedReferences = @("Noesis.Javascript")  # Full assembly name is required Add-Type -AssemblyName 'Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'  $projectCollection = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection  $allProjects = $projectCollection.GetLoadedProjects($project.Object.Project.FullName).GetEnumerator();  if($allProjects.MoveNext()) {     foreach($Reference in $allProjects.Current.GetItems('Reference') | ? {$allowedReferences -contains $_.UnevaluatedInclude })     {         $allProjects.Current.RemoveItem($Reference)     } } 
like image 40
Taliesin Avatar answered Sep 28 '22 08:09

Taliesin