Suporte para Open Folder para sistemas de build do C++ no Visual Studio

O recurso Abrir Pasta está disponível no Visual Studio 2017 e posterior.

No Visual Studio 2017 e posteriores, o recurso "Abrir Pasta" permite que você abra uma pasta de arquivos de origem e comece a codificar imediatamente, com suporte para IntelliSense, navegação, refatoração, depuração e assim por diante. À medida que você edita, cria, move ou exclui arquivos, o Visual Studio rastreia as alterações automaticamente e atualiza continuamente seu índice do IntelliSense. Nenhum arquivo .sln ou .vcxproj é carregado; se necessário, especifique tarefas personalizadas, além de compilar e iniciar parâmetros por meio de arquivos .json simples. Esse recurso permite integrar qualquer sistema de build de terceiros ao Visual Studio. Para obter informações gerais sobre Open Folder, confira Desenvolver código no Visual Studio sem projetos nem soluções.

CMake e Qt

O CMake é integrado ao IDE do Visual Studio como componente da carga de trabalho de área de trabalho do C++. O fluxo de trabalho do CMake não é idêntico ao fluxo de trabalho descrito neste artigo. Se você estiver usando o CMake, confira Projetos do CMake no Visual Studio. Você também pode usar o CMake para criar projetos Qt ou usar a Extensão Qt Visual Studio para Visual Studio 2015 ou Visual Studio 2017.

Outros sistemas de build

Para usar o IDE do Visual Studio com um sistema de build ou conjunto de ferramentas do compilador que não tem suporte direto no menu principal, selecione Arquivo | Abrir | Pasta ou pressione Ctrl + Shift + Alt + O. Navegue até a pasta que contém seus arquivos de código-fonte. Para criar o projeto, configure o IntelliSense e defina parâmetros de depuração, adicione três arquivos JSON:

Arquivo Descrição
CppProperties.json Especifica informações de configuração personalizada para navegação. Crie esse arquivo, se necessário, na pasta raiz do projeto. (Não usado em projetos do CMake.)
tasks.vs.json Especifique comandos de build personalizados. Acessados por meio do item de menu de contexto do Gerenciador de Soluções, Configurar tarefas.
launch.vs.json Especifica argumentos de linha de comando para o depurador. Acessados por meio do item de menu de contexto do Gerenciador de Soluções, Configurações de depuração e de inicialização.

Configurar a navegação de código com CppProperties.json

Para que o IntelliSense e o comportamento de navegação, como Ir para Definição, funcionem corretamente, o Visual Studio precisa saber qual compilador você está usando, onde estão os cabeçalhos do sistema e onde os arquivos de inclusão adicionais estão localizados se eles não estão diretamente na pasta que você abriu (a pasta do workspace). Para especificar uma configuração, escolha Gerenciar Configurações na lista suspensa na barra de ferramentas principal:

Configuration dropdown on the toolbar showing the Manage configurations selection.

O Visual Studio oferece as seguintes configurações padrão:

Add Configuration to CppProperties dialog, showing list of Default configurations: x86-Debug, x86-Release, x64-Debug, x64-Release, and so on.

Se, por exemplo, você escolher x64-Debug, o Visual Studio criará um arquivo chamado CppProperties.json na pasta raiz do projeto:

{
  "configurations": [
    {
      "inheritEnvironments": [
        "msvc_x64"
      ],
      "name": "x64-Debug",
      "includePath": [
        "${env.INCLUDE}",
        "${workspaceRoot}\\**"
      ],
      "defines": [
        "WIN32",
        "_DEBUG",
        "UNICODE",
        "_UNICODE"
      ],
      "intelliSenseMode": "windows-msvc-x64"
    }
  ]
}

Essa configuração herda as variáveis de ambiente do Prompt de Comando do Desenvolvedor do Visual Studio x64. Uma dessas variáveis é INCLUDE e você pode se referir a ela aqui usando a macro ${env.INCLUDE}. A propriedade includePath informa ao Visual Studio onde procurar todas as fontes de que ele precisa para o IntelliSense. Nesse caso, ele diz "pesquisar em todos os diretórios especificados pela variável de ambiente INCLUDE e também em todos os diretórios na árvore de pastas de trabalho atual". A propriedade name é o nome que será exibido na lista suspensa e pode ser o que você quiser. A propriedade defines fornece dicas para o IntelliSense quando encontra blocos de compilação condicional. A propriedade intelliSenseMode fornece algumas dicas adicionais com base no tipo de compilador. Várias opções estão disponíveis para MSVC, GCC e Clang.

Observação

Se o Visual Studio parece estar ignorando as configurações em CppProperties.json, tente adicionar uma exceção ao arquivo .gitignore assim: !/CppProperties.json.

Configuração padrão para MinGW-w64

Se você adicionar a configuração MinGW-W64, o JSON terá a seguinte aparência:

{
  "configurations": [
    {
      "inheritEnvironments": [
        "mingw_64"
      ],
      "name": "Mingw64",
      "includePath": [
        "${env.INCLUDE}",
        "${workspaceRoot}\\**"
      ],
      "intelliSenseMode": "linux-gcc-x64",
      "environments": [
        {
          "MINGW64_ROOT": "C:\\msys64\\mingw64",
          "BIN_ROOT": "${env.MINGW64_ROOT}\\bin",
          "FLAVOR": "x86_64-w64-mingw32",
          "TOOLSET_VERSION": "9.1.0",
          "PATH": "${env.BIN_ROOT};${env.MINGW64_ROOT}\\..\\usr\\local\\bin;${env.MINGW64_ROOT}\\..\\usr\\bin;${env.MINGW64_ROOT}\\..\\bin;${env.PATH}",
          "INCLUDE": "${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\tr1;${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\${env.FLAVOR}",
          "environment": "mingw_64"
        }
      ]
    }
  ]
}

Observe o bloco environments. Ele define propriedades que se comportam como variáveis de ambiente e estão disponíveis não apenas no arquivo CppProperties.json, mas também nos outros arquivos de configuração task.vs.json e launch.vs.json. A configuração Mingw64 herda o ambiente mingw_w64 e usa sua propriedade INCLUDE para especificar o valor para includePath. Você pode adicionar outros caminhos a essa propriedade de matriz conforme necessário.

A propriedade intelliSenseMode é definida como um valor apropriado para GCC. Para mais informações sobre todas essas propriedades, confira a referência de esquema CppProperties.

Quando tudo estiver funcionando corretamente, você verá o IntelliSense nos cabeçalhos do GCC ao passar o cursor do mouse sobre um tipo:

Screenshot of a GCC IntelliSense pop-up showing the header documentation.

Habilitar o diagnóstico do IntelliSense

Se você não estiver vendo o IntelliSense esperado, poderá solucionar problemas acessando oFerramentas>Opções>Editor de Texto>C/C++>Avançado e definindo Habilitar Registro em Log para true. Para começar, tente definir Nível de registros em log como 5 e Filtros de registros em log como 8.

Options dialog, showing the Diagnostic logging settings.

A saída é canalizada para a Janela de Saída e fica visível quando você escolhe *Mostrar Saída de: Log do Visual C++. A saída contém, entre outras coisas, a lista de caminhos de inclusão reais que o IntelliSense está tentando usar. Se os caminhos não corresponderem àqueles em CppProperties.json, tente fechar a pasta e excluir a subpasta .vs que contém dados de navegação armazenados em cache.

Definir tarefas de build com tasks.vs.json

Você pode automatizar os scripts de compilação, ou quaisquer outras operações externas nos arquivos existentes em seu workspace atual, executando-os como tarefas diretamente no IDE. Você pode configurar uma nova tarefa clicando com o botão direito em um arquivo ou pasta e selecionando Configurar Tarefas.

Solution Explorer shortcut menu showing the Configure Tasks command.

Isso cria (ou abre) o arquivo tasks.vs.json na pasta .vs criada pelo Visual Studio na pasta raiz do projeto. Defina qualquer tarefa arbitrária nesse arquivo e, em seguida, invoque-a no menu de contexto do Gerenciador de Soluções. Para continuar o exemplo de GCC, o snippet a seguir mostra um arquivo tasks.vs.json completo com uma só tarefa que invoca g++.exe para criar um projeto. Suponha que o projeto contenha um só arquivo chamado hello.cpp.

{
  "version": "0.2.1",
  "tasks": [
    {
      "taskLabel": "build hello",
      "appliesTo": "/",
      "type": "default",
      "command": "g++",
      "args": [
        "-g",
        "-o",
        "hello",
        "hello.cpp"
      ]
    }
  ]
}

O arquivo JSON é colocado na subpasta .vs. Para ver essa pasta, clique no botão Mostrar Todos os Arquivos na parte superior do Gerenciador de Soluções. Você pode executar essa tarefa clicando com o botão direito do mouse no nó raiz no Gerenciador de Soluções e escolhendo build hello. Quando a tarefa for concluída, você deverá ver um novo arquivo, hello.exe, no Gerenciador de Soluções.

Você pode definir muitos tipos de tarefas. A exemplo a seguir mostra um arquivo tasks.vs.json que define uma única tarefa. taskLabel define o nome exibido no menu de contexto. appliesTo define em quais arquivos o comando pode ser executado. A propriedade command se refere à variável de ambiente COMSPEC, que identifica o caminho para o console (cmd.exe no Windows). Referencie também variáveis de ambiente declaradas em CppProperties.json ou CMakeSettings.json. A propriedade args especifica a linha de comando a ser invocada. A macro ${file} recupera o arquivo selecionado no Gerenciador de Soluções. O exemplo a seguir exibirá o nome do arquivo .cpp atualmente selecionado.

{
  "version": "0.2.1",
  "tasks": [
    {
      "taskLabel": "Echo filename",
      "appliesTo": "*.cpp",
      "type": "command",
      "command": "${env.COMSPEC}",
      "args": ["echo ${file}"]
    }
  ]
}

Depois de salvar tasks.vs.json, clique com o botão direito do mouse em qualquer arquivo .cpp na pasta, escolha Ecoar nome de arquivo no menu de contexto e veja o nome de arquivo exibido na janela de Saída.

Para obter mais informações, confira Referência de esquema de Tasks.vs.json.

Configurar parâmetros de depuração com launch.vs.json

Para personalizar os argumentos de linha de comando do programa e instruções de depuração, clique com o botão direito do mouse no executável no Gerenciador de Soluções e selecione Configurações de Depuração e de Inicialização. Isso abrirá um arquivo launch.vs.json existente ou, se nenhum existir, criará um arquivo com um conjunto de configurações mínimas de inicialização. Primeiro, você pode escolher o tipo de sessão de depuração que deseja configurar. Para depurar um projeto MinGw-w64, escolhemos Inicialização de C/C++ para MinGW/Cygwin (gdb). Isso cria uma configuração de inicialização para usar gdb.exe com algumas suposições bem informadas sobre valores padrão. Um desses valores padrão é MINGW_PREFIX. Você pode substituir o caminho literal (conforme mostrado abaixo) ou definir uma propriedade MINGW_PREFIX em CppProperties.json:

{
  "version": "0.2.1",
  "defaults": {},
  "configurations": [
    {
      "type": "cppdbg",
      "name": "hello.exe",
      "project": "hello.exe",
      "cwd": "${workspaceRoot}",
      "program": "${debugInfo.target}",
      "MIMode": "gdb",
      "miDebuggerPath": "c:\\msys64\\usr\\bin\\gdb.exe",
      "externalConsole": true
    }
  ]
}

Para iniciar a depuração, escolha o executável na lista suspensa de depuração e clique na seta verde:

Toolbar debug target dropdown, showing the green arrow to start the debugger.

Você deverá ver a caixa de diálogo Inicializando o Depurador e então uma janela do console externo que está executando seu programa.

Para mais informações, confira Referência do esquema launch.vs.json.

Como iniciar outros executáveis

Você pode definir as configurações de inicialização para qualquer executável em seu computador. O seguinte exemplo inicia 7za e especifica argumentos adicionais, adicionando-os à matriz JSON args:

{
  "version": "0.2.1",
  "defaults": {},
  "configurations": [
    {
      "type": "default",
      "project": "CPP\\7zip\\Bundles\\Alone\\O\\7za.exe",
      "name": "7za.exe list content of helloworld.zip",
      "args": [ "l", "d:\\sources\\helloworld.zip" ]
    }
  ]
}

Quando você salva esse arquivo, a nova configuração é exibida na lista suspensa Destino de Depuração e você pode selecioná-la para iniciar o depurador. Crie quantas configurações de depuração desejar para qualquer quantidade de executáveis. Se você pressionar F5 agora, o depurador será iniciado e atingirá qualquer ponto de interrupção que você já possa ter definido. Todas as janelas do depurador conhecidas e sua funcionalidade agora estão disponíveis.