Include file in C#, Mono (gmcs) - c#

I'm writing a really small application in C# and I need to include an .cs file with some class. How do I do that? I'm looking for some equivalent to PHP's "include file" or Python's "from file import something". Obviously "using" is not enough and the file has to be somehow linked. And I really don't want to start some new super-huge-totally-useless project using MonoDevelop or VisualStudio, I would like to stay with simple gmcs and command line.

You simply include both file names on the command line and ensure that the namespaces are the same or that the namespace of the included file is imported via a using statement or via fully qualified references. Then the command line for compilation looks like this:
gmcs mainFile.cs includeFile.cs
Note that the mono command line is designed to support the exact same syntax (with a few additions) as the Microsoft compiler so this is true for both of them.
Fundamentally this is what the project files and visual studio are doing (albeit going through an in memory msbuild equivalent)

There are two ways to "include" a file in .NET (and Mono)
Compile several files together.
gmcs mainFile.cs includeFile.cs
then files are then compiled together to a single assembly
Compile the includeFile to a separate assembly and reference that from the main assembly
gmcs -target:library includeFile.cs
gmcs -r:includeFile.dll mainFile.cs
this way you get two assemblies

Related

Can I compile C# without having to include the reference .dlls in the console? (Linux)

As part of my project I have two files that I need to compile, and they both depend on System.Windows.Forms and System.Drawing. When compiling I write:
mcs engine.cs -r:System.Windows.Forms.dll,System.Drawing.dll
mcs main.cs -r:System.Windows.Forms.dll,System.Drawing.dll,engine.exe
Right now this is a nuisance, but manageable, but I am afraid that it will get worse once I write more code. I am not using Visual Studio as I found it easier to just use Atom for everything.
I tried to search for Atom packages that can handle this automatically; bash scripts that compile with the references in the background, but I'm curious to know if there is a simpler way that I'm just not seeing.
Thanks.

mono-compiled binaries not runable on Windows (unless msbuild is used)

I have some trouble using binaries created by Mono csc compiler on Windows. It's a basic CLI project for Framework 4.0 with a few internal assemblies. Previously, we were building this tool with xbuild and the result was usable everywhere. Now xbuild cannot be used (internal policy reasons) so I added a script which calls csc commands directly. The .exe can still be run in Mono but on Windows I get:
Method not found: "System.String System.String.TrimEnd(Char)".
at …
This is surprising. When I investigate that function call in code, it's like:
subDirectory.Replace('/', Path.DirectorySeparatorChar).TrimEnd(Path.DirectorySeparatorChar)
So, that signature is not available in .NET but .TrimEnd(params Char[]) is. And the compiler should normally convert between a single argument and params array.
My csc command line looks like:
csc /debug:full /debug:portable /optimize- /define:"DEBUG;TRACE"
/langversion:latest .v4.0.AssemblyAttribute.cs
/out:bin/Debug/myproject.exe /target:exe *.cs /.cs
/r:bin/Debug/some_custom_depencency.dll
/r:bin/Debug/some_other_custom_dependency.dll …
/nostdlib /r:System.dll /r:System.Xml.Linq.dll
/r:System.Data.DataSetExtensions.dll /r:System.Data.dll
/r:System.Xml.dll /r:System.Core.dll /r:mscorlib.dll /warn:4
It's more or less the same what msbuild does, just using shell's wildcard expansion. And the .v4.0.AssemblyAttribute.cs file is the one I grabbed from xbuild temp files (where it defines the .NET Framework version).
I checked the old and new exes (msbuild and custom calls) in dotPeek and everything looks identical except for the signature. File is runnable with Mono itself.
I'm running out of ideas now, can anyone suggest something to try or change or knows the reason immediately?
Found the problem, it was right upfront. msbuild/xbuild uses absolute paths to the framework assemblies but my call didn't. I assumed that it would consider information from AssemblyAttribute but apparently it doesn't, mono linker happily goes to whatever its default framework is, and is not reporting mismatches at build time.
The solution: change the /r:... paths to the ones in /usr/lib/mono/4.0-api/ (or whatever the framework setting defines).

Faster C# compilation via usage of "object" files and merge later?

I'm very new to C# and have more knowledge in the field of C++ and Java. When compiling a C++ or Java project, I am used to that compilation is performed for each source file on its own. In C++, and additional step to link all the object files into one library/exe/dll is taken afterwards.
I see several advantages in this method, but I can not find a way to realize it in C# using the mono dmcs compiler. Assume I have two files each with a single class.
OptionsSet.cs
interface OptionsSet {
//
}
DefaultOptionsSet.cs
class DefaultOptionsSet : OptionsSet {
//
}
I can successfully compile this into a library by invoking
dmcs mylib/OptionsSet.cs mylib/DefaultOptionsSet.cs -target:library -out:mylib.dll
But I do not want to recompile all source files when I changed a single file! Doing the following:
dmcs mylib/DefaultOptionsSet.cs -target:library -out:mylib/DefaultOptionsSet.dll
yields
mylib\DefaultOptionsSet.cs(15,27): error CS0246: The type or namespace name `OptionsSet' could not be found. Are you missing an assembly reference?
Compilation failed: 1 error(s), 0 warnings
I know I can add assembly references with the -r option, but what if the assembly reference was not yet compiled?
In Java, my Makefile would look like this:
SOURCE_DIRS = mylib
SOURCES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.java))
CLASSES = $(SOURCES:java=class)
compile: $(CLASSES)
mylib/%.class: mylib/%.java
javac $< -classpath .
But I can not directly translate this to build my C# library.
C# does not support to do what you want to do, there is only a single step between source files (.cs) and the final assemblies (.dll and .exe).
Have in mind that a C# compiler is in general a lot faster than a C/C++ compiler for the same amount of source code (among other things this is because the C# doesn't have to read megabytes of header files for each source file), so generally compilation speed is not an issue.
If you really want what you can do is to split your work into several assemblies (.dll files), compile each separately, and then just reference those assemblies when building your main executable. However unless your project is really big, you'll spend more time implementing this split than the time you'd save from building less when done.
I'd recommend not to worry about long compile-times unless you actually have a problem with long compile-times.

How to compile just one file in c#?

In VC++ I can press CTRL+F7 to compile a single file, or right click on a source file ot compile it.
Is it possible to compile a single file (or current file) in C#?
I would like to for example know if my current file has any errors in it without having to compile everything.
For single .cs file compile + run:
In VS 2008, go to "Tools" > "External Tools"
Click on "Add"
Title: Run CSC (or whatever you want)
Command: C:\Windows\system32\cmd.exe
Arguments: /c C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe /target:winexe $(ItemPath) && $(ItemFileName)
Initial directory: $(ItemDir)
Check Use Output Window
Apply + Ok
Go to Tools and choose "Run CSC"
If this doesn't work, verify that your paths for cmd and csc match.
No it is not possible to do this in C#.
Unlike C++ a C# file cannot be reasonably compiled on it's own to determine if it has any errors. C++ achieves this through #include statements which allows a .cpp file to understand the declaration of types available. These declarations define the structure of types the current file depends on and allows the compiler to ensure they are used according to specification.
This process is handled implicitly in C#. The set of declarations available is simply the set of all declarations in all compiled files which are otherwise accessible. There is no way to forward declare dependencies in the manner C++ does and hence no way to ensure they are being used correctly within a single file.
A Visual Studio add-in tool like ReSharper is a very good investment for this situation.
ReSharper performs continuous background solution-wide code analysis and will report issues by conveniently displaying a bar next to your code file\document scrollbar which has red\orange lines denoting any lines of code that have issues\errors. The displayed lines are click-able to navigate to the line in question and also have tool-tips detailing what the exact problem is:
http://www.jetbrains.com/resharper/features/code_analysis.html#Continuous_Code_Quality_Analysis
http://www.jetbrains.com/resharper/features/screenshots/50/marker_bar.png
The issues\warnings that ReSharper can check for are configurable (but it has excellent configuration out-of-the-box), and can denote anything from errors which would cause the code not to compile to more subtle issues where it has detected a possible null method call result which has not been explicitly checked for.
In command line:
%windir%\Microsoft.Net\framework\V3.5\csc.exe /target:library File.cs
You could reasonably attach this to the solution explorers context menu through Tools->External Tools
set the arguments to /target:library $(ItemPath)
something like that might do what you want. Though the file would have to depend on no other files in the project or in referenced binaries aside from what's in the GAC.
Shift-F6 will compile the current assembly, which is almost what you want.
Yes it's possible. You can call the compiler directly using command prompt. i.e.
Create single file 'hello.cs'
Open the Visual Studio command prompt
Navigate to the directory that has 'hello.cs'
Run csc hello.cs
Execute your single file by typing hello.exe
This will at least tell you whether a single file compiles or not. You can find more information here: https://msdn.microsoft.com/en-us/library/78f4aasd.aspx
Yes, this can be done using the Mono .NET Framework. At the command prompt, run mcs path/to/file.cs.
From the Mono docs:
To compile, use csc:
csc hello.cs
Note: csc compiler is not available on all platforms or in very old Mono versions, in such cases use mcs instead.
The compiler will create “hello.exe”, which you can run using:
mono hello.exe
Using Visual Studio 2022 csc.exe
navigate here in PowerShell:
PS C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\Roslyn
compile single file into dll or exe:
.\csc.exe -target:library -out:"C:\Users\quick\OneDrive\Desktop\C#\PerpetualCalendar\PerpetualCalendar.dll" "C:\Users\quick\OneDrive\Desktop\C#\PerpetualCalendar\PerpetualCalendar.cs"
cs file needs Main Method
.\csc.exe -target:exe -out:"C:\Users\quick\OneDrive\Desktop\C#\PerpetualCalendar\PerpetualCalendar.exe" "C:\Users\quick\OneDrive\Desktop\C#\PerpetualCalendar\PerpetualCalendar.cs"

.cs to .dll conversion issue

I've 10 .cs files in my app_code folder. Now I want to convert all 10 class files into one dll. Is if possible?
I'm trying to convert it by using csc /t:library admin.cs --> like this
But it is showing error like The type of namespace dbConnection could not be found (Are you missing a using directive or an assembly refference? )
Why are you using the command line compiler?
You don't want to create a DLL - you want to create an Assembly. This is important because you need to know the terminology to solve this.
The code you're compiling has errors. The message you quote means that you are missing an assembly reference, or you are missing a "using" statement in admin.cs, or (most likely) there are syntax errors - in this case, dbConnection is being used in a context where it is not defined.
Do yourself a favor and open this up in visual studio. Create a new "class library" project (it's on the list available in the "new project" dialog) and add all of your .cs files to it. Compile, find the bugs, fix them.
Given the form of your question, you're obviously pretty new at C# and .NET. Use the tools that are available (namely, Visual Studio) and give it some time.
If you really want to use the command line compiler, you can list of the assemblies that you depend on with the /r option.
You can create a new Class Library project in your solution and move your code files into there. The Class Library project will compile into a single DLL.

Categories