Compilando programas em C++
Neste capítulo, vamos aprender a compilar e executar programas com um único arquivo e projetos na linguagem C++.
No terminal, abra a pasta c_cpp_projects
que criamos anteriormente para guardar nossos projetos.
cd ~/dev/c_cpp_projects
Programa
Seção intitulada “Programa”Crie um diretório chamado binary_tree
, entre nele e abra-o no Visual Studio Code.
mkdir -p binary_treecd binary_treecode .
Lembre-se de ativar o perfil C/C++
que criamos no capítulo Configurando o VSCode.
Crie um arquivo chamado main.cpp
e adicione o seguinte código.
#include <iostream>
using namespace std;
int main(){ cout << "Hello, World!" << endl; return 0;}
Para compilar o código, utilizamos o comando clang++
, em vez de apenas clang
.
A estrutura do comando é a mesma.
Antes de executá-lo, vamos criar uma pasta chamada build
para guardar o arquivo binário gerado.
mkdir -p buildclang++ main.cpp -o build/binary_tree
Para executar o programa, basta chamar o arquivo binário gerado.
./build/binary_tree

Projeto
Seção intitulada “Projeto”Vamos editar este projeto para de fato representar uma árvore binária.
Crie duas pastas dentro do projeto: tree
e node
.
mkdir -p tree node
- Dentro de tree, crie um arquivo
tree.cpp
e umtree.hpp
. - Dentro de node, crie um arquivo
node.cpp
e umnode.hpp
.
touch tree/tree.cpp tree/tree.hpp node/node.cpp node/node.hpp
- Na raiz do projeto, crie os arquivos
main.cpp
,.clang-format
e.clang-tidy
.
touch main.cpp .clang-format .clang-tidy
- Use os snippets para preencher o conteúdo dos arquivos de formatação e de linting.
A estrutura do projeto deve ficar da seguinte forma.
Directorynode
- node.cpp
- node.hpp
Directorytree
- tree.cpp
- tree.hpp
- .clang-format
- .clang-tidy
- main.cpp
Copie o conteúdo de todos os arquivos abaixo para os respectivos arquivos criados. Não se esqueça de salvar cada um deles.
#include "tree/tree.hpp"#include <iostream>
using namespace std;
int main() { Tree tree;
tree.insert(5); tree.insert(3); tree.insert(8); tree.insert(1); tree.insert(4); tree.insert(7); tree.insert(9);
tree.print();
cout << endl;
return 0;}
#ifndef __NODE_HPP__#define __NODE_HPP__
class Node {private: int data; Node *left; Node *right;
public: Node(int data); ~Node() {}
int getData(); Node *getLeft(); Node *getRight();
void setData(int data); void setLeft(Node *left); void setRight(Node *right);};
#endif // __NODE_HPP__
#include "node.hpp"
Node::Node(int data) { this->data = data; left = nullptr; right = nullptr;}
int Node::getData() { return data;}
Node *Node::getLeft() { return left;}
Node *Node::getRight() { return right;}
void Node::setData(int data) { this->data = data;}
void Node::setLeft(Node *left) { this->left = left;}
void Node::setRight(Node *right) { this->right = right;}
#ifndef __TREE_HPP__#define __TREE_HPP__
#include "../node/node.hpp"
class Tree { private: Node *root;
void insert(Node *node, int data); void print(Node *node);
public: Tree(); ~Tree();
void insert(int data); void print();};
#endif // __TREE_HPP__
#include "tree.hpp"
#include <iostream>
using namespace std;
Tree::Tree() { root = nullptr;}
Tree::~Tree() { Node *current = root; while (current != nullptr) { Node *temp = current; current = current->getRight(); delete temp; }}
void Tree::insert(int data) { if (root == nullptr) { root = new Node(data); } else { insert(root, data); }}
void Tree::insert(Node *node, int data) { if (data < node->getData()) { if (node->getLeft() == nullptr) { node->setLeft(new Node(data)); } else { insert(node->getLeft(), data); } } else { if (node->getRight() == nullptr) { node->setRight(new Node(data)); } else { insert(node->getRight(), data); } }}
void Tree::print() { print(root);}
void Tree::print(Node *node) { if (node != nullptr) { print(node->getLeft()); cout << node->getData() << " "; print(node->getRight()); }}
Antes de compilar o projeto, vamos inicializar o controle de versão com o Git.
Crie o arquivo .gitignore
na raiz do projeto, e o preencha com o snippet gitignore-c-cpp
.
Então, inicialize o repositório Git e faça o primeiro commit.
git initgit add .git commit -m "Initialize project"
Compilação
Seção intitulada “Compilação”Para compilar o projeto, precisamos passar todos os arquivos para o compilador.
Fazemos isso usando o comando clang++
da seguinte maneira:
clang++ <arquivos.cpp> -I <pastas_com_arquivos.hpp> -o <executável>
<arquivos.cpp>
: todos os arquivos.cpp
do projeto.<pastas_com_arquivos.hpp>
: todas as pastas que contêm arquivos.hpp
do projeto.<executável>
: nome do arquivo binário gerado.
Ou seja, precisamos especificar a localização de todos os arquivos que desejamos incluir e compilar. Dado que nosso projeto tem mais de uma pasta internamente, precisamos especificar a localização de todas elas. Execute o código a seguir.
clang++ tree/tree.cpp node/node.cpp main.cpp -I tree -I node -o build/binary_tree
Para executar o programa, basta chamar o arquivo binário gerado.
./build/binary_tree
Se tudo estiver correto, você verá os nós da árvore binária sendo impressos no terminal em ordem crescente.

Configurações
Seção intitulada “Configurações”Assim como fizemos para projetos em C, podemos configurar tarefas de compilação para C++ no Visual Studio Code. Se você seguiu os passos recomendados no capítulo Configurando o VSCode, já está configurada uma tarefa de compilação para C++.
Infelizmente, essa tarefa apenas compila arquivos .cpp
que estejam na raiz do projeto.
Uma vez que nosso projeto tem arquivos em pastas diferentes, precisamos especificar a localização de todos eles.
Dessa forma, a tarefa de compilação global não é suficiente para compilar o projeto binary_tree
.
Precisamos criar um arquivo de tarefa personalizado para isso.
Nós configuramos também alguns snippets para facilitar a construção do arquivo tasks.json
.
Crie uma pasta chamada .vscode
na raiz do projeto e um arquivo chamado tasks.json
dentro dela.
mkdir -p .vscodetouch .vscode/tasks.json
Garanta que o perfil C/C++
esteja ativo e abra o arquivo tasks.json
.
Digite nele tasks-json
e pressione

Então, dentro do vetor tasks
, digite cpp-build-task
e pressione

Observe o campo args
do arquivo tasks.json
.
Ele contém os argumentos que passamos para o comando de compilação.
Atualmente, ele recebe todos os arquivos .cpp
que estejam na raiz do projeto.
"args": [ "-fcolor-diagnostics", "-fansi-escape-codes", "-g", "${workspaceFolder}/*.cpp", "-I", "${workspaceFolder}", "-o", "${workspaceFolder}/build/${workspaceFolderBasename}"],
Precisamos passar, além desses, todos os arquivos .cpp
que estão nas pastas tree
e node
.
Para isso, adicionamos uma linha para cada pasta, iniciando com o atalho ${workspaceFolder}
, o qual indica a pasta raiz do projeto.
O arquivo tasks.json
deve ficar da forma abaixo.
{ "version": "2.0.0", "tasks": [ { "args": [ "-fcolor-diagnostics", "-fansi-escape-codes", "-g", "${workspaceFolder}/*.cpp", "${workspaceFolder}/node/*.cpp", "${workspaceFolder}/tree/*.cpp", "-I", "${workspaceFolder}", "-o", "${workspaceFolder}/build/${workspaceFolderBasename}" ], "command": "clang++", "detail": "Tarefa de compilação de um projeto em C++. Compila todos os arquivos C++ ligados do projeto em um único executável.", "group": { "kind": "build" }, "label": "Clang: build C++ project (Local)", "options": { "cwd": "${workspaceFolder}" }, "problemMatcher": ["$gcc"], "type": "cppbuild" } ]}
Poderemos então usar o atalho Clang: build C++ project (Local)
.

O Visual Studio Code compilará o projeto e mostrará o resultado no terminal integrado.
