CS107 Compilando Programas em C com GCC

Escrito por Chris Gregg, com modificações por Nick Troccoli

Clique aqui para um vídeo.

O compilador que usaremos para o CS107 é chamado de “Coleção de Compiladores GNU” (gcc). É um dos compiladores mais utilizados, e é ambos Software Livre, e está disponível em muitas plataformas de computação diferentes.

gcc executa o passo de compilação para construir um programa, e depois chama outros programas para montar o programa e ligar as partes componentes do programa em um programa executável que você pode executar. Vamos aprender um pouco sobre cada um desses passos durante o CS107, mas o bom é que gcc pode produzir todo o programa executável (executável) para você com um comando.

No CS107, vamos usar predominantemente Makefiles para compilar, montar e vincular nosso código, mas o Makefile executa gcc para fazer o trabalho. This is just a quick overview on how to compile and run your own programs should you decide to do so without a Makefile.

The simplest way to run gcc is to provide gcc a list of .c files:

$ gcc hello.c$

Note that you do not put header files (.h) into the gcc command: it reads in the header files as it compiles, based on the #include statements inside .c files.

If the program compiled without errors or warnings, you don’t get any output from gcc, and you will have a new file in your directory, called a.out. To run this file, you need to tell the shell to run the file in the current directory, by using ./ before the name:

$ ./a.outHello, World!$

Geralmente não queremos os nossos programas nomeados a.out, por isso pode dar a gcc uma opção, -o programName, para lhe dizer o nome do ficheiro executável:

$ gcc hello.c -o hello$ ./helloHello, World!$

Nota: cuidado para não introduzir acidentalmente um nome de ficheiro executável que seja o mesmo que o seu ficheiro de entrada – algo como:

$ gcc hello.c -o hello.c

On myth, o seu perfil foi configurado para apanhar o erro e não compilá-lo, deixando o seu ficheiro-fonte em tacto. Este não é o caso em muitos outros sistemas Linux, por isso tenha cuidado! Em outros sistemas, o GCC sobrescreveria seu arquivo fonte com o novo executável.

gcc toma muitas opções diferentes de linha de comando (flags) que mudam seu comportamento. Uma das bandeiras mais comuns é a de “nível de otimização”, -O (maiúsculas ‘o’). gcc tem a capacidade de optimizar o seu código para diversas situações.

  1. -O ou -O1: Optimizar. Otimizar a compilação leva um pouco mais de tempo, e muito mais memória para uma grande função. Com -O, o compilador tenta reduzir o tamanho do código e o tempo de execução, sem realizar nenhuma otimização que leve muito tempo de compilação.
  2. -O2: Otimize ainda mais. O GCC executa quase todas as otimizações suportadas que não envolvem um tradeoff de velocidade espacial. Em comparação com -O, esta opção aumenta tanto o tempo de compilação quanto a performance do código gerado.
  3. -O3: Otimize ainda mais. -O3 ativa todas as otimizações especificadas por -O2 e também ativa outras otimizações. Esta é frequentemente a melhor opção a utilizar.
  4. -O0: Reduza o tempo de compilação e faça com que a depuração produza os resultados esperados. Esta é a opção padrão.
  5. -Os: Optimizar para o tamanho. -Os habilita todas -O2 otimizações que normalmente não aumentam o tamanho do código. Também realiza outras otimizações projetadas para reduzir o tamanho do código.
  6. -Ofast: Desconsiderar o cumprimento de normas rigorosas. -Ofast permite todas as -O3 optimizações. Também permite optimizações que não são válidas para todos os programas em conformidade com as normas.
  7. -Og: Otimize a experiência de depuração. -Og permite optimizações que não interferem com a depuração. Deve ser o nível de otimização escolhido para o ciclo padrão de edição-compilação-debug, oferecendo um nível razoável de otimização enquanto mantém uma compilação rápida e uma boa experiência de debugging. Usaremos -Og no CS107 quando estivermos depurando.

Ver o man página para gcc para mais detalhes sobre otimização (ou veja aqui para mais informações sobre otimizações).

Outra bandeira comum é a opção -std=gnu99, que diz gcc para usar a “versão gnu c do padrão c de 1999”. O padrão fornece uma sintaxe tal como ser capaz de definir uma variável dentro de uma declaração de loop (por exemplo, for (int i = ...)). Nós usaremos esta norma no CS107.

Também usaremos a bandeira -g, que nos permite usar o depurador, gdb, para nos dar números exatos de linha em nosso código quando o rodamos.

Exemplo:

$ gcc -std=gnu99 -g -Og loop.c -o loop 

Se você estiver interessado em mais informações sobre gcc, confira a Seção 1 deste documento Stanford Unix Programming Tools, bem como o manual completo do gcc(GNU).