Tópicos

Ferramentas e ambiente de desenvolvimento: make, cvs, compilador de C/C++.

Exercício 1

Considere quatro ficheiros recurs.cpp (contendo a função factrecurs ), recurs.h (contendo a declaração da função factrecurs), iter.cpp (contendo a função factiter ), iter.h (contendo a declaração da função factiter) e main.cpp (contendo a função main que invoca sequencialmente ambas as funções anteriores e que inclui recurs.h e iter.h ).

  1. Construa, com estes cinco ficheiros, um projecto designado factorial, indicando os comandos para o colocar sob o controlo de versões do CVS. Admita que o repositório já existe em /cvs .
  2. Construa uma Makefile para gerar o executável fact, a partir dos ficheiros anteriores. Indique os comandos necessários para colocar a Makefile no repositório CVS.
  3. Considere agora que vai ter dois executáveis, cada um invocando a sua função. Indique as alterações à Makefile para que passe a gerar os executáveis recurs e iter, utilizando ambos o mesmo ficheiro main.cpp (mas diferentes implementações do factorial). Indique as operações do CVS para criar a nova versão do projecto, assumindo que o projecto está checked-out no directório corrente.
  4. Considere uma nova versão do projecto: pretende-se construir um único executável fact, mas a escolha da implementação do factorial é efectuada em tempo de execução. Considere que os ficheiros recurs.cpp e recurs.h existem num subdirectório recurs e, analogamente, existe um directório iter para a outra versão. Cada um dos conjuntos apresenta agora a mesma interface para a função que calcula o factorial: fact. Construa duas bibliotecas dinâmicas, ambas designadas por libfact.so, cada uma em seu directório ( recurs/libfact.so e iter/libfact.so). A selecção da variante a utilizar faz-se definindo a variável de ambiente LD_LIBRARY_PATH com o directório apropriado. Indique quais os ficheiros iniciais modificados, face à alínea anterior, a nova Makefile e os comandos CVS necessários para que o repositório passe a conter a nova versão.
  5. Modifique a alínea anterior para que o utilizador possa escolher a variante a utilizar através de um argumento na linha do comando fact, respectivamente recurs ou iter. Indique quais os ficheiros iniciais modificados, a nova Makefile e os comandos CVS necessários para registar a nova versão.

Resolução do Exercício 1

Resolução no wiki da disciplina: Make/CVS example 1

Material de introdução às ferramentas make e CVS: ver wiki da disciplina

Exercício 2

Considere que se pretende desenvolver um compilador para a linguagem Pascal, usando C como linguagem de trabalho.
Para tal são desenvolvidos (admitem-se como existentes):

  • a análise lexical no ficheiro pascal.l, sabendo que o comando flex -l pascal.l gera o ficheiro lex.yy.c (que inclui o ficheiro y.tab.h).
  • a análise sintática no ficheiro pascal.y, sabendo que o comando byacc -d pascal.y gera os ficheiros y.tab.c e y.tab.h.
  • a verificação semântica no ficheiro pascal.c.
  • a geração de código no ficheiro i386.c.
  • as estruturas e declarações comuns no ficheiro pascal.h.
  1. Construa a Makefile que permite gerar automaticamente o executável pascal constituído pelos ficheiros acima indicados. Utilize, sempre que possível regras implícitas.
  2. Admita que pretende colocar os ficheiros fonte sob o controlo de versões do CVS e que o repositório ficará em $HOME/cvs, embora ainda nunca tenha usado o CVS.
  3. Ao transportar o compilador para um processador sparc foi necessário desenvolver um ficheiro sparc.c para gerar código para este processador.
  4. Sabendo que o compilador da alínea anterior estava sob o controlo do CVS indique as instruções necessárias para incluir este ficheiro no projecto designado por pascal. Assuma que o ficheiro já existe no directório corrente e a variável de ambiente CVSROOT está definida e designa o repositório CVS que contém o projecto pascal.
  5. Modifique a Makefile da alínea anterior por forma a permitir gerar, ou o executável para i386, ou o executável para sparc, consoante o argumento do comando make seja i386 ou sparc, mas gerando sempre um executável designado por pascal.