Primeiros passos com C# e o Mono #00
Tags: mono, linux, csharp, terminal
Published: 2020-03-27 03:11:57

|                    Capítulos                   |
|------------------------------------------------|
| [#00 - Instalação e compilador C#](https://dev.to/dannrocha/meus-primeiros-passos-como-c-e-mono-2ao1)           |
| [#01 - Sistema de build e importação de pacotes](https://dev.to/dannrocha/primeiros-passos-com-c-e-o-mono-01-448i) |
| #02 - Configurando ambiente de desenvolvimento |
***Esse post é mais um lembrete***. Comecei a escrever esse post porque queria salvar o passo a passo de como executar o C# em ambiente linux, utilizando a implementação open source do C#, o mono, sem utilizar qualquer IDE.

Porque não utilizar uma IDE ou algum editor de texto entupido de plugin (VS Code, ...) pra executar programas C#? Simplesmente porque gostaria de ter a dor de cabeça de rodar um programa em um ambiente pouco conhecido, sem saber muito da linguagem e sua importação de módulos, além de tentar entender como as IDEs "linkam" as bibliotecas com o arquivo raiz (Main).

## Instalação do Mono:
Meu ambiente de atual é o Ubuntu 18.04, então os comandos de instalação são específicos pra essa plataforma, mas você pode acessar o site do projeto oficial para obter as instruções especificas pra sua plataforma [clique aqui](https://www.mono-project.com/download/stable/).

### Adicionando o repositório.
```
sudo apt install gnupg ca-certificates
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
sudo apt update
```
### Comando de Instalação.
```
sudo apt install mono-devel
```

### +Como instalei o ".NET"
Tive alguns problemas na instalação do *.NET*. Ao Tentar adicionar o repositório da Microsoft o servidor não respondia ou demorava demais pra obter dados da internet. Pra passar por cima do problema da instalação convencional tive que usar o modo "avançado" que o pagina inicial do ".NET" disponibiliza. Selecionando a versão e a arquitetura, obtive o link de um script de instalação ".sh", ao executar o script, ele realizar a  descompactação do pacote no diretório de chamada do script. Para deixar o comando "dotnet" disponível de forma global no sistema, movi o diretório do ".NET" para a ***/opt*** e fiz um link simbólico do executável principal para ***/usr/bin/***.

## Executando programas no Mono
Primeiramente uma simples observação: A [documentação do MONO/MICROSOFT](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe) é dez vez mais detalhado do que esse passo a passo.

* Arvore de diretórios:
```
.App
└── main.cs
```
* Conteúdo do main.css
```c#
using System;

namespace App {
	public class Run {
		public static void Main(string[] args) {
			Console.WriteLine("Hello Mono");
		}	
	}
}

```
* Compilando e executando.

O Mono possui o comando ***mono-csc*** que recebe *N* flags de configurações caso deseje uma compilação mais especifica. Para saber mais quais diretivas utilizar basta chamar o comando ***mono-csc --help | less***, o ***| less*** serve para paginar o manual do comando.

```
mono-csc main.cs
```

Após executar o comando, é gerado um arquivo com mesmo nome arquivo principal do projeto passado por parâmetro para o ***mono-csc*** com a extensão ***.exe***. Caso exista erros no programa referente a sintaxe ou erro de importação a compilação falhará.

Para executar o arquivo gerado digite ***"./"***(ponto + barra) na frente do programa compilado.
```
./main.exe
```
## Utilizando algumas <u>***flags***</u> do compilador Mono.
Todos as flags abaixo podem ser usadas em conjunto, e para facilitar a execução automatizada dos comandos recomendo utilizar o ***make*** e um ***Makefile***.

**[Todas as flags](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe)**

#### Definindo o arquivo principal do projeto (a que possui o Main).
* ***[-main](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/main-compiler-option)***
```
mono-csc filename.cs -main:namespace.class
```
***Exemplo***
```
mono-csc main.cs -main:App.Run
```
#### Definindo um nome para o arquivo compilado
A flag ***[-out](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/out-compiler-option):*** pode ser usada para definir um nome específico para o executável gerado, basta adicionar a flag e depois dos dois pontos (:) o nome do seu projeto. 
```
mono-csc filename.cs -main:namespace.class -out:new_filename
```
***Exemplo***
```
mono-csc main.cs -main:App.Run -out:hello_mono
```
#### Compilando recursivamente.
A opção ***[-recurse](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/recurse-compiler-option)*** permite compilar arquivos de código-fonte em todos os diretórios filho do diretório especificado ou do diretório do projeto.
.
```
mono-csc -recurse:filename.cs -main:namespace.class -out:new_filename
```
***Exemplo***
```
mono-csc -recurse:main.cs -main:App.Run -out:new_filename
```

#### Compilando com dependência de class/namespaces externas 
Vamos modificar um pouco o "projeto" para ter os múltiplos arquivos.

* Arvore de diretórios:
```
.App
├── ClasseExterna
│   └── ClasseExterna.cs
├── main.cs
└── outraClasseExterna.cs
``` 

Conteúdo dos arquivos
* ***main.cs***
```c#
using App.ClassExterna;
using App.OutraClassExterna;

namespace App {
	public class Run{
		public static void Main(string[] args){
			Falar.Diga("Ola Class Externa");
			Grite.Som("AHAHHAHAHHAHAHAHHAHAH");
		}
	}
}
```
* ***outraClasseExterna.cs***
```c#
using System;

namespace App.OutraClassExterna{
	public static class Grite{
		public static void Som(string msg){
			Console.WriteLine(msg);
		}
	}
}
```

* ***ClasseExterna/ClasseExterna.cs.cs***
```c#
using System;

namespace App.ClassExterna {
	public static class Falar{
		public static void Diga(string msg){
			Console.WriteLine(msg);
		}
	}
}
```
#### Compilando os arquivos

Para realizar a compilação dos multiplos arquivos, passe os arquivos como parâmetro, respeitando os locais dos arquivos.

```
mono-csc filename.cs pathname/filename1.cs pathname/filename2.cs
```
***Exemplo***
```
mono-csc -recurse:main.cs ClasseExterna/*.cs outraClasseExterna.cs   
```

### Adicionando na compilação uma das bibliotecas padrão.
Vamos usar a ***System.Drawing*** e ***System.Windows.Forms*** como exemplo.

O nosso novo app vai apenas exibir na tela a mensagem: "Meu primeiro Programa em C# com GUI usando Mono".

* Arvore de diretórios.
```c#
.App
├── main.cs
```
* Conteudo da main.cs
```c#
using System;
using System.Drawing;
using System.Windows.Forms;

namespace App {
	class Window : System.Windows.Forms.Form {

		public Window(){} 

		public Window(string title, int width, int height) {
			
			Label label = new Label();

			ClientSize = new System.Drawing.Size (width, height);

			label.Text = "Meu primeiro Programa em C# com GUI usando Mono";
			label.Dock = DockStyle.Fill;
			label.TextAlign = ContentAlignment.MiddleCenter;
			this.Controls.Add(label);
			Text = title;
			
		}
		
		public static void Main(string[] args) {
			
			int width = 840, height = 480;

			Application.Run(new Window("Minha Janela", width, height));
		}
	}
}
```
Exemplo retirado do próprio repositório do Mono [link do repositório](https://github.com/mono/winforms)

##### Compilando
* Sintaxe
```
mono-csc filename.cs -r:library.dll -r:library.dll
```
***Exemplo***
Como estamos utilizando a ***System.Drawing*** e ***System.Windows.Forms***, devemos colocar essas bibliotecas como referencia na compilação com a flag [-reference](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/reference-compiler-option) ou [-r](https://docs.microsoft.com/pt-br/dotnet/csharp/language-reference/compiler-options/reference-compiler-option).
```
mono-csc main.cs -r:System.Windows.Forms.dll -r:System.Drawing.dll 
```
##### Programa em execução.

![](https://uploaddeimagens.com.br/images/002/553/993/original/Captura_de_tela.jpg?1585319920)

Há bibliotecas que não necessitam ser referenciadas no momento da compilação, ***exemplo***: ***System***, ***System.Collections.Generics***

#### Usando pacotes.
Vamos usar o Gtk como exemplo nesse tópico.

* Fonte
```c#
using Gtk;

namespace Poem {
	public sealed class GoncalvesDias {
		public struct Lyrical{
			public string Title;
			public string Body;

			static Lyrical(){}

			public Lyrical(string title, string body){
				Title = title;
				Body = body;
			}
		}

		public static Lyrical SongOfExile =  new Lyrical(
			"Canção do Exílio", 
		
		@"
	   	Minha terra tem palmeiras,
	   	Onde canta o Sabiá;
	   	As aves, que aqui gorjeiam,
	   	Não gorjeiam como lá.
	   	
	   	Nosso céu tem mais estrelas,
	   	Nossas várzeas têm mais flores,
	   	Nossos bosques têm mais vida,
	   	Nossa vida mais amores.
	   	
	   	Em cismar, sozinho, à noite,
	   	Mais prazer encontro eu lá;
	   	Minha terra tem palmeiras,
	   	Onde canta o Sabiá.
	   	
	   	Minha terra tem primores,
	   	Que tais não encontro eu cá;
	   	Em cismar — sozinho, à noite —
	   	Mais prazer encontro eu lá;
	   	Minha terra tem palmeiras,
	   	Onde canta o Sabiá.
	   	
	   	Não permita Deus que eu morra,
	   	Sem que eu volte para lá;
	   	Sem que desfrute os primores
	   	Que não encontro por cá;
	   	Sem qu’inda aviste as palmeiras,
	   	Onde canta o Sabiá.
	
	   	By Gonçalves Dias."
		);

	}
}


namespace App{
	public class Screen : Window {	 
	    public Screen(string title) : base(title) {
	        
BorderWidth = 8;
	        SetPosition(WindowPosition.Center);
	        DeleteEvent += delegate { Application.Quit(); };
	    }
	}
}

namespace Root {
	public class Run {
		public static void Main(){
			Application.Init();
			var screen = new App.Screen(Poem.GoncalvesDias.SongOfExile.Title);

			var poem = new Label(Poem.GoncalvesDias.SongOfExile.Body);

			screen.Add(poem);
			screen.ShowAll();

		 	Application.Run();
		}
	}
}
```

Para realizar a compilação utilizando um pacote, o compilador do Mono possui a flag ***-pkg:*** passando depois dos dois pontos o pacote utilizado no projeto.
```
mono-csc filename.cs -pkg:package 
```
***Exemplo***
```
mono-csc main.cs -pkg:gtk-sharp-2.0 
```
##### Programa em execução.
![](https://uploaddeimagens.com.br/images/002/554/365/original/Captura_de_tela_de_2020-03-27_14-08-37_Easy-Resize.com.jpg?1585328998)

Como sei quais pacotes estão disponíveis no meu sistema?
* Verifique o diretório ***/usr/lib/mono***