what is difference between cli and mono in unix - c#

If I start the application directly
./coolappimade.exe
it get started using /usr/bin/cli. What is difference between this and /usr/bin/mono if any? What is better, start is as "native" or using mono?

As Bobson suggested, it is a symlink, I forgot to check...
So:
$ which cli
/usr/bin/cli
$ which mono
/usr/bin/mono
$ ls -l /usr/bin/mono
-rwxr-xr-x 1 root root 3054984 Jul 24 2012 /usr/bin/mono
$ ls -l /usr/bin/cli
lrwxrwxrwx 1 root root 21 Apr 17 16:16 /usr/bin/cli -> /etc/alternatives/cli
$ ls -l /etc/alternatives/cli
lrwxrwxrwx 1 root root 13 Apr 17 16:16 /etc/alternatives/cli -> /usr/bin/mono
Therefore on first sight, there is no difference (this is default way how it is installed in ubuntu). After reading http://www.mono-project.com/Guide:Running_Mono_Applications I figured out that the reason why this happens is that the debian packages of mono are registering the .exe as non-native binaries, that are executed using /usr/bin/cli (which is symlink to another symlink to /usr/bin/mono - why is that instead of directly running mono - nobody knows :)). This is just another way to execute mono binaries - according to linked page it's not recommended because it's linux only

Related

Unable to debug dotnet core GenericHost docker container

I am using Linux containers on the latest Windows build Windows 10 2004 and enabled WSL 2 and Docker Desktop 2.3.0.3 (45519).
I right click the docker-compose file, and select Set as Startup Project.
I then hit F5 to debug.
I can see the image running with docker ps however breakpoints are not being hit.
I cannot view Logs (on the Visual Studio Containers window) as it says:
It was not possible to find any compatible framework version
The framework 'Microsoft.AspNetCore.App', version '3.1.0' was not found.
- No frameworks were found.
You can resolve the problem by installing the specified framework and/or SDK.
The specified framework can be found at:
- https://aka.ms/dotnet-core-applaunch?framework=Microsoft.AspNetCore.App&framework_version=3.1.0&arch=x64&rid=debian.10-x64
I have installed the SDKs from the link given above.
Build output is below:
1>------ Build started: Project: Libertas.Host.Tickers.ScheduledTasks, Configuration: Debug Any CPU ------
1>Libertas.Host.Tickers.ScheduledTasks -> C:\Users\User\Source\Repos\myrepo\Libertas\src\Libertas.Host.Tickers.ScheduledTasks\bin\Debug\netcoreapp3.1\Libertas.Host.Tickers.ScheduledTasks.dll
1>docker build -f "C:\Users\User\Source\Repos\myrepo\Libertas\src\Libertas.Host.Tickers.ScheduledTasks\Dockerfile" --force-rm -t libertashosttickersscheduledtasks:dev --target base --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=Libertas.Host.Tickers.ScheduledTasks" "C:\Users\User\Source\Repos\myrepo\Libertas\src"
1>Sending build context to Docker daemon 1.362MB
1>
1>Step 1/4 : FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
1> ---> 86a2e7d45948
1>Step 2/4 : WORKDIR /app
1> ---> Running in d1ed1740d43e
1>Removing intermediate container d1ed1740d43e
1> ---> 90bd1703e28d
1>Step 3/4 : LABEL com.microsoft.created-by=visual-studio
1> ---> Running in 2626d5865d89
1>Removing intermediate container 2626d5865d89
1> ---> da74703374d2
1>Step 4/4 : LABEL com.microsoft.visual-studio.project-name=Libertas.Host.Tickers.ScheduledTasks
1> ---> Running in 7a381e7ea47a
1>Removing intermediate container 7a381e7ea47a
1> ---> fd2dd439cce6
1>Successfully built fd2dd439cce6
1>Successfully tagged libertashosttickersscheduledtasks:dev
1>SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
1>docker rm -f 9ff95181e06801ed3d4b4d5743397604b743d77c840f2047fb2caee046e5d8eb
1>Error: No such container: 9ff95181e06801ed3d4b4d5743397604b743d77c840f2047fb2caee046e5d8eb
1>docker run -dt -v "C:\Users\User\vsdbg\vs2017u5:/remote_debugger:rw" -v "C:\Users\User\Source\Repos\myrepo\Libertas\src\Libertas.Host.Tickers.ScheduledTasks:/app" -v "C:\Users\User\Source\Repos\myrepo\Libertas\src:/src/" -v "C:\Users\User\AppData\Roaming\Microsoft\UserSecrets:/root/.microsoft/usersecrets:ro" -v "C:\Users\User\.nuget\packages\:/root/.nuget/fallbackpackages" -e "DOTNET_USE_POLLING_FILE_WATCHER=1" -e "NUGET_PACKAGES=/root/.nuget/fallbackpackages" -e "NUGET_FALLBACK_PACKAGES=/root/.nuget/fallbackpackages" --name Libertas.Host.Tickers.ScheduledTasks_1 --entrypoint tail libertashosttickersscheduledtasks:dev -f /dev/null
1>ba95df9d32d6a0af07b1eab32af606131e075b2afff664c4003dbe3eae349543
========== Build: 1 succeeded, 0 failed, 6 up-to-date, 0 skipped ==========
My Dockerfile is below:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["Libertas.Host.Tickers.ScheduledTasks/Libertas.Host.Tickers.ScheduledTasks.csproj", "Libertas.Host.Tickers.ScheduledTasks/"]
COPY ["Libertas.Application.Tickers.ScheduledTasks/Libertas.Application.Tickers.ScheduledTasks.csproj", "Libertas.Application.Tickers.ScheduledTasks/"]
COPY ["PolygonIo.WebSocket/PolygonIo.WebSocket.csproj", "PolygonIo.WebSocket/"]
RUN dotnet restore "Libertas.Host.Tickers.ScheduledTasks/Libertas.Host.Tickers.ScheduledTasks.csproj"
COPY . .
WORKDIR "/src/Libertas.Host.Tickers.ScheduledTasks"
RUN dotnet build "Libertas.Host.Tickers.ScheduledTasks.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "Libertas.Host.Tickers.ScheduledTasks.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Libertas.Host.Tickers.ScheduledTasks.dll"]
I am unable to hit any breakpoints or even confirm if the app is running. I have a Generic Host app, and I don't even hit the breakpoint of the first line within public static void Main(string[] args).
Pointers much appreciated.
UPDATE AND FIX
So this was the smoking gun, in particular as this was a console application, and not a AspNetCore app.
It was not possible to find any compatible framework version
The framework 'Microsoft.AspNetCore.App', version '3.1.0' was not found.
- No frameworks were found.
You can resolve the problem by installing the specified framework and/or SDK.
The specified framework can be found at:
- https://aka.ms/dotnet-core-applaunch?framework=Microsoft.AspNetCore.App&framework_version=3.1.0&arch=x64&rid=debian.10-x64
I found one of my referenced libraries had a reference to Grpc.AspNetCore.
Once i moved this code out, it was able to run (I can confirm before the container instance was not running), with full debugging.
It compiled OK, the container ran, the application within the container never seemed to launch.
QUESTION
I would like to get to the bottom of why, as i don't fully understand how this fixed everything and what can be done to avoid in future (seems any console app that references a library that accidentally or otherwise references an AspNetCore dependency could have the same issue).
I had run into a similar problem... well, I think that the reasons are quite similar, in my case, I could not do anything, I could not even build the project, I had compiling errors, 'simple' ones... lol... let's say that using system; was erring and some other libraries that are there by default.
After a lot of investigation, I found out that my project was in net standard 2.0, but one of the nuget packages was for net standard 2.1, removing that package and finding a way to fix that part of the code resolved the problem.
The reason I believe was similar to what you are after, when adding the libraries, you are adding external code, external code that you don't control, so if the external library was referencing to another library that was not compatible with your project, like in my case, so I believe that the libraries were fighting to decide if it was meant to be a console or a web server app, have you tried to see the process that was created?
I also had a look at the library that you are mentioning (https://www.nuget.org/packages/Grpc.AspNetCore) and then click on dependencies and then there is this package:
Grpc.AspNetCore.Server.ClientFactory
which may have caused the crash.
Be careful with nuget packages, they are pretty cool and 'useful' but look at the dependencies, sometimes it is better to do your own code, that was my lesson.
For more details : https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/dependencies
QUESTION I would like to get to the bottom of why, as i don't fully understand how this fixed everything and what can be done to avoid in future (seems any console app that references a library that accidentally or otherwise references an AspNetCore dependency could have the same issue).
In Visual Studio Solution Explorer shows us the dependency tree with Nuget Packages and above that is the Frameworks listing Microsoft.NETCore.App:
This is how we can see the GitHub Repo references AspNetCore:
<FrameworkReference Include="Microsoft.AspNetCore.App" />
How can I stop this from happening?
Check Solution Explorer for Frameworks.
Have Unit Tests on the config and dependencies.
Always review the Package Dependancies you import.
If you're looking for the canonical story it's over here.
The problem Iria discusses can be prevented with NuGet Version ranges and wildcards notation. When referring to package dependencies, NuGet supports using interval notation for specifying version ranges, summarized as follows:
+-----------+---------------+-------------------------------------------------------+
| Notation | Applied rule | Description |
+-----------+---------------+-------------------------------------------------------+
| 1.0 | x ≥ 1.0 | Minimum version, inclusive |
| (1.0,) | x > 1.0 | Minimum version, exclusive |
| [1.0] | x == 1.0 | Exact version match |
| (,1.0] | x ≤ 1.0 | Maximum version, inclusive |
| (,1.0) | x < 1.0 | Maximum version, exclusive |
| [1.0,2.0] | 1.0 ≤ x ≤ 2.0 | Exact range, inclusive |
| (1.0,2.0) | 1.0 < x < 2.0 | Exact range, exclusive |
| [1.0,2.0) | 1.0 ≤ x < 2.0 | Mixed inclusive minimum and exclusive maximum version |
| (1.0) | invalid | invalid |
+-----------+-------------
When you're adding Packages enforce a version, this way you keep track of your dependancies with different versions (and ultimately versions of the .net framework).
Change the BASE image to use aspnet instead of runtime. The runtime image does not contain the ASPNET libs.
🪲 runtime:3.1-buster-slim
to
👍 aspnet:3.1-buster-slim
This also works for newer releases of .NET.

How to import nUnit/OpenCover results to SonarQube

We are running SonarQube Community Edition Version 7.9.1 (build 27448) (the currently latest docker image)
I have some nUnit tests but I'm struggling to get the code coverage data imported to SonarQube.
I have successfully used SonarScanner.MSBuild (sonar-scanner-msbuild-4.6.2.2108-net46) to import the code analysis and number of nUnit tests to SonarQube using the following commands:
SonarScanner.MSBuild.exe begin /k:"ProjectName" /d:sonar.host.url="..." /d:sonar.login="..." /d:sonar.cs.nunit.reportsPaths="NUnitResults.xml"
MSBuild.exe ....sln /t:Rebuild
nunit3-console.exe --result=NUnitResults.xml path\to\tests.dll
SonarScanner.MSBuild.exe end /d:sonar.login="..."
Now I want to use OpenCover to get the code coverage info to SonarQube so I'm using the following commands
SonarScanner.MSBuild.exe begin /k:"ProjectName" /d:sonar.host.url="..." /d:sonar.login="..." /d:sonar.cs.nunit.reportsPaths="NUnitResults.xml" /d:sonar.cs.opencover.reportsPaths="opencover.xml"
MSBuild.exe ....sln /t:Rebuild
nunit3-console.exe --result=NUnitResults.xml path\to\tests.dll
OpenCover.Console.exe -output:opencover.xml -register:user -target:"nunit3-console.exe" -targetargs:"path\to\tests.dll --result=NUnitResults.xml"
SonarScanner.MSBuild.exe end /d:sonar.login="..."
[I think I'm probably unnecessarily running the nUnit tests twice, but I'll sort that out once I've resolved the following issue]
The problem is I'm not getting any code coverage details on SonarQube.
Checking the SonarScanner log I can see the following output from OpenCover:
Executing: nunit3-console.exe
NUnit Console Runner 3.10.0 (.NET 2.0)
Copyright (c) 2019 Charlie Poole, Rob Prouse
06 September 2019 09:24:53
Runtime Environment
OS Version: Microsoft Windows NT 10.0.14393.0
CLR Version: 4.0.30319.42000
Test Files
path\to\UnitTests.dll
Run Settings
DisposeRunners: True
WorkDirectory: ...
ImageRuntimeVersion: 4.0.30319
ImageTargetFrameworkName: .NETFramework,Version=v4.6.1
ImageRequiresX86: False
ImageRequiresDefaultAppDomainAssemblyResolver: False
NumberOfTestWorkers: 8
Test Run Summary
Overall result: Passed
Test Count: 35, Passed: 35, Failed: 0, Warnings: 0, Inconclusive: 0, Skipped: 0
Start time: 2019-09-06 08:24:54Z
End time: 2019-09-06 08:24:57Z
Duration: 3.111 seconds
Results (nunit3) saved as NUnitResults.xml
Committing...
Visited Classes 12 of 12 (100)
Visited Methods 41 of 41 (100)
Visited Points 240 of 240 (100)
Visited Branches 41 of 41 (100)
==== Alternative Results (includes all methods including those without corresponding source) ====
Alternative Visited Classes 12 of 12 (100)
Alternative Visited Methods 41 of 53 (77.36)
Now checking the dir I can see I have NUnitResults.xml and opencover.xml created and populated. (I don't really know how to read OpenCover results but it has data for my unit tests)
The SonarScanner.MSBuild.exe end log has this tidbit:
INFO: Sensor C# Tests Coverage Report Import [csharp]
INFO: Parsing the OpenCover report path.\opencover.xml
INFO: Adding this code coverage report to the cache for later reuse: path.\opencover.xml
WARN: The Code Coverage report doesn't contain any coverage data for the included files. For troubleshooting hints, please refer to https://docs.sonarqube.org/x/CoBh
INFO: Sensor C# Tests Coverage Report Import [csharp] (done) | time=14ms
INFO: Sensor C# Unit Test Results Import [csharp]
INFO: Parsing the NUnit Test Results file path.\NUnitResults.xml
INFO: Sensor C# Unit Test Results Import [csharp] (done) | time=34ms
Now the classes that the unit tests cover are included (I can see them in SonarQube marked as uncovered) so I guess either OpenCover isn't collecting the correct info or something is going wrong matching the covered files with the file in the solution.
n.b. Checking the project that should be covered by these tests, under Project > Build > Advanced the Debug Info is set to full for Debug configuration, which some resources seem to suggest is required.
Any idea what I'm missing/where I'm going wrong?
UPDATE
Checking the bottom of opencode.xml it has the following:
<Module skippedDueTo="MissingPdb" hash="DD-83-09-69-9F-A7-11-FF-F5-BC-43-7C-87-B2-54-99-0D-A5-D5-61">
<ModulePath>C:\Windows\Microsoft.Net\assembly\GAC_MSIL\MyCompany.Common.Utility\v4.0_1.0.0.0__bf95fa7f15863c9f\MyCompany.Common.Utility.dll</ModulePath>
<ModuleTime>2019-09-05T16:07:28.6111533Z</ModuleTime>
<ModuleName>MyCompany.Common.Utility</ModuleName>
<Classes />
</Module>
The original authors of this solution seemed to like shoving everything in the GAC, so I'm guessing OpenCover is looking in the GAC rather than locally for the dll, and the GAC doesn't hold pdbs.
I tried setting the OpenCover -targetdir setting as suggested in the manual:
The path to the target directory; if the target argument already contains a path then this argument can be used to provide an alternate path where PDB files may be found.
I also tried to use -searchdirs (Alternative locations to look for PDBs.)
but neither of them resolved it.
Can I tell OpenCover to use the bin\Debug pdbs?
https://github.com/OpenCover/opencover/wiki/Usage#notes-on-spaces-in-arguments
Using \" in targetargs to represent quotes to nunit3-console
SonarScanner.MSBuild.exe begin /k:"ProjectName" /d:sonar.host.url="..." /d:sonar.login="..." /d:sonar.cs.nunit.reportsPaths="NUnitResults.xml" /d:sonar.cs.opencover.reportsPaths="opencover.xml"
MSBuild.exe ....sln /t:Rebuild
OpenCover.Console.exe -output:opencover.xml -register:user -target:"nunit3-console.exe" -targetargs:"\"path\to\tests.dll\" --result=NUnitResults.xml"
SonarScanner.MSBuild.exe end /d:sonar.login="..."
Step1 : SonarScanner.MSBuild.exe begin /k:"Project-Name" /d:sonar.cs.opencover.reportsPaths=%cd%\TestCoverResult.xml /d:sonar.exclusions="**/*.css,**/*.js,**/*.cshtml" /d:sonar.verbose="true" /d:sonar.host.url="https://host-url.com/" /d:sonar.login="Login-Token"
Step2 : "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe" /t:Rebuild
Step3 : ".\packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe" "-target:.\packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe" "-targetargs:.\Test-Project\bin\Debug\Test-Project.dll" "-output:.\TestCoverResult.xml" -register:user
Step4 : SonarScanner.MSBuild.exe end
Explanation:
1 : reportsPath: specifies the path of the code-coverage result file.
2 : ".\packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe" : it is system path of the "OpenCover.Console.exe"
3 : ".\packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe" : it is system path of the "nunit3-console.exe"

Mono 3.4.1 isn't compiling correctly on the raspberry pi

I m trying to compile the latest Mono source from GIT (3.4.1) on the raspberry pi, i can make, and make install, but if i go to /usr/local/lib/mono i get only “2.0 compat-2.0 gac” folders and none for the other frameworks.
When i try to run:
pi#raspberrypi ~/testeMono $ mcs hello.cs
pi#raspberrypi ~/testeMono $ mono hello.exe
The assembly mscorlib.dll was not found or could not be loaded.
It should have been installed in the `/usr/local/lib/mono/4.5/mscorlib.dll' directory.
I have a initial mono installation that i got doing "sudo apt-get install mono-complete" (since i need mono to build mono) it's on /usr/lib/mono
i did 'make check' and here are the failed tests
420 test(s) passed. 6 test(s) did not pass.
Failed tests:
block_guard_restore_aligment_on_exit.exe
bug-10127.exe
finally_block_ending_in_dead_bb.exe
pinvoke2.exe
pinvoke3.exe
winx64structs.exe
make[5]: *** [runtest] Error 1
make[5]: Leaving directory `/home/pi/mono/mono/tests'
make[4]: *** [testjit] Error 2
make[4]: Leaving directory `/home/pi/mono/mono/tests'
make[3]: *** [check-am] Error 2
make[3]: Leaving directory `/home/pi/mono/mono/tests'
make[2]: *** [check-recursive] Error 1
make[2]: Leaving directory `/home/pi/mono/mono/tests'
make[1]: *** [check-recursive] Error 1
make[1]: Leaving directory `/home/pi/mono/mono'
make: *** [check-recursive] Error 1
Any help trying to debug what's wrong is welcome, since i don't know where should i look.
I would add these questions to comment, but don't have enough reputation.
what is the output of ./autogen.sh at the end? Look at the libraries section. Do you have .NET 4.0 and .NET 4.5 'yes' in this section? If they are 'no', try run ./autogen.sh --with-profile4=yes --prefix=your_prefix
Libraries:
.NET 2.0/3.5: yes
.NET 4.0: yes
.NET 4.5: yes
why do you choose to install in /usr/local, when your system mono is located in /usr? You'll have two mono installation in different directories. This is useful, when you what to use parallel mono environments, but as far as I understand, you just want update mono to the latest version. I use --prefix=/usr in this case, to avoid issues of finding libraries in PATH.
these failed tests mean that some of mono functionality (related to PInvoke) won't work correctly on your platform but in general mono will work as expected (because all other tests were passed)

Using .NetZ and WPF causes System.IO.IOException

My aim is to be able to use any packer for C# applications and libraries (preferring WPF) via command line or full build-in at Visual Studio.
I came accross .NetZ (http://madebits.com/netz/) that is pretty neat and worked pretty well until I tested it with a WPF application:
PackageExample.Program -> C:\Users\[username]\Documents\Visual Studio
2012\Projects\PackageExample\PackageExample.Program\bin\Debug\PackageExample.Program.exe
COMMAND: packcompress\netz-bin-40\netz.exe -o PackageExample.Program\bin\Debug\Packed -pl
anycpu -s -z PackageExample.Program\bin\Debug\PackageExample.Program.exe
"PackageExample.Program\bin\Debug\*.dll" -d:# -v
__________________________________________
| |
| .NETZ - .NET Executables Compressor |
| Copyright (C) 2004-2013 Vasian Cepa |
| [v0.4.8] http://madebits.com |
|__________________________________________|
PE subsystem : GUI
.NET Runtime : 4.0.30319.18052
Output directory: C:\Users\[username]\Documents\Visual Studio
2012\Projects\PackageExample\PackageExample.Program\bin\Debug\Packed
RID: zip.dll
Added : C:\Users\[username]\Documents\Visual Studio
2012\Projects\PackageExample\packcompress\netz-bin-40\zip.dll [65536 byte(s) ~ 64KB]
Processing : 3 file(s)
1| C:\Users\[username]\Documents\Visual Studio
2012\Projects\PackageExample\PackageExample.Program\bin\Debug\PackageExample.Program.exe
[255488 byte(s) ~ 249KB] -> [130850 byte(s) ~ 127KB] - 49%
RID: A6C24BF5-3690-4982-887E-11E1B159B249
2| C:\Users\[username]\Documents\Visual Studio
2012\Projects\PackageExample\PackageExample.Program\bin\Debug\PackageExample.Lib1.dll
[4096 byte(s) ~ 4KB] -> [1577 byte(s) ~ 1KB] - 62%
RID: PackageExample.Lib1!2!1Version=1.0.0.0!2!1!4=neutral!2!1PublicKeyToken=null
3| C:\Users\[username]\Documents\Visual Studio
2012\Projects\PackageExample\PackageExample.Program\bin\Debug\PackageExample.Lib2.dll
[4608 byte(s) ~ 4KB] -> [1617 byte(s) ~ 1KB] - 65%
RID: PackageExample.Lib2!2!1Version=1.0.0.0!2!1!4=neutral!2!1PublicKeyToken=null
Done [00:00:00.300]
The packed app throws this: http://i.imagebanana.com/img/251ygj82/Unbenannt.PNG
(The ressource mainwindow.xaml cannot be found.)
The problem seems to be the xaml .NetZ confuses, but I found some people who got it working on the internet, but I do not get any problem solution.
Are you able to help me in this case?
Additional information: It might be interesting to mention I even tried this with the .NET 2.0 .NetZ build on a .NET 3.5 WPF application.
I also had problems using NetZ to compress an WPF 4.0 exe and DLLs into a single exe.
My app.xml.cs would start to run, but then an UnhandledException of type NotImplementedException would be thrown:
Baml2006SchemaContext.ResolveBamlType ...
To troubleshoot this, I ran fuslogvw.exe to see assembly binding errors, and discovered that GalaSoft.MvvmLight.Wpf4.dll was failing to load from the Netz-packed assembly.
I then switched to NetZ.exe compiled from source and tried again.
After repeated experimentation, I see that if I recompile and NetZ-pack the app, it sometimes starts working. Recompile again the main app again, and NetZ produces a failing app.
In other words, something is intermittent.
Sorry for the not-so good news - either try another packing scheme, or try NetZ repeatedly on many builds, until you find a working one.

after using mkbundle2, destination machine can't find libmono.0.dylib

I have a very simple .NET commandline application that I want to port to OS X.
I can run it with "mono app.exe"
However, the destination machines won't have mono installed.
So, I wanted to bundle mono inside the app.
In order to do this, I used mkbundle2:
mkbundle2 -o bundledapp.exe app.exe --deps
This works without errors, output:
OS is: Darwin
Sources: 1 Auto-dependencies: True
embedding: /Users/kclement/Projects/app/build/app.exe
embedding: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/2.0/mscorlib.dll
embedding: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/gac/System/2.0.0.0__b77a5c561934e089/System.dll
embedding: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/gac/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
embedding: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/gac/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
embedding: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/gac/System.Security/2.0.0.0__b03f5f7f11d50a3a/System.Security.dll
embedding: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/mono/gac/Mono.Security/2.0.0.0__0738eb9f132ed756/Mono.Security.dll
Compiling:
as -arch i386 -o temp.o temp.s
cc -g -o bundledapp.exe -Wall temp.c `pkg-config --cflags --libs mono` temp.o
Done
I can execute this on the build machine. When I execute on a machine without mono however, it won't run.
Output:
dyld: Library not loaded: /Library/Frameworks/Mono.framework/Versions/2.6.1/lib/libmono.0.dylib
Referenced from: /Users/kristof/./bundledapp.exe
Reason: image not found
Trace/BPT trap
What am I missing? How do I include the actual mono runtime?
EDIT:
I also tried adding the --static flag.
That gives my app another license however, which I'm not sure I want.
I then no longer complains about libmono, but about libgthread-2.0.0.dylib
So, the problem is that mkbundle links to some file that reside on my mac, where I expected it to bundle them. You can clearly see that by looking up the linked resources with the command:
otool -L ./BundledApp
(where bundledApp is the output of mkbundle2)
In order to fix it, I ended up using the mkbundle nant-tasks from the monobjc project:
http://www.monobjc.net/index.php?page=mkbundle-task
I think they are pretty much an automated version of what I found here:
http://code.google.com/p/cocoa-sharp-dev/wiki/RedistributableAppWithoutInstallingMono
But that gave me exceptions.
The Monobjc nant task works without any issues, and is by far the easiest solution. I still have multiple files but that's ok, at least it works now.
Try running:
mkbundle -o bundledappname program.exe
--deps
(use a different name for the bundle rather than the same as your program.exe and do not put .exe extension to the -o flag)
Also, did you tried macpack ?
For more information on how to create bundles read here and the fine manual of mkbundle

Categories