Symbols packages with more than one assembly

May 15, 2011 at 7:38 PM

Is it possible to create a symbols package when your package contains more than one assembly?  What would the structure of the src directory look like, since normally everything from the single project goes at the top level?

May 15, 2011 at 8:58 PM
Edited May 15, 2011 at 9:02 PM

Assuming you have assemblies X and Y and your repository has a typical layout like this one:
C:\Projects\SomeDirectory\SomeProject.sln
C:\Projects\SomeDirectory\X\X.csproj
C:\Projects\SomeDirectory\X\Class1.cs
C:\Projects\SomeDirectory\Y\Y.csproj
C:\Projects\SomeDirectory\X\Class2.cs

A correct SymbolSource package would need to have this structure:
lib\X.dll
lib\X.pdb
lib\Y.dll
lib\Y.pdb
src\X\X.csproj
src\X\Class1.cs
src\Y\Y.csproj
src\Y\Class2.cs

Actually the csproj files aren't needed, but what I wanted to express is that you would just need to copy the X and Y source folders into src. The algorithm that we use searches for the longest common path prefix in the original path (in this case C:\Projects\SomeDirectory) and replaces it with the src folder path.

On Sun, May 15, 2011 at 9:38 PM, afdavis <notifications@codeplex.com> wrote:

From: afdavis

Is it possible to create a symbols package when your package contains more than one assembly? What would the structure of the src directory look like, since normally everything from the single project goes at the top level?

Read the full discussion online.

To add a post to this discussion, reply to this email (nuget@discussions.codeplex.com)

To start a new discussion for this project, email nuget@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

May 16, 2011 at 12:07 AM

Thanks, that helps a lot.  If the project file and its output assembly have different names, which one should be used for the directory name in src?

For example:  MyProject.csproj which outputs MyFullNamespace.MyProject.dll

 

May 16, 2011 at 6:55 AM
Well, neither. The directory name must match the original directory name used during compilaton, because dlls/pdbs contain embedded absolute paths to source files. That's how debugging and source stepping works locally. You need to put your original directory structure under src - after stripping out the common prefix.

So if you have:
Common\Path\Prefix\MyProjectDirectory\MyProject.csproj which outputs MyFullNamespace.MyProject.dll
and
Common\Path\Prefix\MyProjectExtraDirectory\MyExtraProject.csproj which outputs MyFullNamespace.MyExtraProject.dll

The package should contain:
lib\MyFullNamespace.MyProject.dll
lib\MyFullNamespace.MyExtraProject.dll
src\MyProjectDirectory\*.cs
src\MyProjectExtraDirectory\*.cs

*.cs in this example is again the original project structure, because it might happen that there are many files named identically in a single project.

I hope it will be clear now.

On Mon, May 16, 2011 at 2:08 AM, afdavis <notifications@codeplex.com> wrote:

From: afdavis

Thanks, that helps a lot. If the project file and its output assembly have different names, which one should be used for the directory name in src?

For example: MyProject.csproj which outputs MyFullNamespace.MyProject.dll

Read the full discussion online.

To add a post to this discussion, reply to this email (nuget@discussions.codeplex.com)

To start a new discussion for this project, email nuget@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

May 17, 2011 at 10:13 PM
Edited May 18, 2011 at 12:50 AM

I have a fairly straight foward example that I am trying to accomplish, but I am unable to get the symbols published to symbolsource.

MyPackage.nupkg <-- zip file

   \lib
      \NET40-Client
         \HelloWorld.dll
      \SL4
         \HelloWorld.dll

I then create a second copy of my .nupkg file and using the Package Explorer modify it and save it as:

MyPackage.symbols.nupkg <-- zip file

   \lib
       \NET40-Client
           \HelloWorld.dll
           \HelloWorld.pdb
       \SL4
           \HelloWorld.dll
           \HelloWorld.pdb

Now i have two files MyPackage.nupkg and MyPackage.symbols.nupkg, but when i try to publish it fails to publish symbols. I am using NuGet.exe 1.3 that i downloaded today. I do all my package authoring using the GUI package explorer and simply export the .nupkg to a file directory and then use the NuGet.exe to push assemblies and symbols up to NuGet.org and SymbolSource.org since the GUI doesn't have that ability yet.

Submission failed: System.InvalidOperationException: Source file C:\...\HelloWorld\
HelloWorld\Greeting.cs not found for image file HelloWorld.
  at ITDT.Hss.Processing.Tools.PackageValidator.Validate (IDirectoryInfo directo
ryInfo) [0x00000] in <filename unknown>:0
  at ITDT.Hss.Server.Management.WebService.CreateJob (ITDT.Hss.Server.Management
.User user, System.Byte[] zipContent) [0x00000] in <filename unknown>:0

For some reason even though it gives me the error Symbolsource still shows my project deployed.

Project Repository Company Read Write
HelloWorld NuGet Public   Yes

But when I try to install and step through the code it fails. I followed the following steps from Davids blog

  • Under General, turn off “Enable Just My Code”
  • Under General, turn on “Enable source server support”. You may have to Ok a security warning.
  • Under Symbols, add “http://srv.symbolsource.org/pdb/Public” t the list.

    Looking at fiddler it fails to obtain the symbols from the server.
    Request - http://srv.symbolsource.org/pdb/public/HelloWorld.pdb/<api key>/HelloWorld.pdb
    Response - HTTP 1.1 404 Not Found

    I just came to notice that there are suppose to be some extra information in the HelloWorld.symbols.nupkg.  So there is this additional src folder that is suppose to contain the files for source, but the src folder does not follow the target framework pattern, so how am i suppose to seperate the Silvelight files from the WPF files?

    \lib
        \NET40-Client
            \HelloWorld.dll
            \HelloWorld.pdb
        \SL4
            \HelloWorld.dll
            \HelloWorld.pdb
    \src
        \Properties
           \AssemblyInfo.cs
        \Greeting.cs

    I would propose that the file structure be:

    \lib
        \NET40-Client
             \HelloWorld.dll
             \HelloWorld.pdb
        \SL4
             \HelloWorld.dll
             \HelloWorld.pdb
    \src
        \NET40-Client
            \Properties
                \AssemblyInfo.cs
            \Greeting.cs
        \SL4
            \Properties
                \AssemblyInfo.cs
            \Greeting.cs

    Another thing that I forgot to mention that adds extra complexity to this solution, is that my silverlight and WPF share the same code base. the Greeting.cs file actual exists in the Silverlight project, but is linked into the WPF project. So, In the layout I proposed above will there even be a Greeting.cs file? Seems to me that symbol support still has a long way to go, but I am looking forward to it.

  • May 19, 2011 at 7:19 AM
    Edited May 19, 2011 at 7:27 AM

    Ok, let me try to address all the issues that you described:

    1. Error message:

    Submission failed: System.InvalidOperationException: Source file C:\...\HelloWorld\HelloWorld\Greeting.cs not found for image file HelloWorld.

    As you correctly figured out this means that a source file was missing in the src folder. All submitted dlls are cross-checked with pdbs and then the existence of all source files is verified.

    2. Deployment status:

    To verify that a package was uploaded successfully you can go to the Status page and find your submission, or even better browse through Metadata pages and find your project/version. The table that you pasted only shows that you are permitted to upload on behalf of that project.

    3. Multi-framework support:

    Since you are compiling from the same codebase (using conditional compilation I assume) you only need to (and actually should) only include your source tree once:

    \src
       \Properties
          \AssemblyInfo.cs
       \Greeting.cs

    These source files will be associated with both \lib\NET40-Client\HelloWorld.dll and \lib\SL4\HelloWorld.dll.

    I hope this explains it all and that you'll find the the long way to go isn't that long actually ;)

    May 19, 2011 at 4:36 PM
    Edited May 19, 2011 at 4:37 PM

    @memfis, Thanks for your reply.

    I am awaiting a response from David on the NuGet team he said to post this question here after I commented on his blog. Later in my post I indicated what my mistake was, which was the missing src folder.
    http://blog.davidebbo.com/2011/04/easy-way-to-publish-nuget-packages-with.html <- only explains how to publish single dll targeting one framework.
     I am trying to get an answer on how to deploy a single dll that is targeted at multiple frameworks. I need a real answer though from the NuGet team on what is the actual Implementation.

    Thank you for the feed back.

    Developer
    May 19, 2011 at 5:25 PM

    This isn't supported in the workflow mentioned in David's blog post. We don't have a solution for that as yet. So you'll have to do it the manual way if you want to support multiple frameworks.

    May 19, 2011 at 5:29 PM

    Right, the current project-based workflow has limitation. We will definitely try to make it more general in the future.

    May 19, 2011 at 5:48 PM

    So, basically I just upload my .dll to NuGet like I have been doing and then upload my symobls one by one to SymbolSource.org. I have not used symbolsource.org before so I am still trying to figure out how to deploy symbols correctly.

    Thanks for the replies.

    May 20, 2011 at 5:52 AM

    Related thread: http://nuget.codeplex.com/discussions/258338

    May 20, 2011 at 7:10 PM

    @chrisahill1: you don't need to upload symbols separately (although actually you could). What do you mean by "one by one"?

    May 20, 2011 at 7:17 PM

    Since I am new to SymbolSource. I was assuming that I had to load my HelloWorld.pdb for my 4 frameworks seperateley.

    HelloWorld.pdb - .Net 3.5 Client Profile
    HelloWorld.pdb - .Net 4.0 Client Profile
    HelloWorld.pdb - Sl4
    HelloWorld.pdb - Sl3-wp

    Its just a matter of finding the time to read the symbolsource.org site and learn how to upload my symbols. if i can upload all of those at the same time then great.

    May 20, 2011 at 7:37 PM

    The best way is to put dlls and pdbs into lib - separated by framework - and sources into src - but only once, without any separation. If you have some common files for various frameworks but also some individual files, your original project tree (physical filesystem paths) make that separation for you. Just strip the common prefix and place the result under src. Note that a pdb has an entire absolute path to every file used to compile the associated dll, so when you structure your repository, you already are making a distinction between sources for each target framework. And there is no other way to match them with your binaries other than by that physical path.

    Consider this example:

    C:\Projects\HelloWorld\Common\HelloWorld.cs
    C:\Projects\HelloWorld\Silverlight\SpecialThing.cs
    C:\Projects\HelloWorld\Silverlight\HelloWorld.csproj (includes SpecialThing.cs and ..\Common\HelloWorld.cs, target SL4)  
    C:\Projects\HelloWorld\Full\SpecialThing2.cs
    C:\Projects\HelloWorld\Full\HelloWorld.csproj (includes SpecialThing2.cs and ..\Common\HelloWorld.cs, targets NET40-Client)

    The correct package for nuget.org will be in this case:

    \lib\NET40-Client\HelloWorld.dll
    \lib\SL4\HelloWorld.dll

    And for symbolsource.org:

    \lib\NET40-Client\HelloWorld.dll
    \lib\NET40-Client\HelloWorld.pdb
    \lib\SL4\HelloWorld.dll
    \lib\SL4\HelloWorld.pdb 
    \src\Common\HelloWorld.cs
    \src\Silverlight\SpecialThing.cs
    \src\Full\SpecialThing2.cs

    Perhaps you could share your actual project structure, including where and how you place your sources for compilation and I could explain on that example. I know the docs on symbolsource.org aren't really consolidated at the time, but we'll look into it soon.

    May 20, 2011 at 9:07 PM
    Edited May 20, 2011 at 9:08 PM

    thanks for the well explained example. The majority of our code exist in the silverlight project and is just linked over and compiled for the other frameworks. There may be one or two files that are not present in one of the linked versions.

    This is the structure that we have:

    \SilverlghtHelloWorld.sln
       \HelloWorld.cspj
           \Properties
               \Resources.resx ( mulitple files for localization)
           \Folder1
               \Code1.cs
           \Folder2
               \Code2.cs
           \Code3.cs
           \ToolkitFolder
                \UIControl.cs

    \WPFHelloWorld.sln
         \HelloWorld.cspj
            \Properties
                  \Resources.resx 
            \Folder1
                \Code1.cs (Linked)
             \Folder2
                \Code2.cs (Linked)
              \Code3.cs (Linked)
          \HelloWorld35.cspj
             \Folder1
                 \Code1.cs (Linked)
              \Folder2
                  \Code2.cs (Linked)
              \Code3.cs (Linked)
              \ToolkitFolder
                  \UIControl.cs (linked)


    \WP7HelloWorld.sln
        \HelloWorld.cspj
            \Properties
               \Resources.resx
            \Folder1
                \Code1.cs (Linked)
             \Folder2
                \Code2.cs (Linked)
             \Code3.cs (Linked)
             \ToolkitFolder (not included in this frameworkd)
                \UIControl.cs

    This covers most of the complexity of the API  structure.  There are several *.cspj files in each solution with dependencies to other *.cspj files in the solution. We are trying to start simple by just getting the core .dll file out there. The HelloWorld API is a test project that I am building to mirror the structure of our actual API. Since NuGet doesn't have a private/developer site. I can't test out our actual API I have to build this test project and slowly add more complexity.