Fenner
RAD

Compilar e executar

Ctrl+F9 e F9, o executável desatualizado, a RTL pré-compilada e o AppGuard.

Compilar e executar#

Ctrl+F9 compila com o fc.exe e mostra a saída em Mensagens; duplo clique numa linha de erro vai à linha. F9 executa. A tela de espera mostra quanto tempo já faz, e ao fim a barra de estado diz em quanto tempo compilou. Acima das abas ficam a Plataforma e a Configuração de build, que dizem o -P e o -M da compilação. O fc.exe é procurado primeiro ao lado do RAD.exe e só depois em C:\Fenner\Compiler\bin.

Ctrl+S salva o projeto (<Nome>.fxp, .config, .manifest, src\Unit1.fxm, src\Unit1.designer.fxi, src\Unit1.fxf). Há uma preferência para gravar antes de compilar.

Executar (F9) e o executável desatualizado#

Ao lado do .exe/.dll o compilador grava um .fxdeps: a lista de tudo o que a compilação leu (o projeto, o .config, cada módulo, cada include, a RTL e o próprio fc.exe). No F9 o RAD o consulta: se algum desses arquivos mudou desde a compilação, mostra "o executável não reflete mais o código-fonte atual", com os arquivos que mudaram, e pergunta:

  • Sim: recompila e executa;
  • Não: executa o que está no disco;
  • Cancelar.

Se a recompilação falhar, nada é executado. Sem .fxdeps não há o que validar, e o F9 segue como sempre.

Um .fxdeps mais velho que o executável é ignorado: sobrou de uma compilação anterior e não diz nada sobre o .exe de agora. E um arquivo só conta como mudado se o conteúdo mudou (SHA-256): o RAD regrava todos os módulos a cada gravação, e isso sozinho não dispara o aviso.

A RTL pré-compilada (RtlPackage)#

A RTL (Fenner.BedRock) pode ficar numa DLL compartilhada em vez de dentro de cada executável. Um projeto que a usa compila em bem menos tempo (medido: 22 s contra 39 s no mesmo projeto, e o .exe sai com 1 MB em vez de 12), e todos os aplicativos passam a ter um alocador só. O preço: o executável só abre com a Fenner.BedRock.dll ao lado. O RAD a copia para a pasta do executável a cada compilação, e é ela que se distribui junto. Veja Packages e o .fxd.

O parâmetro do projeto. Aba Compilação das configurações do projeto: "Usar a RTL pré-compilada (RtlPackage)". É a chave RtlPackage do <Nome>.config, com dois ajustes: a Debug vale para todos os modos (All) e a Release, para o modo Release; um modo de outro nome usa a Debug. Um projeto novo já nasce ligado; um projeto aberto não muda, vale o que o .config dele disser.

Onde ela mora. <pasta do fc.exe>\Packages\MSWin64Debug|MSWin64Release\Fenner.BedRock.* (.dll, .fxd, .fxnames, .lib), igual no desenvolvimento e na distribuição.

Quando o RAD abre, ele confere as duas. Se falta, ou se foi feita por outro fc.exe (o .fxd recusa outra versão do compilador), compila em segundo plano, uma de cada vez, com o andamento no canto direito do rodapé ("RtlPackage (Debug): compilando em segundo plano… 2:15"). A janela segue livre. Só se considera pronta uma package com o carimbo Fenner.BedRock.rad-stamp (o fc.exe que a gerou), gravado quando a compilação termina bem: uma compilação interrompida deixa arquivos pela metade e, sem o carimbo, eles não contam. Fechar o RAD no meio derruba a compilação (e o compilador junto, sem deixar órfão); na próxima abertura ela recomeça. Uma que falhou não é tentada de novo sozinha na mesma sessão (o log fica em %APPDATA%\Fenner\RAD\rtlpackage). Projeto > Recompilar a RTL pré-compilada refaz as duas quando a RTL mudar.

Enquanto a package não está pronta, um projeto que a pede compila com a RTL embutida (--NoPackages) e o RAD diz por quê nas mensagens: melhor compilar mais devagar do que falhar.

Se a compilação COM a package falhar, o RAD pergunta o que fazer:

  • Compilar sem a package: só desta vez, o projeto continua pedindo a package;
  • Desligar a package no projeto: tira a chave RtlPackage do .config, grava e compila;
  • Parar.

Serve para o caso de a culpa ser da package (feita por outra versão do compilador, ou defeituosa) e não do seu código; se o erro for do código, ele volta de qualquer jeito.

O aplicativo que não some calado (AppGuard)#

Um erro fatal do sistema (violação de acesso, estouro de pilha, divisão de inteiros por zero) que escape de todo tratamento faz o Windows encerrar o processo sem dizer nada: o usuário só vê a janela sumir. Todo aplicativo (janelas ou console) gerado pelo RAD leva o módulo AppGuard, que mostra o erro antes de o processo morrer: numa caixa de mensagem, ou na saída de erro num aplicativo de console (UTF-8 quando redirecionada).

O RAD grava src\AppGuard.fxm a cada gravação e o põe no uses do .fxp sozinho; um projeto antigo ganha o módulo na próxima gravação. O nome AppGuard é reservado. Uma DLL não o leva.

São dois ganchos, porque um só não basta:

  • o tratador vetorizado é o único que enxerga um erro nascido dentro de uma window procedure (o clique de um botão, por exemplo): o Windows leva essa exceção pela fronteira do user32, e o processo morre sem passar pelo filtro de nível superior;
  • o filtro de nível superior pega o que escapar do resto.

O tratador só reporta erro de hardware cujo endereço está no próprio executável (as bibliotecas do sistema tratam sozinhas os acessos inválidos benignos) e nunca sob depurador. Nenhum dos dois consome o erro: depois de mostrar, devolvem o controle ao Windows, que encerra o processo e grava o dump.