Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package references cannot be resolved when trying to build API documentation programmatically #833

Closed
kMutagene opened this issue Aug 22, 2023 · 4 comments

Comments

@kMutagene
Copy link
Contributor

kMutagene commented Aug 22, 2023

Hi there,

I am trying to build API documentation for Plotly.NET programmatically, following the instructions from the docs. However, this fails for every project where there are external dependencies. Here is for example the error for Plotly.NET, which depends on a few packages, one of them bein DynamicObj:

code:

ApiDocs.GenerateHtml(
    inputs = [
        ApiDocInput.FromFile(
            @"C:\Users\schne\source\repos\plotly\Plotly.NET\src\Plotly.NET\bin\Release\netstandard2.0\Plotly.NET.dll"
        )
    ],
    output = @"C:\Users\schne\source\repos\plotly\Plotly.NET\src",
    collectionName = "Plotly.NET",
    substitutions = []
)
Full error
loading 1 assemblies...
registering entities for assembly Plotly.NET...

Error: FSharp.Compiler.DiagnosticsLogger+UnresolvedPathReferenceNoRange: Assembly: DynamicObj, full path: DynamicObj.DynamicObj
at FSharp.Compiler.TypedTree.CcuThunk.EnsureDerefable(String[] requiringPath) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTree.fs:line 5437
at FSharp.Compiler.TypedTree.NonLocalEntityRef.TryDeref(Boolean canError) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTree.fs:line 3319
at FSharp.Compiler.TypedTree.EntityRef.get_Deref() in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTree.fs:line 3395
at FSharp.Compiler.TypedTreeOps.stripTyEqnsA(TcGlobals g, Boolean canShortcut, TType ty) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTreeOps.fs:line 764
at FSharp.Compiler.TypedTreeOps.tyargsEnc(TcGlobals g, FSharpList`1 gtpsType, FSharpList`1 gtpsMethod, FSharpList`1 args) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTreeOps.fs:line 8768
at FSharp.Compiler.TypedTreeOps.typeEnc(TcGlobals g, FSharpList`1 gtpsType, FSharpList`1 gtpsMethod, TType ty) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTreeOps.fs:line 8741
at FSharp.Compiler.TypedTreeOps.XmlDocArgsEnc(TcGlobals g, FSharpList`1 gtpsType, FSharpList`1 gtpsMethod, FSharpList`1 argTys) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTreeOps.fs:line 8772
at FSharp.Compiler.TypedTreeOps.XmlDocSigOfVal(TcGlobals g, Boolean full, String path, Val v) in D:\a\_work\1\s\src\Compiler\TypedTree\TypedTreeOps.fs:line 8832
at FSharp.Compiler.InfoReader.GetXmlDocSigOfScopedValRef(TcGlobals g, EntityRef tcref, ValRef vref) in D:\a\_work\1\s\src\Compiler\Checking\InfoReader.fs:line 1105
at FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue.get_XmlDocSig() in D:\a\_work\1\s\src\Compiler\Symbols\Symbols.fs:line 2027
at FSharp.Formatting.ApiDocs.CrossReferences.getXmlDocSigForMember(FSharpMemberOrFunctionOrValue memb) in /home/runner/work/FSharp.Formatting/FSharp.Formatting/src/FSharp.Formatting.ApiDocs/GenerateModel.fs:line 707
at FSharp.Formatting.ApiDocs.CrossReferenceResolver.registerMember(FSharpMemberOrFunctionOrValue memb) in /home/runner/work/FSharp.Formatting/FSharp.Formatting/src/FSharp.Formatting.ApiDocs/GenerateModel.fs:line 801
at FSharp.Formatting.ApiDocs.CrossReferenceResolver.registerEntity(FSharpEntity entity) in /home/runner/work/FSharp.Formatting/FSharp.Formatting/src/FSharp.Formatting.ApiDocs/GenerateModel.fs:line 831
at <StartupCode$FSharp-Formatting-ApiDocs>[email protected](FSharpEntity arg00)
at Microsoft.FSharp.Collections.SeqModule.Iterate[T](FSharpFunc`2 action, IEnumerable`1 source) in D:\a\_work\1\s\src\FSharp.Core\seq.fs:line 602
at FSharp.Formatting.ApiDocs.ApiDocModel.Generate(FSharpList`1 projects, String collectionName, FSharpOption`1 libDirs, FSharpOption`1 otherFlags, Boolean qualify, FSharpOption`1 urlRangeHighlight, String root, FSharpList`1 substitutions, FSharpFunc`2 onError, ApiDocFileExtensions extensions) in /home/runner/work/FSharp.Formatting/FSharp.Formatting/src/FSharp.Formatting.ApiDocs/GenerateModel.fs:line 2939
at FSharp.Formatting.ApiDocs.ApiDocs.GenerateHtml(FSharpList`1 inputs, String output, String collectionName, FSharpList`1 substitutions, FSharpOption`1 template, FSharpOption`1 root, FSharpOption`1 qualify, FSharpOption`1 libDirs, FSharpOption`1 otherFlags, FSharpOption`1 urlRangeHighlight, FSharpOption`1 onError) in /home/runner/work/FSharp.Formatting/FSharp.Formatting/src/FSharp.Formatting.ApiDocs/ApiDocs.fs:line 153
at <StartupCode$FSI_0025>.$FSI_0025.main@()
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)

I have tried browsing the source code of the command tool for hints how these references can be resolved by the tool, but had no success. Is there a way to make sure these references can be resolved?

@nojaf
Copy link
Collaborator

nojaf commented Aug 22, 2023

Hello,

I think this might be the same problem as in #616 (comment).

Could you try and reference the missing dll using the ?otherFlags parameter?
Something like otherFlags = [ "-r:MyPath/ToMy/Assembly.dll" ]

@kMutagene
Copy link
Contributor Author

Hi @nojaf, thanks for the response, I'll give this a spin.

However, the referenced assemblies are not contained in the compilation output, so I guess the standard way is referencing these packages from the nuget cache (i do not use paket)?

@kMutagene
Copy link
Contributor Author

Adding references the way you suggested works fine, thanks. here is the solution. Note that i used <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> in my .fsproj file so that the dependency dlls are put into the same folder as the compilation output of the library.

I hoped that the references would not be necessary then, because the dependency dlls are in the same folder, but i still have to set the otherFlags option sadly.

ApiDocs.GenerateHtml(
    inputs = [
        ApiDocInput.FromFile(
            @"path\to\bin\Debug\netstandard2.0\Plotly.NET.dll"
        )
    ],
    output = @"C:\Users\schne\source\repos\plotly\Plotly.NET\src",
    collectionName = "Plotly.NET",
    substitutions = [],
    otherFlags = [ 
        @"-r:path\to\bin\Debug\netstandard2.0\Giraffe.ViewEngine.StrongName.dll" 
        @"-r:path\to\bin\Debug\netstandard2.0\DynamicObj.dll"
        @"-r:path\to\bin\Debug\netstandard2.0\Newtonsoft.Json.dll"
    ]
)

@kMutagene
Copy link
Contributor Author

For future reference, I found that setting libDirs is enough when all dependencies are in one folder:

A combination of <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> in the fsproj file and setting libDirs to the compilation output path leads to only one folder with all dependecies referenced. This might be easier especially for large projects with many dependencies:

ApiDocs.GenerateHtml(
    inputs = [
        ApiDocInput.FromFile(
            @"C:\Users\schne\source\repos\plotly\Plotly.NET\src\Plotly.NET\bin\Debug\netstandard2.0\Plotly.NET.dll"
        )
    ],
    output = @"C:\Users\schne\source\repos\plotly\Plotly.NET\src",
    collectionName = "Plotly.NET",
    substitutions = [],
    libDirs = [ @"C:\Users\schne\source\repos\plotly\Plotly.NET\src\Plotly.NET\bin\Debug\netstandard2.0\"]
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants