Работя почти година по внедряването на микроуслуги на C++11, работещи като Docker контейнери. По време на моето пътуване видях да се появяват доста интересни инструменти за работа със C++ в тази област (микро-услуги и Docker).

Започнах да използвам Xcode на Mac OS X (сега macOS). Дори когато Xcode е чудесен инструмент за работа по C++ проект, с много привлекателен потребителски интерфейс и не супер добро изживяване за отстраняване на грешки, но полезно IMHO, той има една наистина досадна функция: постоянно индексира кода, докато го въвеждам и, в резултат на това, въртя вентилаторите на моя MacBook Pro до 5000 rpm и го правя наистина горещ. Опитах се да деактивирам всички опции за довършване на код в предпочитания без никакъв успех. Това ме накара да се замисля за връщане към Emacs, който, дори когато го използвах в миналото, бих казал, че не съм експерт и повторното му зареждане в мозъка ми ще ми отнеме известно време, за да интериоризирам клавишите за бърз достъп и така нататък, така че си помислих да потърся нещо подобно, но модерно, за което минах през TextMate, Atom, Sublime и Visual Studio Code.

Visual Studio Code (VSC отсега нататък) има подобна идея като Emacs, да предостави много прост инструмент за редактиране, но мощен, като в същото време осигурява пълния цикъл на разработка (редактиране, изграждане и отстраняване на грешки в инструмента). Работи с естествена производителност на Windows, OS X и Linux и с много адаптивен потребителски интерфейс, който изглежда и се чувства естествено за операционната система, в която работи, което е плюс.

По времето, когато започнах да работя по моя проект за микро-услуги, VSC беше доста нов и нямаше пълна поддръжка за C++, с изключение на оцветяването на синтаксиса и някои много експериментални интеграции с GDB и LLDB, но днес след по-малко от година VSC е доста работещ в цикъла на разработка на C++, можете да го интегрирате с CMake и да изградите C++ проект от VSC и не само да използвате CMake, но и да използвате C++ Debugger (GDB или LLDB) във VSC.

Така че тази статия е за стъпките, които последвах, за да конфигурирам VSC да работи с C++, CMake и LLDB.

Предпоставки

  • Вече е инсталиран C++ компилатор, независимо дали е clang или gcc. В моя случай вече съм инсталирал Xcode, който използвам за моите iOS проекти, така че е удобно, но ако се интересувате само от чист C++, можете да инсталирате някое от споменатите по-горе или и двете.

Инсталиран код на Visual Studio:

  • Изтеглете VSC от тук
  • Отворете VSC
  • Стартирайте VS Code Quick Open (⌘+P) и поставете следните команди, след което натиснете enter.

За да инсталирате разширението Microsoft C/C++:

  • ext install cpptools

За да инсталирате разширение CMake:

  • ext install cmake

Инсталиране на разширение Native Debug:

  • ext install debug

Нека започнем, като създадем работно пространство във VSC

Създайте директория, където ще се намира вашият проект, да кажем (по много неформален начин) ~/Desktop/hello-vsc и отворете тази директория на VSC (Command + O):

Сега добавете файловете:

  • CMakeLists.txt
  • hello_vsc.cpp

Сега нека напишем малко код

В случай, че се чудите, CMakeLists.txt е входният файл на CMake. CMake е инструмент за команден ред, използван за контролиране на процеса на компилиране на софтуер и може да се използва за разработка на софтуер между различни платформи. Така че в микро-услугите земята е от ключово значение за крос-платформата и от днес C++ е най-добрият крос-платформен език от всички.

Така че нека напишем следния код в нашия файл CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)
project(hello-vsc)
set(SOURCE hello-vsc.cpp)
add_executable(${PROJECT_NAME} ${SOURCE})

където първо се уверяваме, че използваме като минимална версия на cmake 3.0, след това задаваме името на проекта на „hello-vac“, след това казваме, че изходният код на нашия проект е в „hello-vsc.cpp“, тук вие може да добавя повече файлове, разделени с един или повече интервали и накрая задаваме нашия изпълним файл, използвайки същото име, което използваме като име на проекта, и декларирайки изходния код, който да бъде включен по време на процеса на изграждане. Това е всичко за CMake, в случай че искате да научите повече за CMake, това са отлични уроци.

Сега на „hello-vsc.cpp“ въведете следния прост C++ код и го запазете:

#include <iostream>
int main(int argc, const char * argv[]) {
    std::cout << "hello Visual Studio Code! :)" << '\n'; 
    return 0;
}

Сега в редактора ще забележите зелено извиване под първия и единствен оператор #include:

това означава, че VSC не може да намери включения файл в този случай iostream,така че трябва да генерираме файла c_cpp_properties.json и за да направим това просто:

  • щракнете върху електрическата крушка, която се появява отляво
  • щракнете върху Добавяне на включен път към настройките.

ще ви бъде представен файл със следния JSON източник:

{
    "configurations": [
        {
            "name": "Mac",
            "includePath": ["/usr/include"],
            "browse" : {
                "limitSymbolsToIncludedHeaders" : true,
                "databaseFilename" : ""
            }
        },
        {
            "name": "Linux",
            "includePath": ["/usr/include"],
            "browse" : {
                "limitSymbolsToIncludedHeaders" : true,
                "databaseFilename" : ""
            }
        },
        {
            "name": "Win32",
            "includePath": ["c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include"],
            "browse" : {
                "limitSymbolsToIncludedHeaders" : true,
                "databaseFilename" : ""
            }
        }
    ]
}

като се има предвид, че тази статия е фокусирана върху Mac OS X, ще използваме раздела с надпис „име“: „Mac“, но това, което ще направим тук, трябва да е приложимо и за другите платформи.

Генерираният файл c_cpp_properties.json е достатъчен за тази статия, но ако трябва да използвате други библиотеки на трети страни, масивът “includePath” е мястото за добавяне на още пътища, така че VSC да може да предостави информация за автоматично довършване.

Генериране на задачи за CMake и Make

Във VSC напишете ⇧+⌘+P и напишете „Tasks“, след това изберете тази с името „Configure Task Runner“:

от списъка изберете този, обозначен като „Други“:

което ще генерира файла „tasks.json“, който изглежда по следния начин:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "echo",
    "isShellCommand": true,
    "args": ["Hello World"],
    "showOutput": "always"
}

файл със задача ви позволява да добавите команда, която може да бъде изпълнена от обвивката в примера по-горе, генерираният файл tasks.json изпълнява командата „echo“ и я предава като аргумент „Hello World“. За да го изпълните, просто въведете:

  • ⇧+⌘+P и въведете отново „Задачи“, но този път изберете опцията, означена като „Изпълни задача“

  • Изберете само елемент в списъка, означен като „ехо“ и ще видите резултата в долната част на редактора:

Повече за задачите тук

така че сега нека направим нещо по-интересно, нека модифицираме файла tasks.json както следва:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "sh",
    "isShellCommand": true,
    "args": ["-c"],
    "showOutput": "always",
    "options": {
        "cwd": "${workspaceRoot}/build"
    },
    "tasks": [
        {
            "taskName": "cmake",
            "args": ["cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug .."]     
        },
        {
            "taskName": "make",
            "args": ["make -j 8"],
            "isBuildCommand": true            
        }
    ]
}

интересната част в нашия случай е секцията “options”, където се използва свойството “cwd” (текущата работна директория) и заместващата променлива “${ workspaceRoot}”, тази променлива съдържа пътя до папката, където зареждаме нашия проект във VSC. Свързваме директорията „build“, която трябва да бъде създадена в главната директория на нашия проект:

$ cd hello-vsc
$ mkdir build
$ ls -l
-rw-r--r--  1 ivanmejia  staff   125B Nov 28 08:41 CMakeLists.txt
drwxr-xr-x  6 ivanmejia  staff   204B Nov 28 08:42 build/
-rw-r--r--  1 ivanmejia  staff   136B Nov 28 10:44 hello_vsc.cpp

тогава свойството “tasks” е масив от задачи, които изискваме, в този случай задачата “cmake”, която ни позволява да генерираме всички компилационни файлове, необходими за генериране на двоичен файл изпълним; в този случай ние и задачата “make”, която ни позволява да изградим нашия изпълним файл.

Накрая свойството „isBuildCommand“, зададено на true, позволява изпълнението на задачата чрез Задачи: Изпълнение на задача за изграждане.

Сега, за да стартирате „cmake“, направете следното:

  • ⇧+⌘+P и въведете „Задачи“ и изберете „Изпълни Задача
  • От списъка изберете „cmake“ и ще видите следния резултат
Usage
  cmake [options] <path-to-source>
  cmake [options] <path-to-existing-build>
Specify a source directory to (re-)generate a build system for it in the
current working directory.  Specify an existing build directory to
re-generate its build system.
Run 'cmake --help' for more information.

това означава, че не предаваме правилно аргументите, затова се нуждаем от друго свойство, наречено „suppressTaskName” (във файла tasks.json по-горе) и го задайте на true, което ще потисне името на задачата да бъде предава като част от задачата и вместо това предава аргументите на задачата, които за случая на “cmake” са:

-G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..

което основно инструктира CMake да генерира компилиращите файлове и да го настрои да инструктира C++ компилатора да избягва използването на оптимизации и да генерира код за отстраняване на грешки; накрая „..“ показва използването на файла ../CMakeLists.txt като вход на CMake.

Аргументите за задачата “make” са:

-j 8

основно инструктира make да започне изграждането на нашата програма и да използва 8 задачи, които могат да се изпълняват едновременно във всяко ядро ​​на процесора на вашия компютър, дори когато в този случай този аргумент не е необходим, можете да го оставите, в случай че имате повече от 8 изходни файла, това Ще накара компилатора да компилира всички източници паралелно, като присвоява всеки източник на едно ядро ​​и оставя останалите на други ядра веднага щом се освободят от работа.

Затова задайте „suppressTaskName“ на true:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "sh",
    "isShellCommand": true,
    "args": ["-c"],
    "showOutput": "always",
    "suppressTaskName": true,
    ...
}

и отново въведете ⇧+⌘+P и въведете „Tasks“ и изберете „Run Task“ и сега трябва да видите резултат като този:

-- The C compiler identification is AppleClang 8.0.0.8000042
-- The CXX compiler identification is AppleClang 8.0.0.8000042
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/ivanmejia/Desktop/hello-vsc/build

сега имаме всички необходими файлове за изграждане на нашия проект в нашата директория ./build.

  • Сега отново въведете ⇧+⌘+P и въведете „Tasks“ и този път изберете „Run Build Task
  • От списъка изберете „make“ и трябва да видите следния резултат:
Scanning dependencies of target hello-vsc
[ 50%] Building CXX object CMakeFiles/hello-vsc.dir/hello_vsc.cpp.o
[100%] Linking CXX executable hello-vsc
[100%] Built target hello-vsc

сега в прозореца на вашия терминал отидете на ./hello-vsc/build и въведете името на изпълнимия файл и трябва да го видите изход:

$ ./hello-vsc
hello Visual Studio Code! :)

И така, вашият код се изгражда чрез CMake от VSC.

Сега нека отстраняваме грешки в нашия код с помощта на LLDB във VSC.

Трябва да конфигурираме нашия проект да използва дебъгера, така че нека следваме тези прости стъпки:

  • Във VSC щракнете върху иконата на малка грешка в страничната лента
  • Щракнете върху иконата за конфигуриране в изгледа за отстраняване на грешки (малкото зъбно колело с червена значка върху него):

  • От списъка изберете LLDB (тези стъпки се отнасят и за други C/C++ дебъгери). Това ще генерира нов файл, наречен launch.json. Между другото, в случай че се чудите къде се съхраняват всички тези файлове (c_cpp_properties.json, tasks.json и launch.json), ако погледнете терминала си, ще видите директория ./.vscode, където се намират всички тези файлове се съхраняват.
$ ./hello-vsc/.vscode$ ls -l
total 24
-rw-r--r--  1 ivanmejia  staff   771B Nov 28 10:15 c_cpp_properties.json
-rw-r--r--  1 ivanmejia  staff   250B Nov 28 15:45 launch.json
-rw-r--r--  1 ivanmejia  staff   625B Nov 28 15:28 tasks.json
  • Вашият нов генериран файл launch.json трябва да изглежда така:
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug",
            "type": "lldb-mi",
            "request": "launch",
            "target": "./bin/executable",
            "cwd": "${workspaceRoot}"
        }
    ]
}
  • Нека променим свойството „target“ по следния начин:
"target": "./bin/hello-vsc"

това ще накара дебъгера да стартира и да се прикачи към нашия изпълним файл във VSC.

  • Накрая трябва да добавите към вашия PATH местоположението на lldb-mi dibbuger, което в случай, че имате инсталиран Xcode, трябва да бъде:
/Applications/Xcode.app/Contents/Developer/usr/bin/
  • след като добавите към вашия PATH във вашия .bash_profile местоположението на lldb-mi дебъгера, просто стартирайте отново VSC и трябва да можете да дебъгвате кода си, като просто щракнете върху „Стартиране на грешки (F5)“ бутон в изгледа за отстраняване на грешки:

И така, това е, имате C++ проект, който се изгражда с CMake и се отстраняват грешки с помощта на LLDB на Mac OS X, всичко това в Visual Studio Code. Надявам се това да ви помогне.

Трябваше да ровя на различни места, за да дойда с това решение и най-накрая това изглежда обещаващо като удобна среда за разработка на различни платформи за C/C++ разработчици като мен. 😀