Работя почти година по внедряването на микроуслуги на 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++ разработчици като мен. 😀