How to configure the DotNet SDK used by FSAC –or– DLL Hell on Ubuntu - linux

I'm learning F#, never having used any DotNet nor Mono before. I like the language, but I'm having a hard time with the myriad runtime versions and how to tell the various tools which version to use.
Summary: it appears DLL Hell on Ubuntu is a thing. How can I tell FSAC to run its auto-complete magic against the latest runtime version, namely Microsoft.NETCore.App 2.1.5, instead of whatever older incarnation it decided to use?
Longish explanation.
My platform is Ubuntu 18.04 amd64. I have installed the latest DotNet Core, specifically the packages dotnet-sdk-2.1 (version 2.1.403-1) and its dependencies dotnet-host, dotnet-runtime-2.1, etc. (which are all version 2.1.5-1). I also have Mono installed, because many tools apparently rely on it.
When I try to use some features that were recently added to DotNet Core, it feels like I'm uncovering a Pandora Box.
Take this example, which uses the new ProcessStartInfo.ArgumentList:
#r "System.Diagnostics.Process.dll"
open System.Diagnostics
let execute exe args =
let proc = new Process()
proc.StartInfo.FileName <- exe
for arg in args do proc.StartInfo.ArgumentList.Add arg
proc.Start() |> ignore
proc.WaitForExit()
execute "echo" ["foo"; "baz"]
If I naively try to run it with /usr/bin/fsharpi (which exec's /usr/bin/mono /usr/lib/mono/fsharp/fsi.exe) I get a "ArgumentList is not defined" error. Fair enough, I guess?
If I run it with /usr/bin/dotnet /usr/share/dotnet/sdk/2.1.403/FSharp/fsi.exe it works! It took me a long time to figure out I could even do it, but at last I'm on the right path.
But if I load the file in any IDE, such as VSCode with the Ionide plugin, or Sublime Text with the FSharp plugin, they still flag ArgumentList as invalid. Sublime's plugin also flags the #r line as invalid, but doesn't tell me why.
Focusing on Sublime's plugin and digging into the code, it appears that it relies on a tool called FsAutoComplete aka. fsac and on Linux explicitly invokes it with mono.
I tried running the FSAC tool with DotNet Core, but it fails to find some library or other:
$ cd .config/sublime-text-3/Packages/FSharp/fsac/fsac/
$ dotnet fsautocomplete.exe
A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/home/tobia/.config/sublime-text-3/Packages/FSharp/fsac/fsac/'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the /home/tobia/.config/sublime-text-3/Packages/FSharp/fsac/fsac/fsautocomplete.runtimeconfig.json file specifying the appropriate framework.
If I take a filesystem approach and search for System.Diagnostics.Process.dll, I'm baffled by the results:
/usr/lib/mono/4.5/Facades/System.Diagnostics.Process.dll
/usr/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll
/usr/lib/mono/xbuild/Microsoft/Microsoft.NET.Build.Extensions/net461/lib/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/2.1.403/Microsoft/Microsoft.NET.Build.Extensions/net461/lib/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.1.0/ref/netcoreapp2.1/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/netstandard.library/2.0.3/build/netstandard2.0/ref/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/lib/net46/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/lib/net461/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/ref/net46/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/ref/net461/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/ref/netstandard1.3/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/ref/netstandard1.4/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/runtimes/linux/lib/netstandard1.4/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/runtimes/osx/lib/netstandard1.4/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/runtimes/win/lib/net46/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/runtimes/win/lib/net461/System.Diagnostics.Process.dll
/usr/share/dotnet/sdk/NuGetFallbackFolder/system.diagnostics.process/4.3.0/runtimes/win/lib/netstandard1.4/System.Diagnostics.Process.dll
/usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.5/System.Diagnostics.Process.dll
Plus another dozen in my home directory, under ~/.nuget. That's insane.
To begin with, the entire /usr/share/dotnet/sdk/NuGetFallbackFolder subtree does not seem to be owned by any Deb package, which is worrisome enough. The others belong to these packages:
mono-devel: /usr/lib/mono/4.5/Facades/System.Diagnostics.Process.dll
mono-devel: /usr/lib/mono/4.7.1-api/Facades/System.Diagnostics.Process.dll
msbuild: /usr/lib/mono/xbuild/Microsoft/Microsoft.NET.Build.Extensions/net461/lib/System.Diagnostics.Process.dll
dotnet-sdk-2.1: /usr/share/dotnet/sdk/2.1.403/Microsoft/Microsoft.NET.Build.Extensions/net461/lib/System.Diagnostics.Process.dll
(*) dotnet-runtime-2.1: /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.5/System.Diagnostics.Process.dll
Running a simple Grep shows that only the last one marked with (*) knows anything about ArgumentList.
So all these other libraries are older / legacy versions, including the one in dotnet-sdk-2.1 itself.
I can only presume that the SDK, aka. the compilers and interpreters, are built against an older version of the runtime / system libraries than the one they build code against. Which is an interesting choice, to say the least.
Taking a process approach, lsof tells me that the FSAC process has only opened DLL files from inside /usr/lib/mono and from its own local directory. This is not promising.
Is there a way to tell FSAC to use the Microsoft.NETCore.App 2.1.5 runtime / system libraries for its autocomplete and linting work?

Related

__MINGW64__ not defined? Or how do I know what threading model to use?

I'm trying to resurrect the windows build of our product, but trying to move over to MingW64 for a better c++ threading experience. But, of course I don't want to just discard the old #include winpthreads code. I'd like an ifdef.
Everything I read says MINGW64 should be defined, but eclipse doesn't see it, nor does command-line:
C:\Program Files (x86)\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32>echo | bin\gcc -E -dM - | find "MING"
#define __MINGW32__ 1
So Is this me, or is this the way it is, or am I somehow still seeing my old mingw(32) installation?
Simple answer.
If you install mingw64 then both __MINGW32__ and __MINGW64__ are defined, and I can confirm that now, but only if you actually install the 64-bit version.
Bizarrely, given the claims of the mingw64 fork to be better for 64bit platforms, the default is 32-bit installation, identified by the non-helpful name 'i686'. You will be wanting the 'x86_64' option instead.

Installing SDL in cygwin

I have Cygwin, setup version 2.8473, 64-bit. I've installed gcc-g++. I am trying to install SDL2, trying both SDL2-2.0.3 and SDL2-2.0.4. I'll talk about the problems with 2.0.3, since that's the stable release.
I read that I should run /usr/bin/set-gcc-default-3.sh, but it's not there. (gcc does seem to have been installed, as I see it working when I run make in the SDL2-2.0.3 directory.) I haven't been able to find out where to get it by searching Internet -- maybe this is it? Without it, make gives me these complaints:
Warning, configure.in is out of date
and lots of "static declaration" errors like this:
.../SDL_render_d3d11.c:135:19: error: static declaration of 'IID_IDXGIFactory2' follows non-static declaration
static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb
^
I wasn't able to find anything useful googling IID_IDXGIFactory2.
According to the SDL Wiki's page on installation, "As of SDL 2.0.3, the codebase still compiles on Cygwin and MingW32, but we expect these to stop working in the future." So it's no longer supported, and I'll leave it.

Invalid Argument Running Google Go Binary in Linux

I’ve written a very small application in Go, and configured an AWS Linux AMI to host. The application is a very simple web server. I’ve installed Go on the Linux VM by following the instructions in the official documentation to the letter. My application runs as expected when invoked with the “go run main.go” command.
However, I receive an “Invalid argument” error when I attempt to manually launch the binary file generated as a result of running “go install”. Instead, if I run “go build” (which I understand to be essentially the same thing, with a few exceptions) and then invoke the resulting binary, the application launches as expected.
I’m invoking the file from within the $GOPATH/bin/ folder as follows:
./myapp
I’ve also added $GOPATH/bin to the $PATH variable.
I have also moved the binary from $GOPATH/bin/ to the src folder, and successfully run it from there.
The Linux instance is a 64-bit instance, and I have installed the corresponding Go 64-bit installation.
go build builds everything (that is, all dependent packages), then produces the resulting executable files and then discards the intermediate results (see this for an alternative take; also consider carefully reading outputs of go help build and go help install).
go install, on the contrary, uses precompiled versions of the dependent packages, if it finds them; otherwise it builds them as well, and installs under $PATH/pkg. Hence I might suggest that go install sees some outdated packages which screw the resulting build.
Consider running go install ./... in your $GOPATH/src.
Or may be just selective go install uri/of/the/package for each dependent package, and then retry building the executable.

NixOS and ghc-mod - Module not found

I'm experimenting a problem with the interaction between the ghc-mod plugin in emacs, and NixOS 14.04. Basically, once packages are installed via nix-env -i, they are visible from ghc and ghci, recognised by haskell-mode, but not found by ghc-mod.
To avoid information duplication, you can find all details, and the exact replication of the problem in a VM, in the bug ticket https://github.com/kazu-yamamoto/ghc-mod/issues/269
The current, default, package management set up for Haskell on NixOS does work will with packages that use the ghc-api, or similar (ghc-mod, hint, plugins, hell, ...) run time resources. It takes a little more work to create a Nix expression that integrates them well into the rest of the environment. It is called making a wrapper expression for the package, for an example look at how GHC is installed an operates on NixOS.
It is reasonable that this is difficult since you are trying to make a install procedure that is atomic, but interacts with an unknown number of other system packages with their own atomic installs and updates. It is doable, but there is a quicker work around.
Look at this example on the install page on the wiki. Instead of trying to create a ghc-mod package that works atomically you weld it on to ghc so ghc+ghc-mod is an atomic update.
I installed ghc+ghc-mod with the below install script added to my ~/.nixpkgs/nixpkgs.nix file.
hsEnv = haskellPackages.ghcWithPackages (self : [
self.ghc
self.ghcMod
# add more packages here
]);
Install package with something like:
nix-env -i hsEnv
or better most of the time:
nix-env -iA nixpkgs.haskellPackages.hsEnv
I have an alias for the above so I do not have to type it out every time. It is just:
nixh hsEnv
The down side of this method is that other Haskell packages installed with nix-env -i[A] will not work with the above installation. If I wanted to get everything working with the lens package then I would have to alter the install script to include lens like:
hsEnv = haskellPackages.ghcWithPackages (self : [
self.ghc
self.ghcMod
self.lens
# add more packages here
]);
and re-install. Nix does not seem to use a different installation for lens or ghc-mod in hsEnv and with the ghc from nix-env -i ghc so apparently only a little more needs to happen behind the scenes most of the time to combine existing packages in the above fashion.
ghc-mod installed fine with the above script but I have not tested out its integration with Emacs as of yet.
Additional notes added to the github thread
DanielG:
I'm having a bit of trouble working with this environment, I can't even get cabal install to behave properly :/ I'm just getting lots of errors like:
With Nix and NixOS you pretty much never use Cabal to install at the global level
Make sure to use sandboxes, if you are going to use cabal-install. You probably do not need it but its there and it works.
Use ghcWithPackages when installing packages like ghc-mod, hint, or anything needs heavy runtime awareness of existing package (They are hard to make atomic and ghcWithPackages gets around this for GHC).
If you are developing install the standard suite of posix tools with nix-env -i stdenv. NixOS does not force you to have your command line and PATH cultured with tools you do not necessarily need.
cabal assumes the existence a few standard tools such as ar, patch(I think), and a few others as well if memory services me right.
If you use the standard install method and/or ghcWithPackages when needed then NixOS will dedup, on a package level (If you plot a dependency tree they will point to the same package in /nix/store, nix-store --optimise can always dedup the store at a file level.), many packages automatically unlike cabal sandboxes.
Response to comment
[carlo#nixos:~]$ nix-env -iA nixos.pkgs.hsEnv
installing `haskell-env-ghc-7.6.3'
these derivations will be built:
/nix/store/39dn9h2gnp1pyv2zwwcq3bvck2ydyg28-haskell-env-ghc-7.6.3.drv
building path(s) `/nix/store/minf4s4libap8i02yhci83b54fvi1l2r-haskell-env-ghc-7.6.3'
building /nix/store/minf4s4libap8i02yhci83b54fvi1l2r-haskell-env-ghc-7.6.3
collision between `/nix/store/1jp3vsjcl8ydiy92lzyjclwr943vh5lx-ghc-7.6.3/bin/haddock' and `/nix/store/2dfv2pd0i5kcbbc3hb0ywdbik925c8p9-haskell-haddock-ghc7.6.3-2.13.2/bin/haddock' at /nix/store/9z6d76pz8rr7gci2n3igh5dqi7ac5xqj-builder.pl line 72.
builder for `/nix/store/39dn9h2gnp1pyv2zwwcq3bvck2ydyg28-haskell-env-ghc-7.6.3.drv' failed with exit code 2
error: build of `/nix/store/39dn9h2gnp1pyv2zwwcq3bvck2ydyg28-haskell-env-ghc-7.6.3.drv' failed
It is the line that starts with collision that tells you what is going wrong:
collision between `/nix/store/1jp3vsjcl8ydiy92lzyjclwr943vh5lx-ghc-7.6.3/bin/haddock' and `/nix/store/2dfv2pd0i5kcbbc3hb0ywdbik925c8p9-haskell-haddock-ghc7.6.3-2.13.2/bin/haddock' at /nix/store/9z6d76pz8rr7gci2n3igh5dqi7ac5xqj-builder.pl line 72.
It is a conflict between two different haddocks. Switch to a new profile and try again. Since this is a welding together ghc+packages it should not be installed in a profile with other Haskell packages. That does not stop you from running binaries and interrupters from both packages at once, they just need to be in their own name space so when you call haddock, cabal, ghc, there is only one choice per profile.
If you are not familiar with profiles yet you can use:
nix-env -S /nix/var/nix/profiles/per-user/<user>/<New profile name>
The default profile is either default or channels do not which one it will be for your set up. But check for it so you can switch back to it later. There are some tricks so that you do not have to use the /nix/var/nix/profiles/ directory to store you profiles to cut down on typing but that is the default location.

EclipseFP is searching for GHC and cannot find it

I have working Eclipse (Kepler Service Release 2) + EclipseFP (2.6.0) + Haskell Platform under Windows 8.1 x64.
In one moment after some cabal install, EclipseFP stopped working and showing me:
The program ghc version >=6.4 is required but it could not be found.
I have:
Uninstalled Haskell Platform
Deleted C:\Users\myuser\AppData\Roaming\cabal*
Deleted C:\Program Files (x86)\Haskell*
Install Haskell Platform 2013.2
Run Eclipse with my Haskell workspace
Try to build my project
It gave me this error about ghc and cannot build it.
EclipseFP configuration found all Haskell Helper executables. It found Cabal 1.16.0.2 and GHC 7.6.3 already. From command-line GHC and cabal are found and are working. "cabal build" is working on the project from command-line, too.
This message doesn't say almost anything! If I could see the path it is searching for GHC or where it get this path from...
EDIT:
Message from buildwrapper:
"C:\Users\home\AppData\Roaming\cabal\bin\buildwrapper.exe synchronize --force=false --tempfolder=.dist-buildwrapper --cabalpath=C:\Program Files (x86)\Haskell Platform\2013.2.0.0\lib\extralibs\bin\cabal.exe --cabalfile=D:\Project\haskell2\SomeGL\SomeGL.cabal --cabalflags= --logcabal=true
configuring because setup_config not present
"C:\Program Files (x86)\Haskell Platform\2013.2.0.0\lib\extralibs\bin\cabal.exe" "configure" "--verbose=1" "--user" "--enable-tests" "--enable-benchmarks" "--builddir=D:\Project\haskell2\SomeGL.dist-buildwrapper\dist"
cabal.exe: The program ghc version >=6.4 is required but it could not be found."
Calling exactly the last line from cmd.exe (as normal non-admin user) everything is working fine:
"C:\Program Files (x86)\Haskell Platform\2013.2.0.0\lib\extralibs\bin\cabal.exe" "configure" "--verbose=1" "--user" "--enable-tests" "--enable-benchmarks" "--builddir=D:\Project\haskell2\SomeGL\.dist-buildwrapper\dist"
EDIT:
To find the potential path environement that is used I tried to run GHCi console inside Eclipse and tried:
import System.Environment
x <- getEnvironment
filter (\ (a,_) -> a == "Path") x
and got something that is starting with:
[("Path","C:\Program Files (x86)\Haskell\bin;C:\Program Files
(x86)\Haskell Platform\2013.2.0.0\lib\extralibs\bin;C:\Program
Files (x86)\Haskell Platform\2013.2.0.0\bin;...")]
First folder is invalid, but Haskell Platform is valid and working.
Another thing I found. One of times I have run "Build All" command there was run Process in Eclipse with GHC and the path was:
Running executable C:\Program Files (x86)\Haskell
Platform\2013.2.0.0\bin\ghc.exe
I went to see this process details and it is run from the same user that is currently Eclipse run with. And the path is correct, but I still got the error:
The program ghc version >=6.4 is required but it could not be found.
Running from command-line still it is working. The program has errors, but only in command-line I see them.
Could someone help with finding this problem?
EDIT:
I found some interesting issue. Running "Build All" command is executing this command:
C:\Users\myuser\AppData\Roaming\cabal\bin\buildwrapper.exe synchronize
--force=false --tempfolder=.dist-buildwrapper --cabalpath=C:\Program Files (x86)\Haskell Platform\2013.2.0.0\lib\extralibs\bin\cabal.exe
--cabalfile=D:\haskell\SomeGL\SomeGL.cabal --cabalflags= --logcabal=true
Which run from command-line gives an error. The problem is that there are no quotes around cabalpath, because it has spaces in it. When I run it that way from command-line it works:
C:\Users\myuser\AppData\Roaming\cabal\bin\buildwrapper.exe synchronize --force=false --tempfolder=.dist-buildwrapper --cabalpath="C:\Program Files (x86)\Haskell Platform\2013.2.0.0\lib\extralibs\bin\cabal.exe" --cabalfile=D:\haskell\SomeGL\SomeGL.cabal --cabalflags= --logcabal=true
I think that all "--cabalfile" parameters should have quotes, because paths could have spaces in them. I still don't know if this is the problem under Eclipse.
I found the problem!
It is that EclipseFP 2.6.0 is using upper case "PATH" variable, but my Windows 8.1 use "Path" and programatically some kind it is possible to have valid two variables "PATH" and "Path" when executing BuildWrapper and Cabal. So something is messing up.
Workaround for this problem is if you rename from Control Panel | System | Environment variables for both User and System from "Path" to "PATH".
I hope this could be fixed in EclipseFP so it could in future work in any case.
Building your project means that under the scenes, cabal build is launched. If you activate the debugging mode in the Haskell helper executable preference page (show BuildWrapper responses), you should see the exact cabal build command being sent. It could be that the path used in Eclipse is different than the path used in the command line, check you eclipse shortcuts. EclipseFP can find the executables because it searches also in some well known folders on windows.
You can also take the current dev version of EclipseFP from github. It should now pass --with-ghc to cabal invocations to make sure the path detected in Eclipse is the one used.

Resources